6.3.1. 定义#
图 6.14 德卡斯特里奥算法构造二阶贝塞尔曲线#
我们先来看如何构造二阶贝塞尔曲线。如图 6.14 所示,我们有三个控制点 \(\mathbf{P}_0, \mathbf{P}_1, \mathbf{P}_2\),通过两轮线性插值得到曲线。第一轮,由参数 \(t\) 对 \(\overrightarrow{\mathbf P_0\mathbf P_1}\) 和 \(\overrightarrow{\mathbf P_1\mathbf P_2}\) 分别做线性插值,得到由同一个参数 \(t\) 分别在上述两条一阶曲线上对应的点:
(6.18)#\[\begin{split}
\begin{align}
\mathbf Q_0&=\mathrm{lerp}(\mathbf P_0, \mathbf P_1, t)=(1-t)\mathbf P_0+t\mathbf P_1\text{,}\\
\mathbf Q_1&=\mathrm{lerp}(\mathbf P_1, \mathbf P_2, t)=(1-t)\mathbf P_1+t\mathbf P_2
\end{align}
\end{split}\]
第二轮,通过对 \(\overrightarrow{\mathbf Q_0\mathbf Q_1}\) 做线性插值,得到同一个参数 \(t\) 对应的点:
(6.19)#\[
\mathbf S=\mathrm{lerp}(\mathbf Q_0, \mathbf Q_1, t)=(1-t)\mathbf Q_0+t\mathbf Q_1
\]
令 \(t\) 遍历 \([0,1]\) 取值范围,即得到由 \(\mathbf P_0, \mathbf P_1, \mathbf P_2\) 控制的二阶贝塞尔曲线。这个算法称为 德卡斯特里奥算法(de Casteljau’s algorithm),效率较高,编程方便且数值稳定性较好,因而得到了广泛的使用。类似地,我们同样可以定义三阶贝塞尔曲线。三阶贝塞尔曲线由四个控制点给出,可以通过三轮线性插值得到,如图 6.15 所示。
图 6.15 德卡斯特里奥算法构造三阶贝塞尔曲线#
进而我们可以将贝塞尔曲线的阶数推广到任意高,\(n\) 阶贝塞尔曲线由 \(n+1\) 个控制点给出。但贝塞尔曲线每个控制点对曲线的影响不是局部的,如图 6.16 所示,因此随着阶数的提高,通过控制点对曲线形状做出有效控制的难度也随之提高。解决方法就是使用分段的低阶贝塞尔函数,也就是贝塞尔样条(Bézier spline),如图 6.17 所示。
图 6.16 一条十二阶贝塞尔曲线,挪动其中一个顶点会改变整条曲线的形状[2]#
图 6.17 一条贝塞尔样条曲线[3]#
由上述构造方法我们可以求出贝塞尔曲线的数学表达式。以二阶贝塞尔曲线为例,结合公式 (6.18) 和公式 (6.19) 我们可以得到曲线的表达式:
(6.20)#\[\begin{split}
\begin{align}
\mathbf S &= (1-t) \mathbf Q_0 + t \mathbf Q_1\\
&= (1-t)( (1-t) \mathbf P_0+ t \mathbf P_1) + t((1-t) \mathbf P_1 + t\mathbf P_2)\\
&= (1-t)^2 \mathbf P_0 + 2t(1-t) \mathbf P_1 + t^2 \mathbf P_2\text{.}
\end{align}
\end{split}\]
不难发现,上式中对各控制点的权重系数正是二项式 \((t+(1-t))^2\) 展开后的各项。更一般地,\(n\) 阶贝塞尔曲线的数学表达式为:
(6.21)#\[
\mathbf S(t) = \sum_{k=0}^n B_{n,k}(t) \mathbf P_k = \sum_{k=0}^n \binom{n}{k} (1-t)^k t^{n-k} \mathbf P_k
\]
其中系数多项式为
(6.22)#\[
B_{n,k}(t)=\binom{n}{k} (1-t)^k t^{n-k}
\]
被称为 \(n\) 阶伯恩斯坦多项式(Bernstein polynomials)。