二阶贝塞尔曲线
mPath.quadTo(400, 200, 10, 500);
mPath.rQuadTo(300, 100, -90, 400);
三阶阶贝塞尔曲线
mPath.cubicTo(600, 550,90, 500,900, 1000);
mPath.rCbicTo(600, 550,90, 500,900, 1000);
二阶函数和三阶函数,google已经内置好了,现在还要求怎么做到多阶的计算
利用的是德卡斯特里奥算法
public class BazierViewextends View {
private PaintmPaint;
private PaintmLinePointPaint;
private PathmPath;
private ListmControlPoints;
public BazierView(Context context) {
super(context);
mPaint =new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.RED);
mLinePointPaint =new Paint();
mLinePointPaint.setAntiAlias(true);
mLinePointPaint.setStrokeWidth(4);
mLinePointPaint.setStyle(Paint.Style.STROKE);
mLinePointPaint.setColor(Color.GRAY);
mPath =new Path();
mControlPoints =new ArrayList<>();
init();
}
private void init() {
mControlPoints.clear();
Random random =new Random();
for (int i =0; i <9; i++) {
int x = random.nextInt(800) +200;
int y = random.nextInt(800) +200;
PointF pointF =new PointF(x, y);
mControlPoints.add(pointF);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//控制点及控制点的连线
int size =mControlPoints.size();
PointF pointF;
for (int i =0; i < size; i++) {
pointF =mControlPoints.get(i);
if (i >0) {
mLinePointPaint.setColor(Color.GRAY);
//控制点连线
canvas.drawLine(mControlPoints.get(i -1).x, mControlPoints.get(i -1).y, pointF.x, pointF.y, mLinePointPaint);
}
//起点、终点换颜色
if (i ==0) {
mLinePointPaint.setColor(Color.RED);
}else if (i == size -1) {
mLinePointPaint.setColor(Color.BLUE);
}
canvas.drawCircle(pointF.x, pointF.y, 10, mLinePointPaint);
}
//曲线连接
buildBezierPoints();
canvas.drawPath(mPath, mPaint);
}
private ArrayListbuildBezierPoints() {
mPath.reset();
ArrayList pointFS =new ArrayList<>();
//阶数
int order =mControlPoints.size() -1;
float de =1f /1000;
for (float i =0; i <=1; i += de) {
PointF pointF =new PointF(deCastelJau(order, 0, i, true), deCastelJau(order, 0, i, false));
Log.e("TAG", "pointF.x" + pointF.x);
Log.e("TAG", "pointF.y" + pointF.y);
pointFS.add(pointF);
if (pointFS.size() ==1) {
mPath.moveTo(pointFS.get(0).x, pointFS.get(0).y);
}else {
mPath.lineTo(pointF.x, pointF.y);
}
}
return pointFS;
}
/**
* p(i,j) = (1-t) * p(i-1,j) + t * p(i-1,j+1);
*
* @param i 阶数
* @param j 控制点
* @param t 时间
* @param calculateX 计算哪个坐标值 true=x false=y
* @return
*/
public float deCastelJau(int i, int j, float t, boolean calculateX) {
if (i ==1) {
return calculateX ? (1 - t) *mControlPoints.get(j).x + t *mControlPoints.get(j +1).x :
(1 - t) *mControlPoints.get(j).y + t *mControlPoints.get(j +1).y;
}else {
float DE = (1 - t) * deCastelJau(i -1, j, t, calculateX) + t * deCastelJau(i -1, j +1, t, calculateX);
return DE;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
init();
invalidate();
}
return true;
}
网友评论