贝塞尔Bezier曲线的使用

本文详细介绍了贝塞尔曲线的概念、公式以及如何使用。通过示例展示了三阶贝塞尔曲线的绘制过程,包括使用Android API和数学公式计算点的坐标。推荐了两个在线工具辅助理解和绘制贝塞尔曲线。此外,还提供了如何确定控制点和套用公式来绘制不同阶的贝塞尔曲线的方法。
摘要由CSDN通过智能技术生成

1 简介

  贝塞尔曲线就是这样的一条曲线,它是依据N个位置任意的点坐标绘制出的一条光滑曲线。那么,我们可以直观地认为,为了得到一条贝塞尔曲线,我们只要输入起点、终点及控制点既可。变化参数t都是位于[0,1]。看到这里还不理解,没关系,文章会介绍怎么使用。

  如下图输入4个点[P0, P1, P2, P3],可以获得一条光滑的三阶贝塞尔曲线,通常我们叫P0为起点,P3为终点,P1和P2为控制点。

强烈推荐在线工具https://cubic-bezier.com,这个工具的使用方法会在文章里介绍。

另外一个在线工具http://wx.karlew.com/canvas/bezier/

2 贝塞尔曲线公式

引用百度百科的贝塞尔曲线公式先介绍一下公式

线性公式

给定点P0、P1,线性贝塞尔曲线只是一条两点之间的直线。这条线由下式给出:

且其等同于线性插值。

二次方公式

二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t)追踪:

三次方公式

P0、P1、P2、P3四个点在平面或在三维空间中定义了三阶贝塞尔曲线。

一般参数公式

阶贝兹曲线可如下推断。给定点P0、P1、…、Pn,其贝兹曲线即:

如上公式可如下递归表达: 用表示由点P0、P1、…、Pn所决定的贝兹曲线。
用平常话来说,阶的贝兹曲线,即双阶贝兹曲线之间的插值。

3 使用公式(以三阶贝塞尔曲线为例)

  对于上图,实际是使用使用了贝塞尔三次方公式,输入的控制点为[P0(97,279), P1(280, 305), P2(233,125), P3(442,219)], t由0–>1均匀变化得到的点B(t), 由B(t)画出的曲线。可以认为在0到1归一化的时间内,在t时刻,B(t)对应的点(x, y)由以下公式计算得到:

代入4个点的x值

  总结下,要使用贝塞尔曲线,首先确定使用的N阶的贝塞尔曲线(即确定要套用的公式,公式是固定的),再输入对应的N+1个点(包含终点,起点,N-2个控制点),就可以通过t由0–>1递增输入,如[0, 0.01, 0.02, … ,0.99, 1],然后通过t的递增变化计算得到对应的点(x, y)即B(t) 。下面使用Android三阶Bezier曲线API(红色粗线)和上面的公式(蓝色细线)来画图比较,及黑色的4个点。

  可以看到画出图形,与上图一样,并且Android三阶Bezier曲线API与我们用公式直接算是一样。

    @Override
    protected void dispatchDraw(Canvas canvas) {
        Point P0,P1,P2,P3;
        P0 = new Point(97, 279);
        P1 = new Point(280,305);
        P2 = new Point(233,125);
        P3 = new Point(442,219);
        mPath.moveTo(P0.x,P0.y);
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(10);

        //Android 三阶Bezier曲线API
        mPath.cubicTo(P1.x,P1.y,P2.x,P2.y,P3.x,P3.y);
        canvas.drawPath(mPath,mPaint);

        //套公式算的
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(2);
        float t;
        mPath.moveTo(P0.x,P0.y);
        for(int i= 0;i<1000;i++){
            t = i*0.001f;
            int x = (int)cubicCurves(t,P0.x,P1.x,P2.x,P3.x);
            int y = (int)cubicCurves(t,P0.y,P1.y,P2.y,P3.y);
            mPath.lineTo(x,y);
        }
        canvas.drawPath(mPath,mPaint);

        //画出P0, P1, P2, P3点
        mPaint.setColor(Color.BLACK);
        canvas.drawPoint(P0.x,P0.y,mPaint);
        canvas.drawPoint(P1.x,P1.y,mPaint);
        canvas.drawPoint(P2.x,P2.y,mPaint);
        canvas.drawPoint(P3.x,P3.y,mPaint);
    }
    /**
     * 求三次贝塞尔曲线(四个控制点)一个点某个维度的值.<br>
     * 套用公式即可
     * x = x0*((1-t)^3)+3*x1*t*((1-t)^2)+3*x2*(t^2)*(1-t)+x3*(t^3)
     * y = y0*((1-t)^3)+3*y1*t*((1-t)^2)+3*y2*(t^2)*(1-t)+y3*(t^3)
     * @return d
     */
    public static double cubicCurves(double t, double p0v, double p1v, double p2v, double p3v) {
        return p0v*Math.pow(1-t,3)+3*p1v*t*Math.pow(1-t,2)+3*p2v*Math.pow(t,2)*(1-t)+p3v*Math.pow(t,3);
    }

4 总结

  使用贝塞尔曲线关键是确定控制点,然后用这些点套对应阶数的公式。N阶贝塞尔曲线,需要N+1个点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值