贝塞尔曲线学习笔记

46 sec read

什么是贝塞尔曲线

贝塞尔曲线的数学基础是早在 1912 年就广为人知的伯恩斯坦多项式。但直到 1959 年,当时就职于雪铁龙的法国数学家Paul de Casteljau才开始对它进行图形化应用的尝试,并提出了一种数值稳定的de Casteljau 算法。然而贝塞尔曲线的得名,却是由于1962年另一位就职于雷诺的法国工程师Pierre Bézier的广泛宣传。他使用这种只需要很少的控制点就能够生成复杂平滑曲线的方法,来辅助汽车车体的工业设计。

贝塞尔曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。因为控制简便却具有极强的描述能力,贝塞尔曲线在工业设计领域迅速得到了广泛的应用。不仅如此,在计算机图形学领域,尤其是矢量图形学,贝塞尔曲线也占有重要的地位。今天我们最常见的一些矢量绘图软件,如 Flash、Illustrator、CorelDraw 等,无一例外都提供了绘制贝塞尔曲线的功能。甚至像 Photoshop 这样的位图编辑软件,也把贝塞尔曲线作为仅有的矢量绘制工具(钢笔工具)包含其中。

贝塞尔曲线在 web 开发领域同样占有一席之地。CSS3 新增了transition-timing-function属性,它的取值就可以设置为一个三次贝塞尔曲线方程。在此之前,也有不少 JavaScript 动画库使用贝塞尔曲线来实现美观逼真的缓动效果。

贝塞尔曲线分类

贝塞尔曲线根据控制点的数量分为:

  • 一阶贝塞尔曲线(2 个控制点)
  • 二阶贝塞尔曲线(3 个控制点)
  • 三阶贝塞尔曲线(4 个控制点)
  • n阶贝塞尔曲线(n+1个控制点)

如何绘制贝塞尔曲线

一阶贝塞尔曲线

对于一阶贝塞尔曲线为我们可以看到是一条直线,通过几何知识,很容易根据t的值得出线段上那个点的坐标:

    \[B_1(t)=P_0 + (P_1 - P_0)t\]

然后可以得出:

    \[B_1(t)=(1-t)P_0 + tP_1,t\in [0,1]\]

二阶贝塞尔曲线

对于二阶贝塞尔曲线,其实你可以理解为:在P_0P_1上利用一阶公式求出点P_0^{'},然后在P_1P_2上利用一阶公式求出点P_1^{'},最后在P_0^{'}P_1^{'}上再利用一阶公式就可以求出最终贝塞尔曲线上的点P_0{''}。具体推导过程如下:

先求出线段上的控制点:

    \[P_0^{'} = (1 - t)P_0 + tP_1\]

    \[P_1^{'} = (1 - t)P_1 + tP_2\]

将上面的公式带入至下列公式中:

    \[B_{2}(t) = (1 - t)P_0^{'} + tP_1^{'}\]

    \[= (1 - t)((1 - t)P_0 + tP_1) + t((1 - t)P_1 + tP_2)\]

    \[= (1 - t)^2P_0 + 2t(1 - t)P_1 + t^2P_2\]

得出以下公式:

    \[B_{2}(t) = (1 - t)^2P_0 + 2t(1 - t)P_1 + t^2P_2 , t\in[0, 1]\]

上面的推导可能比较抽象,不太能理解。下面我们以实例来讲解:

在平面内任选 3 个不共线的点,依次用线段连接。

在第一条线段上任选一个点 D。计算该点到线段起点的距离 AD,与该线段总长 AB 的比例。

根据上一步得到的比例,从第二条线段上找出对应的点 E,使得 AD:AB = BE:BC。

连接这两点 DE。

到这里,我们就确定了贝塞尔曲线上的一个点 F。接下来,请稍微回想一下极限知识,让选取的点 D 在第一条线段上从起点 A 移动到终点 B,找出所有的贝塞尔曲线上的点 F。所有的点找出来之后,我们也得到了这条贝塞尔曲线。

回过头来看这条贝塞尔曲线,为了确定曲线上的一个点,需要进行两轮取点的操作,因此我们称得到的贝塞尔曲线为二次曲线(这样记忆很直观,但曲线的次数其实是由前面提到的伯恩斯坦多项式决定的)。

三阶贝塞尔曲线

与二阶贝塞尔曲线类似,可以通过相同的方法得出以下坐标公式:

    \[B_{3}(t) = (1 - t)^3P_0 + 3t(1 - t)^2P_1 + 3t^2(1 - t)P_2 + t^3P_3 , t\in[0, 1]\]

当控制点个数为 4 时,情况是怎样的?

步骤都是相同的,只不过我们每确定一个贝塞尔曲线上的点,要进行三轮取点操作。如图,AE:AB = BF:BC = CG:CD = EH:EF = FI:FG = HJ:HI,其中点 J 就是最终得到的贝塞尔曲线上的一个点。

这样我们得到的是一条三次贝塞尔曲线。

多阶贝塞尔曲线

n阶贝塞尔曲线公式:

    \[B(t) = \sum_{i=0}^{n}C_n^{i}P_i(1-t)^{n-i}t^i,t\in[0,1]\]

即:

    \[B(t) = \sum_{i=0}^{n}P_ib_{i,n}(t),t\in[0,1]\]

公式中C_n^i的值为\frac{n!}{(n - i)!\cdot i!},与统计学有关。

其中b_{i,n}(t)的值为:

    \[b_{i,n}(t)=C_n^{i}(1-t)^{n-i}t^i,其中i=0,1,...,n\]

参考链接:

打赏作者
微信支付标点符 wechat qrcode
支付宝标点符 alipay qrcode

情感分析的现代方法(修复代码问题)

最近在研究情感分析的内容,翻到了《Modern Methods for Sentiment Analysis》
5 min read

发表评论

电子邮件地址不会被公开。 必填项已用*标注