上篇中我们讲解了贝塞尔曲线

B样条是贝塞尔曲线的延申,贝塞尔曲线是B样条的基础, B样条可以看成很多组贝塞尔曲线的拼接。因此,如果你还不了解贝塞尔曲线,建议你先看懂上一篇。

由来

贝塞尔曲线是在汽车的曲线设计种首次被提出的,汽车的外形设计十分复杂,控制点的表示方式能够简化其数学描述,将其数学化的表示出来。

如今汽车的线条感很强,曲线设计很复杂

还记得贝塞尔曲线的特质吗?主要的两个, 1 阶次是控制点个数减1, 2 牵一发动全身,移动一个控制点,整段曲线都会变化。

如果要用贝塞尔曲线来设计上图种的汽车造型, 那么汽车的设计简直是噩梦,形状复杂的曲线需要更多的控制点,曲线的阶次就会变得非常高。牵一发而动全身, 想改一下车屁股的造型, 移动一下控制点,结果车头的造型也被改变了。

为了克服贝塞尔曲线的以上两大缺点,B样条应运而生了。

因此B样条的两个性质就是贝塞尔的缺点反过来:1 可以指定阶次。2 移动控制点仅仅改变曲线的部分形状,而不死整体

B样条采用解决方案是贝塞尔曲线的拼接,也就是把一条曲线变为多段贝塞尔曲线的拼接。

定义

先看B样条的定义:

B样条有三大要素:节点,控制点,阶次。

控制点和贝塞尔的一样,就是空间上决定曲线形状的点。

U m + 1个非递减数的集合,u0 <= u2 <= u3 <= ... <= umui称为节点knots), 集合U 称为节点向量knot vector), 半开区间[ui, ui+1) 是第i个节点区间(knot span)。注意某些ui可能相等,某些节点区间会不存在。如果一个节点 ui 出现 k 次 (即,ui = ui+1 = ... = ui+k-1), 其中 k > 1, ui 是一个重复度(multiplicity)为k 的多重节点,写为 ui(k)。 否则,如果ui只出现一次,它是一个简单节点。如果节点等间距(即, ui+1 - ui 是一个常数,对 0 <= i <= m - 1),节点向量或节点序列称为均匀的;否则它是非均匀的。

节点可认为是分隔点,将区间[u0, um]细分为节点区间。所有B-样条基函数被假设定义域在[u0, um]上。在本文中,我们经常使用u0 = 0和um = 1,所以定义域是闭区间[0,1]。

比如节点向量是 [0, 0.3, 0.5, 0.7, 0.9, 1.0]

上图是一段B样条曲线,六个节点把曲线分成了五段,节点向量为 [0, 0.3, 0.5, 0.7, 0.9, 1.0]

为了定义B-样条基函数,我们还需要一个参数,基函数的次数(degree)p,第ip次B-样条基函数,写为Ni,p(u),递归定义如下:

上述公式通常称为Cox-de Boor递归公式。 这个定义看起来很复杂;但是不难理解。如果次数(degree)为零(即, p = 0),这些基函数都是阶梯函数,这也是第一个表达式所表明的。即,如果u是在第i个节点区间[ui, ui+1)上基函数Ni,0(u)是1。 例如,如果我们有四个节点u0 = 0, u1 = 1, u2 = 2和 u3 = 3, 节点区间 0, 1 和2是[0,1), [1,2), [2,3),0次基函数是N0,0(u) = 1 在 [0,1) ,在其它区间是0;N1,0(u) = 1 在 [1,2)上,在其它区间是0;N2,0(u) = 1在[2,3)上,其它区间是0。如下图所示:

这一部分一定要理解,为什么是这种阶梯函数呢?其实0阶的意思就是比线性插值低一阶,两个点之间的线性插值是一阶曲线,那么0阶呢? 就是不是线了,就是点。

因此如果你要的B样条曲线是0阶的,那么最终你得到的不是一条曲线,就是一个一个的离散控制点,因为基函数除了1就是0嘛。

一阶B样条曲线是啥呢?就是把控制点按照顺序连起来得到的曲线,这样的意义就是如果在两个控制点之间的就是直接利用这两个点就行线性插值,再看看Ni,p(u)的定义,不就是低一阶曲线的线性插值了嘛, 如果低一阶的曲线是0阶曲线,那么不就是两点之间的线性插值嘛。

建议再看一下我在贝塞尔曲线那一篇如何用逐渐减低阶次的方式递归来理解的。你就明白了,B样条就是贝塞尔穿了个马甲。

为了理解p大于0时计算Ni,p(u)的方法,我们使用三角计算格式。所有节点区间列在左边(第一)列,所有零次基函数在第二列。见下图。

因此,第一列就是控制点,第二列是第一列控制点的线性插值,第三列是第列点的线性插值,以此类推。

两个重要的性质

