教你直白的理解贝塞尔曲线???

1,473

序言

这是第一篇在掘金写的文章,写的不对的或者不好的地方希望友人能够指出便于修改与其他人分享. =.= 实在不善于表达啊 阿西吧。。。

一.什么是贝塞尔曲线? (百度百科你就知道)

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等。在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具。

二.贝塞尔曲线的公式

由于贝塞尔曲线是有固定公式的 所以只用 一次 二次 以及三次 贝塞尔曲线作为示例进行分析

  1. 公式: 有了解过贝塞尔曲线的朋友一定知道,贝塞尔曲线是需要两组固定参数的( 点( array ) , 进度( T ) ),而我们需要求的只是当下瞬时运动的点在哪,在一次贝塞尔曲线中也就是 x = Ax+(Bx-Ax)*t , y = Ay+(By-Ay)*t。 这个规则在一次贝塞尔曲线中是最直接的( 无非就是动点替换 公式递归而已 希望多阶自己思考动手 )
    let PointA = {x:200,y:20},
        PointB = {x:100,y:20},
        PointS = [ PointA , PointB ],
        T = 0;
    // 那么公式为:
        function getPoint({Points,T}){ // 这个是点组 和 进度
            return {
                x:(PointA.x + (PointB.x - PointA.x) *T),
                y:(PointA.y + (PointB.y - PointA.y) *T),
            }
        }
    // 这个时候我们可以尝试调用
    // 当进度( T ) 等于 0 的时候 我们得到的位置和 第一个点的位置是一致的
        var PointCurve = getPoint({PointS,T}) ; // {x:200,y:20} 
    // 当进度( T ) 等于 1 的时候 我们得到的位置和 第二个点的位置是一致的
        T = 1;
        var PointCurve = getPoint({PointS,T}) ; // {x:100,y:20}
    
    // 推导出的公式其实就是在直线 AB 上移动 T 的位置;  直白说就是百分比位置;

这里演示运动示意图:

三.二次贝塞尔曲线

上面说了一次贝塞尔曲线的公式,那么二次贝塞尔曲线怎么运动的呢? 有一种非常非常粗暴的理解方式:任何两条相邻的线 都会产生出另外一根随着进度而变化的线 , 而他们的子级也是相互作用的!!! 所以请注意!!!所有的线最终就是递归求一(逐一递减)!!!,而最后这一根线上的进度,则是当前所在点的位置

也可以理解为:任何两个点能确定另外一个点( 动点 ),如果同级的点( 动点仍然可以往下计算 )为复数则可以继续往下衍生,直到最后只剩下一个动点;

  • 一次贝塞尔曲线 两个点 确定一个点
  • 二次贝塞尔曲线 三个点 =》 两个点 =》 一个点
  • 三次贝塞尔曲线 四个点 =》 三个点 =》 两个点 =》 一个点 以此类推

现在我们开始分析刚才的那句话:

  1. 任何两条相邻的线 都会产生出另外一根随进度变化的线 ==》 二次贝塞尔曲线有两个基线 ==》 衍生出第三根基线( 求一 )
  2. 衍生出的第三根线没有相邻的产物线 无法作为基线继续求一 那么当前点的位置就是该线上的进度比位。 再次说明 请灵活运用上面的公式自己推导 , 使用递归或者其他方式都可以.( 反正我只会递归的方法。。。 自己推导的 不难 ) 这里演示运动示意图:

我们看到 红色点在运动的时候A B C三点的线都是固定的,假设 AB上的动点为E,BC上的动点为F, 那么EF则是求一后的线, 而红色点的当前位置就是EF * T的位置 。是不是很简单粗暴?

四.三次贝塞尔曲线

接下来比较复杂 但是按照我的逻辑来想则会非常简单 这里演示运动示意图:

我们可以看到现在有固点A , B , C , D四点, 假设AB动点为E,BC动点为F,CD则为G点~(好邪恶啊), 那么这时候我们发现EF并不是求一的线 而是唯二 他与FG相连, 那么我们继续EF上也有个动点H(好嗨哟~) , FG上的动点为I点,则得出唯一线HI(真的好hi哟~); 红色点运动轨迹则为HI * T

我就问看这篇文章的人 这理解粗暴不粗暴?

所以不论多少阶的贝塞尔曲线 都是用一个递归式的方式不断的在线上抽点 多点抽线 直到剩下一个点为止( 递减规则 每次少一根线或者一个点 )

五.多次贝塞尔曲线

最后 我们看到一个神奇的现象, 最后所有的动点都会归属到他父级走到的尽头 , B 点的尽头会多一个 C 点多两个 D点多三个...... 依次类推 这些则是 任何两个点能确定另外一个点( 动点 ),如果同级的点( 动点仍然可以往下计算 )为复数则可以继续往下衍生,直到最后只剩下一个动点 这个规则所带来的影响

呃,上述表达可能仍然不是特别清楚 图都是自己绘制的 希望能够给阅读的你带来帮助。 补充: 刚想到可以使用动态规划来进行处理,所有的贝塞尔曲线最终都可以化简为一 最后一步永远是一阶贝塞尔曲线。