在数学的子学科数值分析裡，**B-样条**是样条曲线一种特殊的表示形式。它是B-样条基曲线的线性组合。B-样条是貝茲曲線的一种一般化，可以进一步推广为非均匀有理B样条（NURBS），使得我们能给更多一般的几何体建造精确的模型。

De Boor算法是一个数值上稳定的计算B样条的方法。

术语 *B样条*是Isaac Jacob Schoenberg创造的，B 是基（basis）样条的缩略。

定义
--

给定*m*+1 个节点*t**i* ，分布在[0,1]区间，满足

t\_{0}<t\_{1}<\ldots <t\_{m}
一个*n*次**B样条**是一个参数曲线：

{\mathbf {S}}:[0,1]\to {\mathbb {R}}^{2}
它由*n*次**B样条基(basis B-spline)**组成

{\mathbf {S}}(t)=\sum \_{{i=0}}^{{m}}{\mathbf {P}}\_{{i}}b\_{{i,n}}(t){\mbox{ , }}t\in [0,1].
**P***i*称为**控制点**或**de Boor点**. 
*m*+1个*n*次B样条基可以用**Cox-de Boor递归公式** 定义

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):={\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样条曲线

当B样条是均匀的时候，对于给定的*n*，每个B样条基是其他基的平移拷贝而已。一个可以作为替代的非递归定义是

b\_{{j,n}}(t):=b\_{n}(t+n-j)\qquad {\mbox{ , }}j=-1,\ldots m+1
满足

b\_{n}(t):=(m+1)\sum \_{{i=0}}^{{m+1}}\omega \_{i}(t\_{i}-t)\_{+}^{{m}}\qquad {\mbox{ , }}t\in [0,1]
满足

\omega \_{i}:=\prod \_{{j=0,i\neq j}}^{{m+1}}{\frac {1}{t\_{i}-t\_{k}}}
其中 

(t\_{i}-t)\_{+}
是截断幂函数（truncated power function）

注解
--

当节点数和多项式次数相等时，B样条退化为貝茲曲線。即函数的形状由节点的位置决定。缩放或者平移节点向量不会改变基函数。

样条包含在它的控制点的凸包中

*n*次B样条的一个基

b\_{{i,n}}(t)
仅当在区间[*t**i*, *t**i+n+1*]上非0。就是

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样条

常数B样条是最简单的样条。只定义在一个节点距离上，而且不是节点的函数。它只是不同节点段（knot span）的指示函数。

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样条定义在两个相邻的节点段上，在节点连续但不可微。

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样条

一个片断上的B样条的表达式可以写作：

S\_{{i}}(t)=\sum \_{{k=0}}^{3}{\mathbf {P}}\_{{i-3+k}}b\_{{i-3+k,3}}(t)\qquad {\mbox{ , }}t\in [0,1]
其中**S***i*是第*i*个B样条片断而P是一个控制点集，*i*和*k*是局部控制点索引。控制点的集合会是P\_{i}^{w}=(w\_{i}x\_{i},w\_{i}y\_{i},w\_{i}z\_{i},w\_{i})的集合，其中w\_{i}是比重，当它增加时曲线会被拉向控制点P\_i，在减小时则把曲线远离该点。

  

片段的整个集合*m*-2条曲线（S\_{3},S\_{4},...S\_{m}）由*m*+1个控制点（P\_{0},P\_{1},...P\_{m},m\geq 3）定义，作为*t*上的一个B样条可以定义为

S(t)=\sum \_{{i=0}}^{m}{\mathbf {P}}\_{{i}}b\_{{i,}}(t)
其中*i*是控制点数，*t*是取节点值的全局参数。这个表达式把B样条表示为B样条基函数的线性组合，这也是这个名称的原因。

有两类B样条-均匀和非均匀。非均匀B样条相邻控制点间的距离不一定要相等。一个一般的形式是区间随着插入控制点逐步变小到0。

B樣條的程式指令
--------

### Matlab

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)

### Python

**事前安裝模組**

* 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样条曲面
-----

B样条曲线及曲面相关算法
------------

关于此处涉及的算法，在著作中有针对Bézier、B样条（B-spline）以及非均匀有理B样条（Nurbs）的相关算法的详细数学表达和程序实现方法。

### 求导

在几何处理中，对参数曲线及曲面的求导是最基本的运算之一，由于参数表达的特性，在给定点的切线及法线可通过求导直接得到。
先来考察曲线的情形：采用本页定义中的B样条曲线表达式
{\mathbf {S}}(t)=\sum \_{{i=0}}^{{m}}{\mathbf {P}}\_{{i}}b\_{{i,n}}(t){\mbox{ , }}t\in [0,1] 
对参数t进行求导：
{\frac {d{\mathbf {S}}}{dt}}=\sum \_{{i=0}}^{{m}}b'\_{{i,n}}(t){\mathbf {P}}\_{{i}}

### 节点插入与删除

### 曲线及曲面拟合

应用
--

参看
--

* 样条
* De Boor算法
* 非均匀有理B样条

參考文獻
----

* 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)（页面存档备份，存于）