因为 Ni,1(u) 是从 Ni,0(u) 和 Ni+1,0(u)计算的而 因为Ni,0(u)和Ni+1,0(u) 在区间[ui, ui+1)和[ui+1, ui+2)分别是非零的,Ni,1(u) 在这两个区间都是非零的。换句话说,Ni,1(u)在[ui, ui+2)上是非零的。相似地,因为 Ni,2(u) 依赖于Ni,1(u) 和Ni+1,1(u)且因为这两个基函数在[ui, ui+2)和[ui+1, ui+3)分别是非零的,Ni,2(u)在[ui, ui+3)上非零。总之,为确定基函数Ni,p(u), 的非零定义域,可以追溯到三角计算格式直到回到第一列。例如,假设我们想找到 N1,3(u)的非零定义域。基于上述讨论,我们可从西北和西南方向追溯直到第一列为止,如下图中蓝色虚线所示。因此 N1,3(u)在 [u1, u2), [u2, u3), [u3, u4) 和[u4, u5)上是非零的。或,相等地,它在[u1, u5)上非零。.

这个具体是什么意思呢: 因为基函数N 最后是和控制点直接相乘的,换句话说,基函数N不为零就意味着控制点被用上了,如果基函数N为零就意味着控制点根本就没有用上。

总之,我们有下列观察:

基函数 Ni,p(u) 在[ui, ui+p+1)上非零。或,相等地,Ni,p(u) 在 p+1个节点区间[ui, ui+1), [ui+1, ui+2), ..., [ui+p, ui+p+1)上非零。

我再把这句话翻译成大家更理解的话。Ni,p(u) 就是p阶的B样条函数,第i个控制点仅仅在[ui, ui+1), [ui+1, ui+2), ..., [ui+p, ui+p+1)被用上了,在其他的节点区间[ui,, ui+p+1)之外,根本就没用上。

接着,我们看相反的方向。给定一个节点区间[ui, ui+1),我们想知道哪个基函数会在计算中使用这个区间。我们可以以这个节点区间开始并画一个西北界限箭头和一个西南界限的箭头。所有封闭在楔形里的基函数使用 Ni,0(u)(为什么?)因此在该区间是非零的。因此,所有在[ui, ui+1)上非零的p 次基函数是这个楔形和包含所有Ni,p(u) 的列的交集。实际上,这一列和两个箭头形成一个等边三角形,而这一列是垂直边。 从 Ni,0(u) 数到 Ni,p(u) 有p+1列。因此,等边三角形的垂直边至多有p+1 项,即 Ni,p(u), Ni-1,p(u), Ni-2,p(u), ..., Ni-p+2,p(u), Ni-p+1,p(u) 和Ni-p,p(u)。

让我们看上图。为了找到所有3次在 [u4, u5) 上非零的基函数,画出两个箭头和所有在垂直边的函数是我们想要的。这个例子,是N1,3(u), N2,3(u), N3,3(u), 和N4,3(u).用黄色三角表示。蓝色 (resp., 红色) 三角显示的是在[u3, u4) (resp., [u2, u3) )上非零的3次基函数。注意在[u2, u3)上只有3个3次基多项式。.

总之,我们观察到下列特性:

在任何一个节点区间 [ui, ui+1), 最多有 p+1个p 次基函数非零,即:Ni-p,p(u), Ni-p+1,p(u), Ni-p+2,p(u), ..., Ni-1,p(u) 和 Ni,p(u),

我再把这句话翻译成大家更理解的话。区间 [ui, ui+1)中,只有第i-p个控制点到第i和控制点被用上了,其他的控制点的位置不会相应区间 [ui, ui+1)上曲线的形状。p阶次的B样条,最多用到相对应的p+1个点。 再仔细回想一下,这不就是贝塞尔曲线的性质嘛,曲线的阶次等于控制点的个数减1.

因此,你就能更深一步的理解B样条曲线是贝塞尔曲线拼接而来的,在每一个节点的区间内都可以看作一个贝塞尔曲线。

B样条区间

B样条的定义是有区间的,对于open B样条的定义区间为:

For open B-spline curves, the domain is [up, um-p].

那么在区间 [up-1,up)呢? 答案是没有定义,可能会按照B样条的求解能得到一条曲线,但是错了,这条曲线是不不对的。

举一个例子:

U = { 0, 0.25, 0.5, 0.75, 1 }, 阶数为1,控制点的个数是3个。

不同区间上的基函数

在区间[0,0.25),只有基函数N0,1(u)不为0,意味着仅仅是第一个控制点在起作用。

因此在区间[0,0.25)上,B样条的曲线是从原点(0,0)到第一个控制点的一条直线,这显然不是我们想要的B样条。

因此,直接规定For open B-spline curves, the domain is [up, um-p].

书接下篇

专栏里每一篇都是我一个字一个字打的,都是我认为的原创干货。
欢迎指正讨论,转载请注明,认同请点赞。
这个系列的文章很容易出错,希望大佬们多多指正补充。
仅仅收藏是学不会的,还得点赞喜欢加转发啊。

本文的主要参考资料:

搜索结果提示 - 博客园找找看
CS3621 Introduction to Computing with Geometry Course Notes
B-样条曲线教程(B-spline Curves Notes)目录