B样条

在数学的子学科数值分析裡，B-样条是样条曲线一种特殊的表示形式。它是B-样条基曲线的线性组合。B-样条是貝茲曲線的一种一般化，可以进一步推广为非均匀有理B样条（NURBS），使得我们能给更多一般的几何体建造精确的模型。 De Boor算法是一个数值上稳定的计算B样条的方法。 术语 B样条是Isaac Jacob Schoenberg创造的，B 是基（basis）样条的缩略。 给定m+1 个节点ti ，分布在[0,1]区间，满足 t 0 < t 1 < … < t m {\displaystyle t_{0}<t_{1}<\ldots <t_{m}} 一个n次B样条是一个参数曲线： S : [ 0 , 1 ] → R 2 {\displaystyle \mathbf {S} :[0,1]\to \mathbb {R} ^{2}} 它由n次B样条基(basis B-spline)组成 S ( t ) = ∑ i = 0 m P i b i , n ( t )  ,  t ∈ [ 0 , 1 ] {\displaystyle \mathbf {S} (t)=\sum _{i=0}^{m}\mathbf {P} _{i}b_{i,n}(t){\mbox{ , }}t\in [0,1]} . Pi称为控制点或de Boor点. m+1个n次B样条基可以用Cox-de Boor递归公式 定义 b j , 0 ( t ) := { 1 t j < t < t j + 1 0 . . . {\displaystyle b_{j,0}(t):=\left\{{\begin{matrix}1&\mathrm {} \quad t_{j}<t<t_{j+1}\\0&\mathrm {...} \end{matrix}}\right.} b j , n ( t ) := t − t j t j + n − t j b j , n − 1 ( t ) + t j + n + 1 − t t j + n + 1 − t j + 1 b j + 1 , n − 1 ( t ) . {\displaystyle b_{j,n}(t):={\frac {t-t_{j}}{t_{j+n}-t_{j}}}b_{j,n-1}(t)+{\frac {t_{j+n+1}-t}{t_{j+n+1}-t_{j+1}}}b_{j+1,n-1}(t).} 当节点等距，称B样条为均匀(uniform)否则为非均匀(non-uniform)。 当B样条是均匀的时候，对于给定的n，每个B样条基是其他基的平移拷贝而已。一个可以作为替代的非递归定义是 b j , n ( t ) := b n ( t + n − j )  ,  j = − 1 , … m + 1 {\displaystyle b_{j,n}(t):=b_{n}(t+n-j)\qquad {\mbox{ , }}j=-1,\ldots m+1} 满足 b n ( t ) := ( m + 1 ) ∑ i = 0 m + 1 ω i ( t i − t ) + m  ,  t ∈ [ 0 , 1 ] {\displaystyle b_{n}(t):=(m+1)\sum _{i=0}^{m+1}\omega _{i}(t_{i}-t)_{+}^{m}\qquad {\mbox{ , }}t\in [0,1]} 满足 ω i := ∏ j = 0 , i ≠ j m + 1 1 t i − t k {\displaystyle \omega _{i}:=\prod _{j=0,i\neq j}^{m+1}{\frac {1}{t_{i}-t_{k}}}} 其中 ( t i − t ) + {\displaystyle (t_{i}-t)_{+}} 是截断幂函数（truncated power function） 当节点数和多项式次数相等时，B样条退化为貝茲曲線。即函数的形状由节点的位置决定。缩放或者平移节点向量不会改变基函数。 样条包含在它的控制点的凸包中 n次B样条的一个基 b i , n ( t ) {\displaystyle b_{i,n}(t)} 仅当在区间[ti, ti+n+1]上非0。就是 b i , n ( t ) = { > 0 t i ≤ t < t i + n + 1 0 . . . {\displaystyle b_{i,n}(t)=\left\{{\begin{matrix}>0&\mathrm {} \quad t_{i}\leq t<t_{i+n+1}\\0&\mathrm {...} \end{matrix}}\right.} 换句话说，如果我们操作一个控制点，我们只改变曲线在局部的行为，而不像Bezier曲线那样是全局行为。 常数B样条是最简单的样条。只定义在一个节点距离上，而且不是节点的函数。它只是不同节点段（knot span）的指示函数。 b j , 0 ( t ) = 1 [ t j , t j + 1 ) = { 1 t j ≤ t < t j + 1 0 . . . {\displaystyle b_{j,0}(t)=1_{[t_{j},t_{j+1})}=\left\{{\begin{matrix}1&\mathrm {} \quad t_{j}\leq t<t_{j+1}\\0&\mathrm {...} \end{matrix}}\right.} 线性B样条定义在两个相邻的节点段上，在节点连续但不可微。 b j , 1 ( t ) = { t − t j t j + 1 − t j i f t j ≤ t < t j + 1 t j + 2 − t t j + 2 − t j + 1 t j + 1 ≤ t < t j + 2 0 . . . {\displaystyle b_{j,1}(t)=\left\{{\begin{matrix}{\frac {t-t_{j}}{t_{j+1}-t_{j}}}&\mathrm {if} \quad t_{j}\leq t<t_{j+1}\\{\frac {t_{j+2}-t}{t_{j+2}-t_{j+1}}}&\mathrm {} \quad t_{j+1}\leq t<t_{j+2}\\0&\mathrm {...} \end{matrix}}\right.} 一个片断上的B样条的表达式可以写作： S i ( t ) = ∑ k = 0 3 P i − 3 + k b i − 3 + k , 3 ( t )  ,  t ∈ [ 0 , 1 ] {\displaystyle S_{i}(t)=\sum _{k=0}^{3}\mathbf {P} _{i-3+k}b_{i-3+k,3}(t)\qquad {\mbox{ , }}t\in [0,1]} 其中Si是第i个B样条片断而P是一个控制点集，i和k是局部控制点索引。控制点的集合会是 P i w = ( w i x i , w i y i , w i z i , w i ) {\displaystyle P_{i}^{w}=(w_{i}x_{i},w_{i}y_{i},w_{i}z_{i},w_{i})} 的集合，其中 w i {\displaystyle w_{i}} 是比重，当它增加时曲线会被拉向控制点 P i {\displaystyle P_{i}} ，在减小时则把曲线远离该点。 片段的整个集合m-2条曲线（ S 3 , S 4 , . . . , S m {\displaystyle S_{3},S_{4},...,S_{m}} ）由m+1个控制点（ P 0 , P 1 , . . . , P m , m ≥ 3 {\displaystyle P_{0},P_{1},...,P_{m},m\geq 3} ）定义，作为t上的一个B样条可以定义为 S ( t ) = ∑ i = 0 m P i b i , ( t ) {\displaystyle S(t)=\sum _{i=0}^{m}\mathbf {P} _{i}b_{i,}(t)} 其中i是控制点数，t是取节点值的全局参数。这个表达式把B样条表示为B样条基函数的线性组合，这也是这个名称的原因。 有两类B样条-均匀和非均匀。非均匀B样条相邻控制点间的距离不一定要相等。一个一般的形式是区间随着插入控制点逐步变小到0。 In Matlab，the command“spline” can be used for spline interpolation. (Note： In the command, the cubic B-spline is used) Cubic B-Spline Interpolation by Matlab Generating a sine-like spline curve and samples it over a finer mesh: x = 0:1:10; % original sampling points y = sin(x); xx = 0:0.1:10; % new sampling points yy = spline(x,y,xx); plot(x,y,'o',xx,yy) 事前安裝模組 pip install numpy pip install scipy pip install matplotlib Cubic B-Spline Interpolation by Python from scipy.interpolate import interp1d import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 11) # original sample points, [0, 1, 2, …, 9, 10] y = np.sin(x) f = interp1d(x, y, kind=' cubic ') ) # Cubic means the cubic B-spline. x_new = np.arange(0, 10.1, 0.1) # new sample points, [0, 0.1, 0.2, ….., 9.9, 10] y_new = f(x_new) plt.plot(x,y,'o',x_new, y_new) plt.show() 关于此处涉及的算法，在著作中有针对Bézier、B样条（B-spline）以及非均匀有理B样条（Nurbs）的相关算法的详细数学表达和程序实现方法。 在几何处理中，对参数曲线及曲面的求导是最基本的运算之一，由于参数表达的特性，在给定点的切线及法线可通过求导直接得到。 先来考察曲线的情形：采用本页定义中的B样条曲线表达式 S ( t ) = ∑ i = 0 m P i b i , n ( t )  ,  t ∈ [ 0 , 1 ] {\displaystyle \mathbf {S} (t)=\sum _{i=0}^{m}\mathbf {P} _{i}b_{i,n}(t){\mbox{ , }}t\in [0,1]} 对参数 t {\displaystyle t} 进行求导： d S d t = ∑ i = 0 m b i , n ′ ( t ) P i {\displaystyle {\frac {d\mathbf {S} }{dt}}=\sum _{i=0}^{m}b'_{i,n}(t)\mathbf {P} _{i}} 样条 De Boor算法 非均匀有理B样条 本條目部分或全部内容出自以GFDL授權發佈的《自由線上電腦詞典》（FOLDOC）。 Les Piegl and Wayne Tiller: The NURBS Book, Springer-Verlag 1995-1997 (2nd ed). Jian-Jiun Ding, “Time Frequency Analysis and Wavelet Transforms ”, NTU, 2021. Interactive java applets for B-splines（页面存档备份，存于互联网档案馆） Introduction to Computing with Geometry Notes (Dr.C.-K.Shene/Michigan Technological University)（页面存档备份，存于互联网档案馆）