给定4点 P 1 ( 0 , 0 , 0 ) P_1(0,0,0) P1(0,0,0), P 2 ( 1 , 1 , 1 ) P_2(1,1,1) P2(1,1,1), P 3 ( 2 , − 1 , − 1 ) P_3(2,-1,-1) P3(2,−1,−1), P 4 ( 3 , 0 , 0 ) P_4(3,0,0) P4(3,0,0),用其作为特征多边形来构造一条三次Bezier曲线,并计算参数为 0 , 1 / 3 , 2 / 3 , 1 0,1/3,2/3,1 0,1/3,2/3,1的值。
首先是贝塞尔曲线的定义:当给定空间 n + 1 n+1 n+1个点的位置矢量 P i P_i Pi则 n n n次贝塞尔曲线上个点坐标的插值公式是:
P ( t ) = ∑ i = 0 n P i B i , n ( t ) , t ∈ [ 0 , 1 ] P(t)=\sum_{i=0}^{n}P_iB_{i,n}(t), t\in[0,1] P(t)=i=0∑nPiBi,n(t),t∈[0,1]
具体到对于三次贝塞尔曲线,亦即当 n = 3 n=3 n=3时,有:
P ( t ) = ∑ i = 0 3 P i B i , 3 ( t ) = ( 1 − t ) 3 P 0 + 3 t ( 1 − t ) 2 P 1 + 3 t 2 ( 1 − t ) P 2 + t 3 P 3 , t ∈ [ 0 , 1 ] P(t)=\sum_{i=0}^{3}P_iB_{i,3}(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3,t\in[0,1] P(t)=i=0∑3PiBi,3(t)=(1−t)3P0+3t(1−t)2P1+3t2(1−t)P2+t3P3,t∈[0,1]
问题是如何给它具体过来的呢?
其实就是对 B e r n s t e i n Bernstein Bernstein调和函数 B i , n ( t ) B_{i,n}(t) Bi,n(t)带入 n = 3 n=3 n=3,该函数的定义是:
B i , n ( t ) = n ! i ! ( n − i ) ! t i ( i − t ) n − i = C n i t i ( i − t ) n − i B_{i,n}(t)=\frac{n!}{i!(n-i)!}t^i(i-t)^{n-i}=C_n^it^i(i-t)^{n-i} Bi,n(t)=i!(n−i)!n!ti(i−t)n−i=Cniti(i−t)n−i
此式带入 n = 3 n=3 n=3可得上式。
对于式子:
P ( t ) = ∑ i = 0 n P i B i , n ( t ) P(t)=\sum_{i=0}^{n}P_iB_{i,n}(t) P(t)=i=0∑nPiBi,n(t)
要分为两部分看,一部分是不定的,即选取的点是不确定的,所以 P i P_i Pi具体取值不知道是多少,另一部分是固定的调和函数,在三次贝塞尔曲线的具体情况下,它就是
P ( t ) = ∑ i = 0 3 B i , 3 ( t ) P(t)=\sum_{i=0}^{3}B_{i,3}(t) P(t)=i=0∑3Bi,3(t)
为了看起来,把它写为矩阵形式。 P i P_i Pi它本身就有 x , y , z x,y,z x,y,z分量,三次计算可以合到一个矩阵里进行计算,要不然就得按照下式分别计算
P ( t ) = { x ( t ) = a 3 x t 3 + a 2 x t 2 + a 1 x t + a 0 x y ( t ) = a 3 y t 3 + a 2 y t 2 + a 1 y t + a 0 y z ( t ) = a 3 z t 3 + a 2 z t 2 + a 1 z t + a 0 z P(t)=\left\{ \begin{aligned} x(t) & = & a_{3x}t^3+a_{2x}t^2+a_{1x}t+a_{0x} \\ y(t) & = & a_{3y}t^3+a_{2y}t^2+a_{1y}t+a_{0y} \\ z(t) & = & a_{3z}t^3+a_{2z}t^2+a_{1z}t+a_{0z} \end{aligned} \right. P(t)=⎩ ⎨ ⎧x(t)y(t)z(t)===a3xt3+a2xt2+a1xt+a0xa3yt3+a2yt2+a1yt+a0ya3zt3+a2zt2+a1zt+a0z
按照上面的思路写出三次 B e r n s t e i n Bernstein Bernstein调和函数的矩阵形式:
矩阵的推导如下,对于:
P ( t ) = ∑ i = 0 3 P i B i , 3 ( t ) = ( 1 − t ) 3 P 0 + 3 t ( 1 − t ) 2 P 1 + 3 t 2 ( 1 − t ) P 2 + t 3 P 3 , t ∈ [ 0 , 1 ] P(t)=\sum_{i=0}^{3}P_iB_{i,3}(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3,t\in[0,1] P(t)=i=0∑3PiBi,3(t)=(1−t)3P0+3t(1−t)2P1+3t2(1−t)P2+t3P3,t∈[0,1]
取新函数 B i , 3 B_{i,3} Bi,3为 P i P_i Pi的系数,则调和函数可写为矩阵形式(虽然是个单行矩阵)
B = [ B 0 , 3 B 1 , 3 B 2 , 3 B 3 , 3 ] B=[B_{0,3} \text{ }B_{1,3}\text{ }B_{2,3}\text{ }B_{3,3}] B=[B0,3 B1,3 B2,3 B3,3]
其中每个 B i , 3 B_{i,3} Bi,3最高次项系数最大为3,故可用左侧含 t t t矩阵乘右侧系数矩阵得到。
以 P 0 P_0 P0系数 ( 1 − t ) 3 (1-t)^3 (1−t)3为例,拆开即为 1 − 3 t + 3 t 2 − t 3 1-3t+3t^2-t^3 1−3t+3t2−t3
什么,你忘了怎么拆了?立方和公式为:
( a + b ) 3 = a 3 + 3 a 2 b + 3 a b 2 + b 3 (a+b)^3=a^3+3a^2b+3ab^2+b^3 (a+b)3=a3+3a2b+3ab2+b3
拆开的结果按 t t t从高次到低次排列为 − t 3 + 3 t 2 − 3 t + 1 -t^3+3t^2-3t+1 −t3+3t2−3t+1,取系数分别为 − 1 , 3 , − 3 , 1 -1,3,-3,1 −1,3,−3,1,正对应右侧系数矩阵的第一列,按矩阵乘法乘到左面正好是 − t 3 + 3 t 2 − 3 t + 1 -t^3+3t^2-3t+1 −t3+3t2−3t+1,也就是 B 0 , 3 ( t ) B_{0,3}(t) B0,3(t)
该矩阵乘回去的结果是:
∣ B 0 , 3 B 1 , 3 B 2 , 3 B 3 , 3 ∣ T { \left| {B_{0,3}\text{ } B_{1,3}\text{ }B_{2,3}\text{ }B_{3,3}} \right|^T } ∣B0,3 B1,3 B2,3 B3,3∣T
(竖着这个矩阵忘了对应的markdown语法了,所以写成横着的并加个 T T T,其实竖着才更直观)
然后就是求 ∣ B 0 , 3 B 1 , 3 B 2 , 3 B 3 , 3 ∣ T ∗ ∣ P 0 P 1 P 2 P 3 ∣ T { \left| {B_{0,3}\text{ } B_{1,3}\text{ }B_{2,3}\text{ }B_{3,3}} \right|^T }*{ \left| {P_0\text{ } P_1\text{ }P_2\text{ }P_3} \right|^T } ∣B0,3 B1,3 B2,3 B3,3∣T∗∣P0 P1 P2 P3∣T
于是最终式子长这样(敲Markdown真不如用ipad手写…虽然难看不整齐就是了)
说了这么多,最后就绕到本题的解法去了,请务必要注意, P ( t ) P(t) P(t)参数归根到底还是 t t t,所以先带入几个控制点 P i P_i Pi并化简之后,就要对着题意带入 t t t来做题了。
带入对应的 t t t,可把矩阵解为 ∣ x y z ∣ { \left| x \text{ }y \text{ }z \right| } ∣x y z∣的形式,即三维坐标。
答案分别是 ( 0 , 0 , 0 ) (0,0,0) (0,0,0)、 ( 1 , 2 / 9 , 2 / 9 ) (1,2/9,2/9) (1,2/9,2/9)、 ( 2 , − 2 / 9 , 2 / 9 ) (2,-2/9,2/9) (2,−2/9,2/9)、 ( 3 , 0 , 0 ) (3,0,0) (3,0,0)
虽然图文无关,但是看图可以知道 t t t是干啥的。
事实上,参数t在
de Casteljau
算法中会更加直观
上文中的计算贝塞尔曲线,计算量大(尤其是阶数不止三阶时)还不通用(三阶的算法只能计算三阶的贝塞尔曲线),因此还有另一种算法值得学习,即de Casteljau
算法,这一般也是计算机实现使用的代码。
图源:计算机图形学(孙家广)P303前后
n
+
1
n+1
n+1个点(可以形成
n
n
n条线段),控制形成
n
n
n阶贝塞尔曲线,所以不难看出为什么一次Bezier曲线控制点矩阵有两个点(即
P
0
P_0
P0和
P
1
P_1
P1),高阶类推。