B样条曲线和曲面
上一节中,我们讨论了贝塞尔曲线和曲面。虽然它有许多不错的性质,比如变换不变性等, 但是当约束很多的时候,往往需要高阶的曲线来表述。对于\(n\)个控制点,就需要\(n-1\)阶。高阶的曲线在数值计算的时候效率就比较低而且不稳定。针对这一问题, 人们就想到了分段处理。B样条就是其中一种分段表述曲线曲面的方法,它是 B-样条基函数的线性组合,是贝塞尔曲线曲面的一般化。
1. B样条基函数
令\(U = \{u_0, u_1, \cdots, u_m\}\)为一个单调增的实数序列,即\(u_i ≤ u_{i+1}, i = 0, \cdots, m-1\)。那么对于一个\(p\)阶的B样条, 其第\(i\)个B样条基函数 \(N_{i,p}(u)\)可以由\(p-1\)阶的两个B样条基函数线性表出:
$$ N_{i,p}(u) = \frac{u - u_i}{u_{i+p} - u_i} N_{i,p-1}(u) + \frac{u_{i+p+1}-u}{u_{i+p+1} - u_{i+1}} N_{i,p}(u) $$其中\(u_i\)称为节点(knots),\(U\)称为节点向量。特别的,\(0\)阶的B样条基函数定义为:
$$ N_{i,0}(u) = \begin{cases} 1 & \text{if } u_i ≤ u < u_{i+1} \\ 0 & \text{otherwise} \end{cases} $$2. B样条曲线
给定 \(n + 1\) 个控制点\(P_0, P_1, \cdots, P_n\), 以及一个有\(m+1\)个 knot 的节点向量 \(U = \left\{\underbrace{a, \cdots, a}_{p+1}, u_{p+1}, \cdots, u_{m-p-1}, \underbrace{b, \cdots, b}_{p+1} \right\}\), \(p\)次B-样条曲线由这些控制点和节点向量\(U\)定义: $$ C(u) = \Sigma_{i = 0}^n N_{i,p}(u) P_i \ \ \ \ a ≤ u ≤ b $$
在没有特别声明的情况下,我们认定\(a = 0, b = 1\)。当\(n = p\)并且\(U = \{ 0, \cdots 0, 1, \cdots, 1 \}\)时,\(C(u)\)就是一个贝塞尔曲线。\(C(u)\)本身是一个分段的多项式曲线, 阶数\(p\),控制点数量\(n+1\)和 knot 数量\(m+1\)之间具有关系\(m = n + p + 1\)。\(C(0) = P_0, C(1) = P_n\)。具有彷射不变性(Affine invariance)。
给定一个\(u\)我们需要如下三步来计算插值点:
- 找到\(u\)所在的 knot 区间。
- 计算非零的基函数。
- 计算基函数取值和控制点的线性组合。
3. B样条曲面
B样条曲面是由多条B样条曲线在\(u, v\)两个方向上由\((m + 1) \times (n + 1)\)个控制点构成一张网格:
$$ S(u,v) = \Sigma_{i = 0}^n \Sigma_{j=0}^m N_{i,p}(u)N_{j,p}(v) P_{i,j} $$