1.4 NURBS的参数方程及其特性
1.4.1 Bezier曲线及其用途
之所以要讨论Bezier曲线,是因为它对NURBS曲线的产生起到了启发和促进的作用,可以使我们对NURBS的发展有更清晰的理解。自工业革命以来,机械工程大都采用直线和圆弧等二次圆锥曲线能用方程表示的曲线来设计零部件,而对于自由曲线曲面的描绘则办法不多,没有确切的数学表达式,只能近似而不能精确地设计它们的形态。进入20世纪后期,一些曲面较多的产品,例如汽车、飞机、轮船等,需要用更灵活的曲线描绘方法来设计。另外,工业设计的发展促进了产品外观的多样化,产品造型设计的美学需求要求有更自由、简便、精确的曲线曲面描绘方法,要求建立自由曲线曲面的数学模型。为顺应这种需求,法国雷诺汽车公司的工程师贝塞尔(Pierre Bézier)对此进行研究,建立了一套自由曲线曲面设计系统—UNISURF。贝塞尔出生于工程师世家,在巴黎工艺高等专科学校获得机械工程师学位,后来在巴黎大学获得科学博士学位,大学毕业后加入了雷诺汽车公司,并在此工作了42年,直至1975年退休。在20世纪60年代,他对CAD/CAM领域的曲线数学描述产生了兴趣,对此进行研究并提出了自己的解决方案。他采用一种数学方法来设计曲线,产生的曲线可以由一系列点来交互控制,这些点叫做控制点,设计师只要移动控制点的位置,就可以很方便地改动曲线的形状,非常直观,曲线非常光滑。
我们可以通过割角法来引出贝塞尔曲线方程。在探索曲线数学模型的研究中,对于如何产生自由曲线,一个很自然的想法就是类似于曲面零件的磨削加工过程,把一个有棱角的毛坯不断地磨去棱角从而磨出曲面。Lane 和Riesenfeld提出,可以采用对多边形进行割角的方法来产生曲线。
如图1.11所示,P0、P1、P2、P3、P4为一个空间四边形的顶点,这个四边形各边的中点是P1,0、P1,1、P1,2、P1,3(用第一个下标表示第一次割角,第二个下标表示序号),得到3条线段P1,0P1,1、P1,1P1,2、P1,2P1,3,再连接这3条线段的中点P2,0、P2,1、P2,2,又得到两条线段,再连接这两条线段的中点P3,0、P3,1,求出线段P3,0P3,1的中点P4,0,这样得到两个新的四边形P0、P1,0P2,0、P3,0P4,0和P4,0P3,1P2,2P1,3P4。
图1.11 割角法产生曲线
再对这两个新四边形重复上述的过程,依此类推,不断重复,可以证明(证明过程从略)最终产生的新多边形的极限会收敛于一条曲线,这条曲线就是Bezier曲线,它的方程式为
观察式(1.8)会发现,贝塞尔曲线的方程符合式(1.7)对空间曲线矢量方程的推测,式中,Bi,n(u)是基函数(Basis Function),Pi称为控制点(Control Point)。再对比式(1.4)和式(1.8)会发现,二者的基函数不一样,Bezier曲线的基函数Bi,n(u)为:
这个基函数称为n阶伯恩斯坦(Bernstein)基函数。其中,Bi,n(u)的第一下标i表示控制点的序号,第二个下标n表示曲线阶数。这里暂不讨论它的数学推导,只讨论Bezier曲线具有的特征。
如图1.12所示为两条3阶Bezier曲线,P1、P2、P3、P4为控制点,控制点连线构成控制多边形,当u在[0,1]区间取值时,计算出的蓝色曲线即为3阶Bezier曲线。
图1.12 3阶贝塞尔曲线
Bezier曲线具有如下特性:
控制点数等于阶数加1。例如,3阶Bezier曲线有4个控制点。
曲线形状跟随控制多边形。移动控制点,曲线形状随之改变,改变的趋势与控制多边形相近,直观而且便于控制。
第一个和最后一个控制点与曲线端点重合。
线段P1P2和P3P4与曲线端点处的切线方向相同。
控制多边形的形状能够反映曲线形状。
Bezier曲线为使用计算机进行交互设计提供了一个非常方便的工具,设计师只要移动控制点,就可以交互地改变曲线的形状,曲线形状可由控制多边形的形状预测估计出来,这样就创造性地为设计师提供了一个直观的造型工具。
根据割角法我们引出了Bezier曲线的公式,同样道理,Bezier曲线也可以通过递归割角用几何方法做出。
如图1.13所示,用4个控制点构成的多边形用几何作图法求Bezier曲线上的点。首先在多边形第一条边P0P1上任取一点P1,0,再在第二条边P1P2上取一点P1,1,使,用同样的比率找到点P1,2。连接求得的这3个点得到两条新线段P1,0P1,1和P1,1P1,2,再用同样的比率在这两条线段上进行第二次递推求得点P2,0、P2,1,再用同样比率进行第三次递推求得点P3,0,这个点即为所求的Bezier曲线上的一个点,而且线段P2,0、P2,1在这一点上与曲线相切。改变P1,0的位置即改变d的值,则可得到Bezier曲线上一系列的点。
图1.13 递归割角求3阶贝塞尔曲线
如图1.14所示是多边形顶点的递推示意图,由P0、P1求出P1,0,由P2、P2求出P1,1,依次递推,这个3阶Bezier曲线需要经过3次递推才能得到。读者自己可以证明一下用递归割角法产生的曲线是否是Bezier曲线,方法如下:已知控制点矢量P1、P2、P3、P4,令,利用式(1.4)计算出P1,0、P1,1、P1,2,第二次利用式(1.4)递推出P2,0、P2,1,第三次递推计算出P3,0。作为验证,再通过Bezier曲线式(1.8)和式(1.9)计算出P3,0(i=0~3,n=3),看看二者结果是否一致。
图1.14 多边形顶点递推
1.4.2 Bezier的局限以及B样条曲线
Bezier曲线为交互设计提供了前所未有的直观方便性,但是它本身也存在一些局限性。
设计师在设计过程中,通常需要构造一条曲线,这条曲线要通过几个已知的点。如果我们要构造一条Bezier曲线,要求通过3个特定的点,那么至少需要一条2阶Bezier曲线。同理,至少需要构造一条3阶Bezier曲线才能通过4个已知点。依此类推,设计的形状越复杂,越需要构造更高阶的曲线。而高阶Bezier曲线的计算不仅费时,而且结果不太稳定,看来这不是个有效的办法。
那么,把几段低阶Bezier曲线连接起来,构造成复杂的曲线行不行呢?先来观察一下。
如图1.15所示,这是两条3阶Bezier曲线,第一条曲线的控制点为,第二条曲线的控制点为。要使两条曲线位置连续,则必须使两条曲线首尾相接,即;要使两条曲线达到相切连续,则必须如图1.15中所示使共线。在这种情况下,要想使整条曲线保持连续性从而表现得光滑,则这4个控制点的位置必须固定,那么可移动的控制点个数就很少了,我们很难改变局部曲线的形状而不影响曲线的其他部分,想要更灵活地调节曲线形状就变得很困难。那么有没有办法克服Bezier曲线的局限,将多段低阶曲线连接起来形成一条曲线,在曲线满足连续性的前提下还能灵活地对曲线进行局部修改,而且不影响曲线其他部分的形状呢?
图1.15 两条贝塞尔曲线
如前所述,数学家和工程师们找到了一种解决方案,那就是B样条曲线。B样条曲线保留了Bezier曲线的优点,又克服了Bezier曲线的不足之处,它与Bezier曲线的不同点是二者的基函数不同,Bezier曲线采用的基函数是伯恩斯坦(Bernstein)基函数,而B样条曲线采用的是B样条基函数,也许这就是它被称为B样条曲线的原因。
1.4.3 B样条基函数及其特性
许多学者和工程师对B样条曲线的发展做出了贡献,提出了多种B样条基函数的算法,我们在这里只讨论de Boor & Cox的典型算法,这种算法非常适合计算机运算。
用Ni,k(u)来表示B样条基函数,它的定义为
其中,参数u在某一个递增区间{u0,u1,u2,…,um}上取值,即u0≤u1≤u2≤…≤um,Ni,k(u)中第一个下标i是B样条基函数的序号,第二个下标k是阶数。
在以上定义中,递增区间{u0,u1,u2,…,um}叫做节点矢量(注意这里的矢量不是前述几何意义上有方向的量,而是特指一个递增的数字序列),ui叫做节点(Knots)。k是阶数(Degree),也就是Rhino中所指的曲线曲面阶数概念,一个节点区间[ui,ui+1)叫做一个节点跨距(Knot Span)。
我们已经知道,基函数是控制点矢量的系数,它的性质决定了曲线的性质,决定了如何通过控制点矢量生成曲线。需要注意:
计算B样条基函数时,需要先给定节点矢量{u0,u1,u2,…,um}。给定以后,这些值是固定不变的。如图1.16所示用几何作图来图示,节点矢量为{0,1,2,3,4,5,6,7},参数u就在这个区间内取值。
图1.16 节点矢量
注意:在Rhino中,使用指令创建控制点曲线时,节点矢量是程序已经给定的,用户不需要再输入。而使用指令创建内插点曲线时,则需要指定节点矢量是采用均匀、弦长还是弦长平方根。
节点是可以重合的,即,如图1.17所示,u0=u1=u2=0,u6=u7=u8=4,节点矢量为{0,0,0,1,2,3,4,4,4}。重合的节点叫重节点(复节点)。
图1.17 节点矢量(有重节点)
计算B样条基函数需要先确定阶数。
从式(1.10)可以看出,B样条基函数是一个递推的函数,计算k阶基函数需要先计算(k-1)阶的基函数,所以需要先计算零阶函数,才能算出1阶,后续才能计算出2阶基函数,依此类推,如图1.18所示。
图1.18 B样条基函数的递推
例1.1 计算一个3阶B样条基函数,从中体会它的特性。
给定一个节点矢量{0,1,2,3,4,5,6,7},阶数为3,分别计算它的0阶,1阶,2阶,3阶B样条基函数。
(1)计算0阶B样条基函数。
根据式(1.10),函数N0,0(u)的值在u0≤u≤u1即0≤u<1时等于1,在此区间之外N0,0(u)的值都是零。其余函数依此类推,如图1.19所示。其中,左边是Ni,k(u)的值,右边是相应的函数图形。
图1.19 0阶B样条基函数图形
(2)计算1阶B样条基函数。
根据式(1.10)及图1.13,N0,1(u)需要由N0,0(u)、N1,0(u)两个0阶基函数递推计算得出。
1阶B样条基函数N0,1(u)对应的函数图形如图1.20所示。它在u0≤u<u1区间的函数为N0,1(u)=u,在u1≤u<u2区间的函数为N0,1(u)=2-u,在这两个区间之外N0,1(u)均为0。
图1.20 1阶B样条基函数N0,1(u)图形
接着计算其他的1阶B样条基函数,同时绘出相应的函数图形,如图1.21所示。
图1.21 1阶B样条基函数Ni,1(u)图形
(3)计算2阶B样条基函数。
2阶B样条基函数需要两个1阶函数来递推,式(1.11)是基函数N0,2(u)的计算结果,是3个分段函数,我们把它们的图形都表示在图1.22中,这3个函数只在特定的区间上值不为0。如只在[u0,u1)区间上取值,用红色曲线把这一段函数标示出来,同理在[u1,u2)区间图形是绿色曲线,在[u2,u3)区间图形是蓝色曲线,前两段曲线在节点u1处相切,后两段曲线在节点u2处相切,形成一阶连续的关系。
图1.22 2阶B样条基函数N0,2(u)图形
采用同样的计算方法,可以图示出其他的2阶B样条基函数图形,如图1.23所示。
图1.23 其他2阶B样条基函数N0,2(u)图形
(4)计算3阶B样条基函数。
3阶B样条基函数图形如图1.24所示。
图1.24 3阶B样条基函数N0,3(u)图形
3阶B样条基函数需要两个2阶基函数来递推,3阶B样条基函数N0,3(u)的图形由4个区间的4段函数曲线连接而成,这些曲线在连接点2阶导数相等,也就是2阶连续。其余的3阶B样条基函数图形如图1.25所示。
图1.25 3阶B样条基函数N1,3(u)~N3,3(u)图形
通过例1.1,可发现B样条基函数具有如下特性:
0阶B样条基函数Ni,0(u)只在一个节点跨距[ui,ui+1)内值不为0,1阶B样条基函数Ni,1(u)在两个节点跨距[ui,ui+2)内值不为0,依此类推,没有重复节点的k阶Ni,k(u)在(k+1)个节点跨距[ui,ui+k+1)内值不为0。
如图1.24所示,3阶B样条基函数是由4个函数组成的,这4个函数在节点相连。例如在[u0,u1)跨距内,样条函数由方程表示,变换到[u1,u2)跨距内,样条的方程变换为,也就是说,参数u每跨越一个节点,样条函数就变换到另一个函数表达式。依此推理,没有重复节点的k阶B样条基函数由(k+1)个函数组成,这些分段函数在节点处是(k-1)阶连续。
节点矢量可以是均匀的,也可以是非均匀的,如{0,1,2,3,4,5,6,7}是均匀的,而{0,1,2,2.5,4,5.5,6,7}则是非均匀的。
基函数在支撑跨距内其图形是一个山形,只有一个最大值。
1.4.4 B样条曲线
参考式(1.7),一个k阶B样条曲线方程式为:
其中,Ni,k(u)是B样条基函数,Pi是B样条曲线的控制点矢量。
1.4.3节讨论过,计算B样条基函数需要给定节点矢量、指定阶数,从式(1.12)可知,创建一条B样条曲线还需要指定控制点。在Rhino中,节点矢量不需要用户输入,而是由程序生成,用户创建曲线只需要指定阶数,在屏幕或指令窗口上输入控制点。输入的最少控制点个数等于阶数加1。例如,创建一个3阶曲线,至少需要输入4个控制点。如果只输入3个控制点,则只能形成一条2阶曲线。
下面通过例子来理解B样条曲线的特点。
1.B样条基函数的几何意义
例1.2 给定一个节点矢量{0,1,2,3,4,5}以及3个控制点P0、P1、P2,计算其2阶B样条曲线。
首先,画出基函数的图形,如图1.26所示。
图1.26 2阶B样条基函数N0,2(u)、N1,2(u)、N2,2(u)图形
N0,2(u)、N1,2(u)、N2,2(u)的图形,三者只在[u2,u3)上同时不为0,所以在此跨距内所求B样条曲线为:
当u在[u2,u3)上连续移动取值时,Q(u)相应的运动轨迹即为所求2阶B样条曲线。
以上的公式计算过程比较抽象,下面用一系列图示方法来演示B样条曲线的计算过程,将会更直观地理解B样条曲线的生成过程及其几何意义。
(1)如图1.27所示,用平面坐标系来演示(三维坐标系可用同样方法),在坐标系中指定P0、P1、P23个控制点。
图1.27 坐标系及3个控制点矢量
(2)u=u2=2时,由式(1.13),根据矢量加法的平行四边形法则求出Q(2),如图1.28所示。
图1.28 求出Q(2)
(3)u=2.5时,由式(1.13),根据矢量加法的平行四边形法则求出Q(2.5),如图1.29所示。
图1.29 求出Q(2.5)
(4)u=3时,由式(1.13),根据矢量加法的平行四边形法则求出Q(3),如图1.30所示。
图1.30 求出Q(3)
(5)这里只图示了Q(2)、Q(2.5)、Q(3)3个点,其余点也可求出。连接这些点,即为所求的2阶B样条曲线,如图1.31所示。
图1.31 2阶B样条曲线
由例1.2可以从几何上深入理解基函数的作用,从式(1.13)可以看出,2阶B样条曲线等于3个控制点矢量乘以相应的基函数再求和,那么相应的基函数可以看作控制点矢量的系数,系数决定了控制点对曲线的“控制力”或“影响力”。例如,u=u2=2时,,P0和P1对样条曲线的“影响力”各占50%,而P2的影响力为0;随着参数u“离开”节点2、“跑向”节点3,P0的影响力逐渐减少,P1和P2的影响力逐渐增大,曲线就离开点向P1和P2的方向运动,在u=2.5时,,P0的影响力减少为12.5%,P1的影响力达到最大为75%,P2的影响力为12.5%,;过了这个点,P2的影响力逐渐增大,到u=3时,,P0的影响力为0,P1和P2的影响各占50%。所以,如果把控制点矢量比作力,则样条曲线是这些力的合力,而基函数就像一个有很多只手的总调度员,统筹调配、决定各个控制点力按照怎样的比例参与合力作用,从而最终得到合力,也就是光滑的样条曲线。再回顾一下图1.26,可以很直观地观察到3个基函数在[u2,u3)内此涨彼伏的变化趋势及其所占的比重大小,P0的影响力从50%减少到0,P1的影响力从50%增加到75%,又减少到50%,P2的影响力从0增加到50%。
很自然地,我们会注意到,在[u2,u3)内,N0,2(u)+N1,2(u)+N2,2(u)≡1,也就是3个基函数的和始终等于1,3个控制点对曲线的影响力总和始终为100%,一个控制点影响力减小,另外的控制点影响力必然增加,但影响力总和保持不变。其实这是B样条基函数的重要性质之一,不管曲线的阶数是多少,这一性质始终成立,有兴趣的读者可以自己证明或参考其他书籍。
总结起来,B样条曲线公式(1.12)可以这样来理解:一条k阶B样条曲线,就是控制点矢量和的轨迹线,在每个节点跨距内有(k+1)个控制点对曲线施加影响力,这(k+1)个控制点影响力的总和为100%,在这100%内各个控制点影响力所占比例大小由其系数统筹分配,这个系数就是基函数。曲线阶数越高,同时对曲线施加影响力的控制点越多,每个控制点所占的比例就越少,曲线就越不容易受个别控制点的影响而剧烈波动,曲线就显得越平滑,同时B样条基函数也变得平缓,使得曲线更光顺。
2.重节点(复节点)
从例1.2可以发现,样条曲线的起始点和终点并没有与第一个和最后一个控制点重合,操作起来非常不方便。为了弥补这一不足,就要用到重节点。
重节点就是两个或多个节点重合在一起,下面来看一下它对曲线的影响。
仍以例1.2中的2阶曲线为例,把节点矢量从{0,1,2,3,4,5}改变为{2,2,2,3,4,5},使原先的节点u0、u1移到u2处,使3个节点重合u0=u1=u2=2,变化后的B样条基函数图形如
图1.32所示,细虚线是没有重节点时的基函数图形,粗实线表示有重节点时的基函数图形。
图1.32 u0、u1、u23个节点重合
节点重合后,[u0,u1)、[u1,u2)两个跨距为0,受其影响,N0,2(u)和N1,2(u)两个基函数发生变化,N0,2(u)退化到一个跨距内不为0,N1,2(u)退化到两个跨距内不为0。
则u=u0=u1=u2=2时,N0,2(u)=1,N1,2(u)=N2,2(u)=0,Q(2)=1×P0+0×P1+0×P2,也就是说,P0对曲线的影响力为100%,另外两个控制点对曲线影响为0,曲线上这一点的位置完全由P0决定,在这一点曲线点与P0点重合,绘出的曲线如图1.33所示,这样,通过操纵控制点P0就可以控制曲线端点的位置,非常方便。
图1.33 曲线端点Q(2)与第一个控制点重合
按照同样的方法,把节点u4、u5移动到与u3重合,使u3=u4=u5=3,则节点矢量改变为{2,2,2,3,3,3},则B样条基函数图形变为如图1.34所示,相应的曲线图形如图1.35所示。
图1.34 两端均为重节点的2阶B样条基函数图形
图1.35 两端均为重节点的2阶B样条曲线
通过在两端设立重节点,可以使曲线的端点与首末控制点重合,从而使曲线的创建更容易和直观,目前我们使用的“B样条曲线”的概念默认的就是这种曲线。CAD类软件大都使用这种方法,在Rhino中把重节点叫做“复节点”,其实含义都是一样的。本例中,2阶曲线两端3个节点重合,叫做节点的重合度(或叫做重复读)等于3。如果是3阶曲线,可以证明节点重复度应该是4。依此类推,一条k阶B样条曲线,其首末两端节点的重复度=阶数+1(Rhino中,首末两端节点的重复度=阶数,在后面的Rhino章节再讨论)。
另外,从本例可以看出,2阶曲线最少需要3个控制点来确定,同时最少需要6个节点。依此类推,3阶曲线最少需要4个控制点和8个节点;k阶曲线最少需要(k+1)个控制点,需要2×(k+1)个节点。有n个控制点的k阶曲线节点数为(k+n+1)。
3.多段B样条曲线
前面我们举了一个2阶B样条曲线的例子,这条曲线的支撑区间在[u2,u3)一个节点跨距内,这样单一跨距的曲线等同于1.4.3节讨论的单一Bezier曲线。其实可以证明,Bezier曲线是B样条曲线的一种特殊形式,当B样条曲线是一条单跨距(Single Span)曲线时,它同时也是一条Bezier曲线。然而我们使用B样条曲线的主要目的是为了构建更复杂的曲线,因此很多时候要使用多段B样条曲线,也就是定义在多个节点跨距上的曲线,下面举例说明。
例1.3 构建一个定义在两个节点跨距区间的2阶B样条曲线。
在例1.2基础上,增加一个节点跨距,则节点矢量为{2,2,2,3,4,4,4},在这两个节点跨距内,有4个2阶基函数不为0,分别是N0,2、N1,2、N2,2、N3,2,比例1.2中多了一个N3,2。经过计算,B样条基函数图形如图1.36所示,相应的B样条曲线如图1.37所示。
图1.36 定义在两个节点跨距的B样条基函数
图1.37 两段2阶B样条曲线
如图1.36所示,相对于单跨距曲线,定义在两个跨距的曲线多了一个跨距,相应地增加了一个基函数,也相应地增加了一个控制点。这条2阶曲线是由两段连接起来的,连接点在Q(3)点也就是u=u3=3时的曲线点,当参数u在[u2,u3)跨距上时,N0,2、N1,2、N2,23个基函数的值不为0,相应地P0、P1、P23个控制点对曲线产生影响力,当参数过了u=u3=3点到达[u3,u4)跨距上时,基函数N0,2的值变成0失去作用,而又增加了一个基函数N2,2的值从0渐渐增大,增加了一个控制点P3对曲线产生影响力,则在此跨距内P1、P2、P3控制曲线的走向。因此,Q(3)点是分段曲线的连接点,Q(3)=N1,2(3)P1+N2,2(3)P2,因为N1,2、N2,2在u3点切线连续,所以曲线从[u2,u3)跨入[u3,u4)时也是切线连续。Q(2)~Q(3)对应的是节点矢量上的[u2,u3)跨距,移动P0、P1、P2任一个控制点会影响曲线Q(2)~Q(3)段;Q(3)~Q(4)对应的是[u3,u4)跨距,移动P1、P2、P3中任一控制点会影响曲线Q(3)~Q(4)段。一般来说,我们把节点矢量中的u0、u1、u2…un叫做节点,同时,也把参数u等于u0、u1等节点时计算所得的曲线上对应的点叫做节点,也就是本例中的Q(3)点。在Rhino中打开物件捕捉中的节点选项,就可以捕捉这类曲线上的节点。单跨距曲线节点都在两端,曲线中间没有节点,而在创建复杂的长曲线时,我们采用更多段的曲线,每增加一个曲线段,就加入一个节点跨距,增加一个节点。一条k阶多段曲线,如果内节点是单一节点,曲线段在此节点处是(k-1)阶连续,如果此节点是重节点,每次增加重复节点,曲线在节点处连续性降一阶(内节点重节点对曲线的影响参见3.2.9节)。
1.4.5 NURBS曲线
1.4.4节讨论了B样条曲线,在此基础上进一步讨论NURBS曲线,即“非均匀有理B样条”,在B样条(B-Spline)前面加了两个修饰词:非均匀(NonUniform)和有理(Rational)。下面讨论一下“有理”的含义。在前面已经看到了NURBS的曲线方程:
相对于B样条曲线方程,式中多了红色的部分,这部分决定了创建的曲线是“有理”的,这个“有理”是数学上的概念,指的是这个方程采用了有理函数的形式。
B样条曲线方程是一个多项式参数方程,所谓多项式,是指类似于这样形式的函数式,虽然它有很多优点,但是多项式参数方程却无法表达圆、椭圆、双曲线等二次圆锥曲线。例如单位圆的方程可表示为,而用参数方程则(x,y)坐标可表示为
把代入式,经过计算会得出互相矛盾的结果,可见用B样条的多项式方程无法表达二次圆锥曲线。
如果在CAD系统中再采用另外一套方程专门表达圆锥曲线,那么就太麻烦了,最好用一套方程就可以表达出所有需要的曲线。经过努力,数学家和工程师们把B样条曲线方程表达为有理函数形式,解决了这个问题。
在传统数学中,有理函数就是具有如下形式的函数:
也就是说,有理函数是两个多项式相除的形式。圆、椭圆等二次圆锥曲线虽然不能用多项式来表示,但却可以用有理函数来表达。例如,圆心在原点的单位圆的方程为,就可以用有理函数表示为:
在式(1.15)中,有理函数有相同的分母。经过证明,二次圆锥曲线都可以表示成这种具有共同分母的有理形式。最终的NURBS样条曲线方程就是这种有理函数的形式,见式(1.1)。它既可以表示一般的自由曲线,也可以表示圆锥曲线。下面来探讨一下公式中各个部分的含义。
前面讨论了B样条曲线方程直观的几何含义:最终曲线由若干个控制点矢量的和矢量确定,每个控制点矢量都有一个系数,这个系数就是B样条基函数,它决定了控制点矢量以多大比例参与和矢量,B样条基函数协调地控制着各个控制点矢量的比例,最终画出一条光滑的曲线。再来看NURBS的方程,是一个分子分母相除的商的形式,分子是,每个控制点矢量又多了一个系数,也就是说在计算和矢量时,每个控制点矢量在由B样条基函数控制比例的基础上,又由进一步控制其参与和矢量的比例,的值越大,控制点的影响力也就越大。我们就把叫做控制点的“权值”,改变的值,就能够绘出圆、椭圆等圆锥曲线。我们再来看分母,有理函数都是有分母的,那么这个分母是如何确定的?
这个分母可以用“齐次坐标”来说明,NURBS方程式采用了齐次坐标,齐次坐标是为了弥补笛卡儿坐标系的不足而提出的概念。我们通常使用的坐标系是笛卡儿坐标系,由3个互相垂直的x,y,z轴构成的三维空间坐标。在这个坐标系内,互相平行的直线永远不会相交,没有交点,所有互相平行的平面不会相交,没有交线。但是用这个坐标系来表达人眼看到的图像会存在不足,因为人眼看到的图像是透视图,在这个图像中所有互相平行的直线都相交于无限远的一点,所有水平的平面都消失于地平线,这与笛卡儿坐标系的几何原则是不相同的。在笛卡儿坐标系中,无法描绘无限远的点或线。那么如何用数学方法来描述这种透视图形呢?数学家们找到了一种办法,就是用齐次坐标来表示。齐次坐标从外在表现上就是坐标增加一个维度,例如,一条直线上任一点的一维笛卡儿坐标是x,则这个点的齐次坐标是(x,1),比笛卡儿坐标增加一个维度。当然,这个点的齐次坐标不止一个,满足(wx,w)的都是它的齐次坐标。同理,一个平面上点的齐次坐标为(wx,wy,w),三维空间点的齐次坐标为(wx,wy,wz,w)。举例说明,笛卡儿空间内一个点的坐标为(1,2,3),则它的齐次坐标是4个维度(1,2,3,1),当然,(2,4,6,2)、(3,6,9,3)也是它的齐次坐标,满足的都是它的齐次坐标。那么反过来,我们已知一个空间点的齐次坐标为,则它在笛卡儿空间的坐标为。当齐次坐标为时,代表无限远的点,在笛卡儿空间内没有相应的坐标。
下面举一个尽量直观的例子来帮助大家理解齐次坐标和笛卡儿坐标之间的转换关系。
如图1.38所示是两个空间三角形到一个画面的透视投影示意图。我们都知道,画家画画、相机拍摄时,得到的画面是二维的平面图形,是由三维图像向一个中心投影而得到的。图中所示是一个由x,y,w组成的三维空间,a1b1c1和a2b2c2是空间的两个三角形(蓝色),灰色的平面是与xy平面平行的w坐标为1的画面,0为投影中心,空间的两个蓝色三角形在画面上的透视投影恰好重合为三角形abc。图1.38中,点a1、a2向中心0的投影线重合,a1的坐标为(1,1,3),a1的空间坐标为(2,2,6),则可以证明投影点a的坐标为,同样还可以证明点(3,3,9)、(4,4,12)等空间点在画面上透视投影都为a点。这点很容易理解,我们在拍照时,底片上的一个点会对应空间中的无数个点,只不过前面的点会遮挡住后面的点,只有前面的点才能在底片上曝光。由此可理解,三维空间坐标可看作二维照片的齐次坐标,如果空间点的坐标为,则此点在照片上的投影坐标为,三维空间点的二维笛卡儿坐标为。
图1.38 平面上点的齐次坐标
同样的道理,笛卡儿三维空间点(x,y,z)的齐次坐标是4个维度。那么对于B样条曲线,引入齐次坐标既可以满足表达圆锥曲线的有理函数的要求,又便于数学上的运算和推导,特别是便于在CAD系统中进行图形的旋转、缩放等转换运算。
假设一条2阶B样条曲线的控制点为P0、P1、P2,这3个控制点的笛卡儿坐标分别为,再考虑控制点的权值,控制点的齐次坐标为。在齐次坐标的四维空间里,根据式(1.12),同样B样条曲线为
因为矢量的和等于各矢量坐标分矢量的和,即
则有的四维齐次坐标为:
再投影变换到三维笛卡儿坐标系,则有理B样条曲线的三维坐标为
推广到一般,则得到有理B样条方程式(1.1)。
如图1.39所示,在Rhino中绘制一个有理圆形,共有8个控制点,各个控制点的权值为:
图1.39 有理圆
。可知调整控制点权值至特定数值,可以精确绘出圆锥曲线。
在式(1.1)中,若所有控制点权值都等于1,也就是,考虑到,则有
即当所有控制点权值都等于1时,B样条曲线是一条无理曲线。反之,只要有一个控制点权值不为1,曲线就为有理B样条曲线。