美文网首页
Android 多阶贝塞尔曲线

Android 多阶贝塞尔曲线

作者: 佼佼者Mr | 来源:发表于2020-04-23 22:17 被阅读0次

二阶贝塞尔曲线

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;

    }

相关文章

网友评论

      本文标题:Android 多阶贝塞尔曲线

      本文链接:https://www.haomeiwen.com/subject/harwihtx.html