第3章〓近似样条 3.1引言 前面的章节讨论了如何使用控制点(CP)和调和函数(BF)来表征插值样条和混合样条。贝塞尔样条曲线是图形包中用于建模样条曲线的非常流行和广泛使用的工具。然而,贝塞尔样条有两个主要缺点,这一直是设计近似样条的动机。第一个缺点是CP的数量取决于曲线的阶数,即不可能在不增加多项式阶数和计算复杂度的情况下增加CP的数量以实现更平滑的控制。第二个缺点是没有提供局部控制,即移动单个CP的位置将改变整个样条的形状,而不是样条的局部部分。在局部图形中,控制通常是可取的,因为它可以对样条进行小幅调整[Hearn and Baker,1996]。 为了克服这些缺点,已经提出了一种称为B样条(Bspline)的新型样条。B样条代表“基本样条”,它们是真正的近似值,即通常它们不经过任何CP,但在特殊条件下它们可能被迫这样做。本质上,B样条由多个在连接点处具有连续性的曲线段组成。这可以实现局部控制,即当移动CP时,仅更改一组局部曲线段而不是整个曲线。B样条的BF是使用算法(称为Cox de Boor算法)来计算的,该算法以德国数学家CarlWilhelm Reinhold de Boor命名。连接点处的参数变量t的值存储在称为“结向量(KV)”的向量中。若结点值是等间距的,则生成的样条称为均匀B样条; 否则,称为非均匀B样条。当KV值重复时,称为开放均匀B样条。 BF和B样条方程不是单个实体,而是每个段的表达式集合。例如,若有4个段,分别指定为A、B、C和D,则每个BF(记为B)具有4个子分量BA、BB、BC和BD,并表示为B={BA,BB,BC,BD}。若有3个CP,即P0、P1和P2,则将有3个BF: B0、B1和B2,每个都有4个子分量,即B0A,…,B0D,B1A,…,B1D和B2A,…,B2D。通常每行一个BF表示为 B0={B0A,B0B,B0C,B0D} B1={B1A,B1B,B1C,B1D} B2={B2A,B2B,B2C,B2D} 类似地,曲线方程P也将具有4个子分量,P={PA,PB,PC,PD}。我们之前已经看到,曲线方程可以表示为CP和BF的乘积,因此子分量可以写为: PA=P0.B0A+P1.B1A+P2.B2A,PB=P0.B0B+P1.B1B+P2.B2B等。注意,子分量对t的不同范围有效,因此不能相加,但需要表示为值矩阵。通常,段A在t0≤ t < t1 范围内有效,段B在t1≤ t < t2范围内有效,以此类推。由于曲线表达式可能非常大,在大多数情况下,方程是垂直而不是水平编写的,每个段的值范围都提到了,如下所示: P=PA=P0.B0A+P1.B1A+P2.B2A(t0≤t1,根据一阶项计算。该算法将在后面说明。需要注意的一点是,该算法本质上是递归的,因为与d相关的高阶项是根据与d-1阶相关的低阶项计算的。因此,即使曲线方程只需要有式(3.1)中所示的二阶项Bk,2,还是首先需要计算一阶项Bk,1。 要找到BF和曲线方程,必须分别分析每一段。但首先,需要KV的数值。让我们做一个简化的假设,KV值如下: t0=0、t1=1、t2=2、t3=3、t4=4。因此KV变为T=[0,1,2,3,4]。在适当时,我们将证明这个假设是正确的。 段A: t0≤ t < t1: B0,1=1,B1,1=0,B2,1=0,B3,1=0,B4,1=0B0,2=t-t0t1-t0B0,1+t2-tt2-t1B1,1=tB1,2=t-t1t2-t1B1,1+t3-tt3-t2B2,1=0B2,2=t-t2t3-t2B2,1+t4-tt4-t3B3,1=0 段B: t1≤ t < t2: B0,1=0,B1,1=1,B2,1=0,B3,1=0,B4,1=0B0,2=t-t0t1-t0B0,1+t2-tt2-t1B1,1=2-tB1,2=t-t1t2-t1B1,1+t3-tt3-t2B2,1=t-1B2,2=t-t2t3-t2B2,1+t4-tt4-t3B3,1=0 段C: t2≤ t < t3: B0,1=0,B1,1=0,B2,1=1,B3,1=0,B4,1=0B0,2=t-t0t1-t0B0,1+t2-tt2-t1B1,1=0B1,2=t-t1t2-t1B1,1+t3-tt3-t2B2,1=3-tB2,2=t-t2t3-t2B2,1+t4-tt4-t3B3,1=t-2 段D: t3≤ t < t4: B0,1=0,B1,1=0,B2,1=0,B3,1=1,B4,1=0B0,2=t-t0t1-t0B0,1+t2-tt2-t1B1,1=0 B1,2=t-t1t2-t1B1,1+t3-tt3-t2B2,1=0B2,2=t-t2t3-t2B2,1+t4-tt4-t3B3,1=4-t 注意,每段都有一个特定的k值,但我们在计算BF时仍然在其他可能的值上循环k,因为我们想找出其他CP对那个段的影响。例如,对于段A,B0,2=0,但是我们计算B1,2和B2,2来找出第二个CP和第三个CP对段A的影响。在这种情况下,我们看到B1,2和B2,2为零,表示段A仅受第一个CP即P0控制,不受其他CP即P1和P2影响,见式(3.1)。同样对于段B,k=1,但我们看到B0,2和B1,2都是非零值,这意味着段B受两个CP,即P0和P1的影响。 现在根据式(3.1),确定曲线公式所需的BF为B0,2、B1,2和B3,2。然而,这些BF对于不同的段具有不同的值。因此,需要将所有这些值收集在一起,指定它们有效的段。这里使用单独的下标A、B、C和D来表示相关段。 B0,2={B0,2A,B0,2B,B0,2C,B0,2D} B1,2={B1,2A,B1,2B,B1,2C,B1,2D} B2,2={B2,2A,B2,2B,B2,2C,B2,2D}(3.3) 表3.1总结了BF值的分段计算。如前所述,假设KV为T=[0,1,2,3,4]。 表3.1线性均匀B样条的BF计算 段tBk,1Bk,2 At0≤t< t1 B0,1=1B0,2=t B1,1=0B1,2=0 B2,1=0B2,2=0 B3,1=0 Bt1≤t