本文是小编在工作中遇到的NURBS曲线(Non-Uniform Rational B-Spline)相关的问题时,为了解决这一问题所做笔记的整理。
我当时的需求是需要将NURBS曲线在Rhino和Autocad间传递,这个过程中发现两个软件的NURBS的参数规格并不一致,本文主要记录了我解决这一问题的过程。
在讲述问题的具体内容之前,需要先搞明白NURBS是什么。这就要从样条说起了,其实样条是来源于生产实践,比如用一根软木条加几根钉子就固定出来一个样条了,大概是这样子,真·样条曲线:
但是当计算机绘图开始运用到工程实践中后,怎么表达任意形状曲线并形成统一标准,则成了一个难题。其历史进程就不详说了,下面是一个粗略的曲线标准的包络图,这张图也大致反映了其发展历程:
而NURBS曲线是B-样条(Basis Spline)曲线的拓展,全称为非均匀有理B样条,非均匀和有理的概念会在下面讲述,而关于B-样条曲线,我简述一下其控制因素,为了便于理解,我继续将上述实木样条引入其中进行类比,类比不完全准确,只是对真实情况的近似。
B样条曲线本质上就是把一整条曲线分解为多段贝塞尔曲线的求和,而贝塞尔曲线是根据其基函数推到得出的多项式和,B-样条曲线表达式如下:
其中:Pi是控制多边形的顶点;
u是此参数方程的参数值;
n是总的控制点个数;
k为曲线的次数。
Bi,k为基函数,一般取de Boor-Cox公式:
表达式里的这些变量其实就是B样条曲线的定义需要几大因素:控制点,节点向量,次数,权重。这些也是定义每一段贝塞尔曲线所需要的关键参数。
控制点
通俗的理解,控制点就是上述实木样条的钉子,只是现在不用钉子(曲线上的点)做控制因素,而用一根绳子栓在样条上用力拉,然后手握住绳子的那端的位置点就是控制点。
节点向量
节点向量:
首先节点可以理解为曲线上的点,这些点将曲线分为很多段小曲线,而每个控制点主要影响其中一段曲线,按照刚才的类比就是样条由很多段小木条拼接起来的,而一根绳子上只与一段样条相连,拉动一根绳子主要影响到此段木条的形状,相邻木条会稍微受影响,而更远的木条则保持原样,这也是B-样条区别贝塞尔曲线的重要特征,即每一个控制点只影响有限的曲线段;
在此基础上理解节点向量,整个B样条曲线作为一个参数方程,节点向量就是所有节点的参数值u所组成的一个行向量。所以会有“节点向量之间的区别是向量的差值比例而非绝对值”的说法,因为,差值的比例才决定着整个木条的分段比例。理论上的解释是:可以在贝塞尔曲线的基函数方程里看到包含节点的运算是在这个系数里:
而这个系数只是节点差值的比例罢了,与绝对值无关。
当节点的间距都相等时,即节点向量等分曲线,称曲线均匀(Uniform),间距不等时,称曲线非均匀(Non-Uniform)。
次数
次数,顾名思义就是方程的次数,是贝塞尔曲线中多项式的最高次数,一般取3即可满足大部分工程所需的曲线连续的需求。在实木样条的案例中可以理解为用什么样的材料去做样条。另一个相关概念是曲线的阶数,其值为次数+1。
权重
权重,表达的是控制点对曲线的影响程度,以上述木样条的形式去理解的话就是每根绳子的拉力有多大。当权重都相等时(通常为1),曲线称为非有理(Non-Rational),或简单B-样条曲线,不全相等时称曲线有理(Rational)[1],但权重并未在上述非有理B样条曲线表达式中出现,且不再本文讨论的范围。
关于NURBS的定义我就不再赘述了,回到文章开头提到的问题。
实际工作中发现两软件在节点向量的长度上不一致,Rhino节点向量中节点数量为“次数+控制点数-1”,Autocad中则为“次数+控制点数+1”,一加一减差了两个节点,百思不得其解,而现有资料符合Autocad的数据,即Rhino减少了两个节点。
在Rhino的官方文档中找到了这样一句话:
“Some modelers that use older algorithms for NURBS evaluation require two extra knot values for a total of degree+N+1 knots. When Rhino is exporting and importing NURBS geometry, if needed, it automatically adds and removes these two superfluous knots.”
但是小编寻寻觅觅都没找到文档所述的这个新的NURBS计算方法是什么,只在Rhino官方的论坛里看到一位“官方人员”的表演:
“The superfluous knots have their origin in a theoretical recursive definition of the NURBS basis functions that begins with degree zero basis functions. For NURBS used in modeling, the degree is always >= 1 and the superfluous knots are not needed.Because the people who added NURBS support to IGES, OpenGL, …, didn’t think too clearly, they included the superfluous knot values in the data definitions and these persists in subsequent public formats that copied the early ones and in most NURBS literature. If you examine the evaluation algorithm published in the NURBS book and most other literature, you will see the value of the first and last superfluous knots do not effect the value returned by the evaluation code.”
简言之,他认为指定IGES标准[2]的那些人并没有完全搞清楚节点向量的意义导致多数CAD软件在生成NURBS曲线时储存了多余的节点数据,并透露出一个信息,能省略两个节点的关键信息就在基函数里。
那我就去基函数里寻找,以三次NURBS曲线为例,从程序中截取到的信息中可以看到:节点向量形式符合准均匀B样条曲线[3],即首尾各“阶数+1”个节点的值是分别相等的,其节点向量符合下式:
其中p为曲线的次数。
在此基础上,以4个控制点3次B-样条曲线为例,节点向量{u0,u1,u2,u3,u4,u5,u6,u7}={0,0,0,0,1,1,1,1},
基函数的递归过程如下图所示:
又根据基函数表达式列出B0,1表达式:
因为u0=u1=0,所以u一定等于0,且已知u2=0,代入原式,根据基函数定义可知B0,1=0。
同理可以得到递归过程中所有基函数是否为零,如下图:
可知B0,3为零,而B-样条函数最终是上述基函数求和,B0,3值为零的话就可有可无了啊。
如果把B0,3去掉,那么首节点就不参与计算了,也可以省去。
而最后一个节点U7唯一一次参与计算的地方在B3,3的计算中:
从上述零值函数推导图中可以看到B4,2为零,这样的结果就是唯一一个含有U7的多项式为零,那么此曲线最终表达式也与U7无关,可省去。
总结
上述结果符合Rhino文档中去除两个多余节点不影响曲线结果的说法,并且验证了应该去除的节点是首尾各一个。
声明:这不是证明过程,只是为了理解Rhino文档的说法做的一次简单的推算,如果大佬们发现有错误,欢迎来指正!
注:
[1]、另有一种说法是“有理”是表明NURBS曲线可以用有理多项式进行表达的意思,但小编认为Rational一词在此处并不是有理多项式的意思,只是代表权重的取值。如果此认知有误,欢迎大佬来教我做人。
[2]、IGES全称The Initial Graphics Exchange Specification,是被定义基于Computer-Aided Design (CAD)&Computer-Aided Manufacturing (CAM) systems (电脑辅助设计&电脑辅助制造系统)不同电脑系统之间的通用ANSI信息交换标准。
[3]、准均匀B样条曲线特征是首尾的控制点与节点重合,这个从B样条函数的表达式出发就很容易理解,就是当有次数+1节点值都为同一个值时,由控制点逼近出来的这个点也就与控制点重合了。
参考资料:
1、NURBS – Wikipedia
https://it.wikipedia.org/wiki/NURBS
2、What does NURBS mean and why should I care?
https://wiki.mcneel.com/rhino/nurbs
3、什么是NURBS?
https://www.rhino3d.com/nurbs/
4、《计算几何教程》,王仁宏
为了方便大家交流技术和互通行业资讯,
请添加我们“转自:非解构-公众号”微信,
加入相关讨论交流群。