B-スプライン曲線

B-スプライン曲線（Bスプラインきょくせん、英: B-spline curve）とは、与えられた複数の制御点とノットベクトルから定義される滑らかな曲線である。区分多項式により表現されているため、一部を変更しても曲線全体に影響は及ばない等の性質がある。ベジェ曲線とともに、コンピュータグラフィックスの世界で広く利用されている。なお、B-splineはBasis spline（Basis＝基底）の省略形である（en:B-Spline）。曲線は必ずしも制御点を通らない。 制御点を P i {\displaystyle \mathbf {P} _{i}} とすると、 n {\displaystyle n} 次のB-スプライン曲線は S ( t ) = ∑ i = 0 m − n − 2 P i b i , n ( t )   , t ∈ [ t n , t m − n − 1 ] {\displaystyle \mathbf {S} (t)=\sum _{i=0}^{m-n-2}\mathbf {P} _{i}b_{i,n}(t)\ {\text{,}}\qquad t\in [t_{n},t_{m-n-1}]} . と表される。制御点の個数は m − n − 1 {\displaystyle m-n-1} 個。ここで t j {\displaystyle t_{j}} はノット（knot）と呼ばれる m {\displaystyle m} 個の実数（ベクトル）である。 t 0 = 0 , t m − 1 = 1 {\displaystyle t_{0}=0,t_{m-1}=1} とすることが多い。 t 0 ≤ t 1 ≤ ⋯ ≤ t m − 1 {\displaystyle t_{0}\leq t_{1}\leq \cdots \leq t_{m-1}} また b i , n ( t ) {\displaystyle b_{i,n}(t)} はB-スプライン基底関数（B-spline basis function）と呼ばれ、de Boor Coxの漸化式 によって次のように定義される。 b j , 0 ( t ) := { 1 if t j ≤ t < t j + 1 0 otherwise , j = 0 , … , m − 2 {\displaystyle b_{j,0}(t):=\left\{{\begin{matrix}1&{\text{if}}\quad t_{j}\leq t<t_{j+1}\\0&{\text{otherwise}}\end{matrix}}\right.,\qquad j=0,\ldots ,m{-}2} b j , k ( t ) := t − t j t j + k − t j b j , k − 1 ( t ) + t j + k + 1 − t t j + k + 1 − t j + 1 b j + 1 , k − 1 ( t ) , j = 0 , … , m − k − 2. {\displaystyle b_{j,k}(t):={\frac {t-t_{j}}{t_{j+k}-t_{j}}}b_{j,k-1}(t)+{\frac {t_{j+k+1}-t}{t_{j+k+1}-t_{j+1}}}b_{j+1,k-1}(t),\qquad j=0,\ldots ,m{-}k{-}2.} u {\displaystyle u} 方向に n u {\displaystyle n_{u}} 次で v {\displaystyle v} 方向に n v {\displaystyle n_{v}} 次のB-スプライン曲面（B-spline surface）は以下のように表される。 S ( u , v ) = ∑ i u = 0 m u − n u − 2 ∑ i v = 0 m v − n v − 2 P i u , i v b i u , n u ( u ) b i v , n v ( v )   , u ∈ [ u n u , u m u − n u − 1 ] ,   v ∈ [ v n v , v m v − n v − 1 ] {\displaystyle \mathbf {S} (u,v)=\sum _{i_{u}=0}^{m_{u}-n_{u}-2}\sum _{i_{v}=0}^{m_{v}-n_{v}-2}\mathbf {P} _{i_{u},i_{v}}b_{i_{u},n_{u}}(u)b_{i_{v},n_{v}}(v)\ {\text{,}}\qquad u\in [u_{n_{u}},u_{m_{u}-n_{u}-1}],\ v\in [v_{n_{v}},v_{m_{v}-n_{v}-1}]} . ノットや基底関数は曲線と同じ。制御点の個数は ( m u − n u − 1 ) ( m v − n v − 1 ) {\displaystyle (m_{u}-n_{u}-1)(m_{v}-n_{v}-1)} 個。 n次B-スプライン曲線は、以下のように制限するとn次ベジェ曲線と同一の式になる。つまりベジェ曲線はB-スプライン曲線の特殊な場合である。 制御点の数は n + 1 {\displaystyle n+1} 個。よってノットの数は m = 2 ( n + 1 ) {\displaystyle m=2(n+1)} 個。 t が 0 から 1 まで変化するとし、ノットは t j = 0   for   j ≤ n {\displaystyle t_{j}=0\ {\mbox{for}}\ j\leq n} および t j = 1   for   j > n {\displaystyle t_{j}=1\ {\mbox{for}}\ j>n} 。 ノットベクトルの作り方には色々な方法がある。 一様ノットベクトル（uniform knot vector）とは以下のようにノットを定義する。均等間隔で埋めたもの。 t j = t 0 + t m − 1 − t 0 m − 1 j {\displaystyle t_{j}=t_{0}+{\frac {t_{m-1}-t_{0}}{m-1}}j} 開一様ノットベクトル（open uniform knot vector）や一様間隔ノットベクトル（uniformly-spaced knot vector）と呼ばれる下記の方法で作る方法。 最初の n + 1 {\displaystyle n+1} 個は 0 とする。 最後の n + 1 {\displaystyle n+1} 個は 1 とする。 残りの m − 2 ( n + 1 ) {\displaystyle m-2(n+1)} 個は 0 より大きく 1 より小さい値で均等間隔で埋める。 例えば、n = 2, m = 7 の場合は制御点は4個でノットベクトルは [ 0   0   0   0.5   1   1   1 ] {\displaystyle [0\ 0\ 0\ 0.5\ 1\ 1\ 1]} である。このノットベクトルの作り方では、曲線の端点は最初と最後の制御点になる。また、制御点の数が n + 1 {\displaystyle n+1} 個の場合はn次ベジェ曲線と同一になる。 基本的に曲線は制御点を通らないが、例えば t 0 = t 1 = t 2 = 0 {\displaystyle t_{0}=t_{1}=t_{2}=0} のように連続した複数のノットに対し、同一の値を与えることで、対応する制御点に曲線を通すことができる。 2次B-スプライン曲線の場合、以下のようになり、曲線の始点が0番目の制御点と一致する。 S ( 0 ) = P 0 {\displaystyle \mathbf {S} (0)=\mathbf {P} _{0}} . ノットベクトルの最初の n + 1 個と、最後の n + 1 個を同一にすることで、曲線の端点は最初と最後の制御点になり、固定（clamped）される。 一様なノットにおける2次B-スプライン曲線において、B-スプライン基底関数は次のようになる。 b j , 2 ( t ) = { 1 2 t 2 − t 2 + t + 1 2 1 2 ( 1 − t ) 2 {\displaystyle b_{j,2}(t)={\begin{cases}{\frac {1}{2}}t^{2}\\-t^{2}+t+{\frac {1}{2}}\\{\frac {1}{2}}(1-t)^{2}\end{cases}}} これを行列形式にすると、 S i ( t ) = [ t 2 t 1 ] 1 2 [ 1 − 2 1 − 2 2 0 1 1 0 ] [ p i − 1 p i p i + 1 ] {\displaystyle \mathbf {S} _{i}(t)={\begin{bmatrix}t^{2}&t&1\end{bmatrix}}{\frac {1}{2}}{\begin{bmatrix}1&-2&1\\-2&2&0\\1&1&0\end{bmatrix}}{\begin{bmatrix}\mathbf {p} _{i-1}\\\mathbf {p} _{i}\\\mathbf {p} _{i+1}\end{bmatrix}}} for t ∈ [ 0 , 1 ] , i = 1 , 2 … m − 2 {\displaystyle t\in [0,1],i=1,2\ldots m-2} となる。 有理B-スプラインは各制御点に重みを付けた物。詳細はNURBS（非一様有理B-スプライン）を参照。 スプライン曲線 ベジェ曲線 NURBS 切断冪関数