贝塞尔曲线学习
1.贝塞尔曲线
以下公式中:
B(t)为t时间下 点的坐标;
P0为起点,Pn为终点,Pi为控制点
一阶贝塞尔曲线(线段):
一阶贝塞尔曲线公式
一阶贝塞尔曲线演示
意义:由 P0 至 P1 的连续点, 描述的一条线段
二阶贝塞尔曲线(抛物线):
二阶贝塞尔曲线公式
二阶贝塞尔曲线演示
原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
由 P1 至 P2 的连续点 Q1,描述一条线段。 由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。 经验:P1-P0为曲线在P0处的切线。
三阶贝塞尔曲线:
三阶贝塞尔曲线公式
三阶贝塞尔曲线演示
通用公式:
通用贝塞尔曲线公式
高阶贝塞尔曲线:
4阶曲线:
四阶贝塞尔曲线演示
5阶曲线:
五阶贝塞尔曲线演示
1.1.生成贝塞尔曲线-迭代法
下面我们用代码来生成贝塞尔曲线,来展示如何贝塞尔曲线的生成原理:
package com.che.chechengwang.support.view.bezier;
import android.animation.FloatEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
* 生成贝塞尔曲线-迭代法
*
* 作者:余天然 on 16/6/14 下午2:10
*/
public class BezierGenerater1 extends View {
private Paint paint;
private int centerX, centerY;
private List points;
private FloatEvaluator evaluator;
private float fraction;
private Map colors;
private List destPoints;
public BezierGenerater1(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
evaluator = new FloatEvaluator();
startAnim();
}
//初始化数据点和控制点的位置
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = h / 2;
points = new ArrayList<>();
points.add(new PointF(centerX - 150, centerY));
points.add(new PointF(centerX - 50, centerY - 300));
points.add(new PointF(centerX + 50, centerY + 300));
points.add(new PointF(centerX + 150, centerY));
colors = new HashMap<>();
for (int i = 0; i < points.size(); i++) {
colors.put(i, getRanColor());
}
destPoints = new ArrayList<>();
destPoints.add(points.get(0));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//静态的
drawPoint(canvas, points, Color.BLACK);
drawLine(canvas, points, Color.GRAY);
//动态的
List subData = getSubData(points, fraction);
drawData(canvas, subData, fraction);
}
// 绘制数据点
private void drawPoint(Canvas canvas, List data, int color) {
paint.setColor(color);
paint.setStrokeWidth(20);
for (int i = 0; i < data.size(); i++) {
PointF pointF = data.get(i);
canvas.drawPoint(pointF.x, pointF.y, paint);
}
}
//绘制基准线
private void drawLine(Canvas canvas, List data, int color) {
paint.setColor(color);
paint.setStrokeWidth(4);
for (int i = 0; i < data.size() - 1; i++) {
PointF start = data.get(i);
PointF end = data.get(i + 1);
canvas.drawLine(start.x, start.y, end.x, end.y, paint);
}
}
//绘制路径
private void drawPath(Canvas canvas, List data) {
Path path = new Path();
PointF start = data.get(0);
path.moveTo(start.x, start.y);
for (int i = 1; i < data.size() - 1; i++) {
PointF point = data.get(i);
path.lineTo(point.x, point.y);
}
paint.setColor(Color.RED);
paint.setStrokeWidth(4);
canvas.drawPath(path, paint);
}
//迭代绘制集合
private void drawData(Canvas canvas, List data, float fraction) {
if (data.size() == 1) {
drawPoint(canvas,