贝塞尔曲线的全解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贝塞尔曲线的全解析相关的知识,希望对你有一定的参考价值。

参考技术A

Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。
曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。
1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。

贝塞尔曲线为计算机矢量图形学奠定了基础。
它的主要意义在于无论是直线或曲线都能在数学上予以描述。

抛物线的三切线定理:

设P0、P02、P2是一条抛物线上顺序三个不同的点。过P0和P2点的两切线交于P1点,在P02点的切线交P0P1和P2P1于P01和P11,则如下比例成立:

当P0,P2固定,引入参数t,令上述比值为t:(1-t),即有:

t从0变到1,第一、二式就分别表示控制二边形的第一、二条边,它们是两条 一次Bezier曲线 。将一、二式代入第三式得:

依次类推,
由四个控制点定义的三次Bezier曲线P03可被定义为分别由(P0,P1,P2)和(P1,P2,P3)确定的两条二次Bezier曲线的线性组合。
即由 (n+1) 个控制点Pi(i=0,1,...,n)定义的n次Bezier曲线P0n可被定义为分别由 前、后n个控制点 定义的 两条(n-1)次 Bezier曲线P0n-1与P1n-1的线性组合:

由此得到Bezier曲线的递推计算公式:

以下公式中:B(t)为t时间下点的坐标;P0为起点,Pn为终点,Pi为控制点

由 P0 至 P1 的连续点P01,描述的一条线段:

transition-timing-function 规定过渡效果的时间曲线为贝塞尔曲线
transition: all 2s cubic-bezier( p1x, p1y, p2x, p2y )
项目预览地址: http://jsrun.net/tr3Kp

Android UI贝塞尔曲线 ⑥ ( 贝塞尔曲线递归算法原理 | 贝塞尔曲线递归算法实现 )

文章目录


贝塞尔曲线参考 : https://github.com/venshine/BezierMaker





一、贝塞尔曲线递归算法



一阶贝塞尔曲线 ( 起止点 + 0 0 0 个控制点 = 2 2 2 个点 ) 是一条直线 , 贝塞尔曲线上的点就是直线上的点 ;

二阶贝塞尔曲线 ( 起止点 + 1 1 1 个控制点 = 3 3 3 个点 ) 由 2 2 2 条 一阶贝塞尔曲线 确定 ,

三阶贝塞尔曲线 ( 起止点 + 2 2 2 个控制点 = 4 4 4 个点 ) 由 2 2 2 条 二阶贝塞尔曲线 确定 ,

四阶贝塞尔曲线 ( 起止点 + 3 3 3 个控制点 = 5 5 5 个点 ) 由 2 2 2 条 三阶贝塞尔曲线 确定 ,

⋮ \\vdots

n n n阶贝塞尔曲线 ( 起止点 + n − 1 n-1 n1 个控制点 = n + 1 n + 1 n+1 个点 ) 由 2 2 2 n − 1 n-1 n1 阶贝塞尔曲线 确定 ;


贝塞尔曲线递推公式如下 :

P i k = P i , k = 0 ( 1 − t ) P i k − 1 + t P i + 1 k − 1 , k = 1 , 2 , ⋯   , n ; i = 0 , 1 , ⋯   , n − k P_i^k = \\begincases P_i , k = 0\\\\ (1-t)P_i^k-1 + tP_i + 1^k-1 , k = 1,2,\\cdots,n ; i = 0,1,\\cdots,n-k \\endcases Pik=Pi,k=0(1t)Pik1+tPi+1k1,k=1,2,,n;i=0,1,,nk


上述公式中 k + 1 k + 1 k+1 是贝塞尔曲线的阶数 , i i i 表示顶点序号 ;


根据上述 贝塞尔曲线递推公式 , 可以得到一个递归算法 , 算法核心公式如下 :

p ( i , j ) = ( 1 − u ) × p ( i − 1 , j ) + u × p ( i − 1 , j − 1 ) p(i, j) = (1-u) \\times p (i - 1, j) + u \\times p (i - 1 , j - 1) p(i,j)=(1u)×p(i1,j)+u×p(i1,j1)

上述递推公式中 , i i i 表示贝塞尔曲线的阶数 , j j j 表示贝塞尔曲线中的点个数 ( 包含起止点 + 控制点 ) , u u u 表示比例取值范围 0 0 0 ~ 1 1 1 ;

递归算法的递归终点是取到第 0 0 0 阶 ;





二、贝塞尔曲线递归算法实现



递归算法中最终的一阶贝塞尔曲线上的点计算公式如下 :

p ( i , j ) = ( 1 − u ) × p ( i − 1 , j ) + u × p ( i − 1 , j − 1 ) p(i, j) = (1-u) \\times p (i - 1, j) + u \\times p (i - 1 , j - 1) p(i,j)=(1u)×p(i1,j)+u×p(i1,j1)

根据上述计算公式 , 得到如下代码 :

(1 - u) * mControlPoints.get(j).x + u * mControlPoints.get(j + 1).x

完整的贝塞尔曲线上的点坐标算法如下 :

  • BezierX 方法用于计算 贝塞尔曲线上的 X 轴坐标点 ;
  • BezierY 方法用于计算 贝塞尔曲线上的 Y 轴坐标点 ;
    // 贝塞尔曲线控制点集合
    private ArrayList<PointF> mControlPoints = new ArrayList<>();

    /**
     * 贝塞尔曲线递归算法, 本方法计算 X 轴坐标值
     * @param i 贝塞尔曲线阶数
     * @param j 贝塞尔曲线控制点
     * @param u 比例 / 时间 , 取值范围 0.0 ~ 1.0
     * @return
     */
    private float BezierX(int i, int j, float u) 
        if (i == 1) 
            // 递归退出条件 : 贝塞尔曲线阶数 降为一阶
            // 一阶贝塞尔曲线点坐标 计算如下 :
            return (1 - u) * mControlPoints.get(j).x + u * mControlPoints.get(j + 1).x;
        
        return (1 - u) * BezierX(i - 1, j, u) + u * BezierX(i - 1, j + 1, u);
    

    /**
     * 贝塞尔曲线递归算法, 本方法计算 Y 轴坐标值
     * @param i 贝塞尔曲线阶数
     * @param j 贝塞尔曲线控制点
     * @param u 比例 / 时间 , 取值范围 0.0 ~ 1.0
     * @return
     */
    private float BezierY(int i, int j, float u) 
        if (i == 1) 
            // 递归退出条件 : 贝塞尔曲线阶数 降为一阶
            return (1 - u) * mControlPoints.get(j).y + u * mControlPoints.get(j + 1).y;
        
        return (1 - u) * BezierY(i - 1, j, u) + u * BezierY(i - 1, j + 1, u);
    

以上是关于贝塞尔曲线的全解析的主要内容,如果未能解决你的问题,请参考以下文章

贝塞尔曲线

怎么理解贝塞尔曲线

贝塞尔曲线

Android UI贝塞尔曲线 ① ( 一阶贝塞尔曲线 | 二阶贝塞尔曲线 )

贝塞尔曲线~~~

贝塞尔 平滑曲线