ねこでじ(Nekodigi)

Nekodigi’s diary

学習中の気づきをまとめています。応援よろしくお願いします

【Processing】N次Bスプライン曲線を表示する。

成果物

www.youtube.com
端の処理で結構時間がかかってしまいましたが、無事に完成しました。もう少し改良できる点もありますが、ひとまず実用に耐えるレベルのものができました。次数の変更だけでなく、先端を繋ぐか開くかの変更もできます。

コード

Nth_order_B_Splineという名前で追加しています。
github.com

仕組み

線上のtの位置での座標を求める式はこのようになっています。
{\displaystyle \mathbf{S} (t)=\sum ^{m-n-2}_{i=0}\mathbf{P}_{i} b_{i,n} (t)\ \text{,} \ \ \ \ t\in [t_{n} ,t_{m-n-1} ]}
b()はB-Splineの基底関数(各頂点の重み)で、このように、再帰的に求めることができます。はみ出した…
 \begin{array}{l}
{\displaystyle b_{j,0} (t):=\left\{\begin{matrix}
1 & \text{if} \ \ t_{j} \leq t< t_{j+1}\\
0 & \text{otherwise}
\end{matrix}\right. ,\ \ \ \ j=0,\dotsc ,m-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),\ \ \ \ j=0,\dotsc ,m-k-2.}
\end{array}
今回tは、この式のように均一に分布させています。この分布を変えることで端の処理ができるはずなのですが、Division by zeroエラーが出たので別の方法を使っています。
{\displaystyle t_{j}=t_{0}+{\frac {t_{m-1}-t_{0}}{m-1}}j}
先端の処理は、このサイトを参考にしました。Bスプラインの特性も学ぶことができて本当に参考になりました。
techblog.kayac.com

NURBSとの関係

基底関数に重み(任意)を掛け合わせ、全ての重みの和で割るとNURBSになります。詳しくはこちらをご覧ください。
NURBSとは? - Qiita