B-Spline

参考博客:https://blog.csdn.net/qq_40597317/article/details/81155571

推荐开源代码:https://github.com/PositiveTom/Bspline

推荐知乎:https://zhuanlan.zhihu.com/p/3733431707

B-样条是Bezier曲线的一种一般化,B样条不能表示一些基本的曲线,比如圆,所以引入了NURBS,可以进一步推广为非均匀有理B-样条(NURBS)。三者关系可以表示为:

概述

细分定义域

直接细分(Subdividing)曲线是很困难的。因此,我们细分曲线的定义域。因此,如果曲线的定义域是[0,1],这个闭区间被称为节点
(knots)的点细分成。设这些节点是 $0 <= u0 <= u1 <= … <= um <= 1$。那么点C(ui)的曲线细分如下图所示,因此,修改[0,1]的细分会
改变曲线的形状。

如下图,这里有5段曲线组成了整个曲线。下面的直线定义域为[0,1],就是[0,1]被分成五段

img

可以看出,这里定义域被节点细分,节点分别是0, 0.2, 0.4, 0.6, 0.8,1,6个节点正好可以把定义域(即下面的黑色线段)分成5段。

可以看出,6个节点分别对应于曲线上的一个点,可以用 $C(u_i)$ 代表对应的曲线上的点,$C(u_i)$ 被称为节点点(knot point),节点把B-样条
曲线划分成5个曲线段,每个都定义在一个节点区间上。这些曲线段都是 p 次的贝塞尔曲线。

节点

有 $u0 <= u2 <= u3 <= … <= um$;

那么 $u_i$ 被称为节点,显然上述的m=5。

设U是m+1个非递减数的集合,那么有 $U = {u0,u1,…,um}$,集合U称为节点向量(knot vector)。

如果 $u_i = u_{i+1} = … = u_{i+k-1}$,那么 u_i 是一个重复度(multiplicity)为k的多重节点,k>1,否则如果一个节点只出现一次,那么这就是一个简单节点。如果节点等间距,节点向量或节点序列称为均匀的;否则它是非均匀的。$[u_i, u_{i+1})$ 是第i节点个区间,i=0,1,...,m

所有的B样条函数都被假设在定义域$[u0, um]$上,通常$u_0$为0,$u_m$为1

组成

总之,为了设计一个B-样条曲线,我们需要一系列的控制点(就是下图折线的连接点,一共8个),一系列的节点和一系列的系数,每个系数对应一个控制点,所以所有曲线段连接在一起满足某个连续 条件。系数的计算可能是最复杂的步骤因为它们必须保证某个连续条件。

将多个贝塞尔曲线连接就可以得到B样条。如下图所示,这里有8个控制点,依次用线段连接,B样条曲线由一系列5条3次的贝塞尔曲线连接形成。

一般次数越低(即Bezier曲线的次数p越小),那么B样条曲线就更容易逼近他的控制折线

img

特点

以上所有的分段都为Bezier曲线,对于分段Bezier曲线,不同的曲线段相互独立,移动控制点只会影响其所在的Bezier曲线段,而其他的Bezier曲线段都不会改变,甚至所有关于Bezier曲线的算法可以同样地适用于分段Bezier曲线。

核心思想就是:用分段低阶多项式通过连续的连接来代替高阶多项式

数学表达式

为了能描述复杂形状具有局部性质,改用特殊的基函数即 B样条基函数代替 Bernstein 基函数。一条次数为 $j$ 的平面 B样条曲线,由一组控制点 $P_i \in \mathbb{R}^2$ 和一组节点矢量 $t_i$ 组成,其方程为:

$$
X(t) = \sum_{i=0}^{n} B_{i,j}(t) P_i, \quad t \in [t_0, t_1], \quad 1 \leq j \leq n
$$

由考克斯-德布尔递归公式定义的基函数为:
$$
B_{i,0}(t) =
\begin{cases}
1, & t_i \leq t < t_{i+1} \
0, & \text{otherwise}
\end{cases}
$$

$$
B_{i,j}(t) = \frac{(t - t_i) B_{i,j-1}(t)}{t_{i+j-1} - t_i} + \frac{(t_{i+j} - t) B_{i+1,j-1}(t)}{t_{i+j} - t_{i+1}}, \quad 1 \leq j \leq n
$$

其中,约定 $0/0 = 0$;控制点的个数为 $n+1$;节点个数为 $n+j+2$;基函数的阶次为 $j+1$,次数为 $j$。

DeBoor-Cox定义的B样条基函数:

\begin{array}{l}
B_{j,k}(t) = \frac{t - t_j}{t_{j+k-1} - t_j} B_{j,k-1}(t) + \frac{t_{j+k} - t}{t_{j+k} - t_{j+1}} B_{j+1,k-1}(t); \
\end{array}
\begin{array}{l}
B_{i,1}(t) =
\begin{cases}
1, & t \in [t_i, t_{i+1}); \
0, & t \notin [t_i, t_{i+1}).
\end{cases}
\end{array}

分类

这里的分类是根据是根据节点向量里面的元素取值来分类的;呃,这句话可能不是特别好懂,再具体一点,以3个控制点为例;节点向量这样取值: $t∈[0,0.5,1.0]$ ,这样的取值就是均匀B样条基函数,很明显,均匀分割的;准均匀B样条曲线 $t∈[0,0,0,0,0.5,1.0,1.0,1.0,1.0]$ ,两端的控制点重复了三次;非均匀,自然取值非均匀。