Skip to content

*)TCBスプライン基礎

最終更新日時: 2025年08月25日 12:57

  • nothing
  • 定式化
  • 具体的な線の計算
  • 他のAIに書かせて線の違いを確認

本レポートでは、数値入力を入力データとして与えることを前提とすると、 TCBスプラインを用いて曲線を定義し実装する方法が適していると想定し、 TCBスプラインの理解を進める。


今後の実装方針としてはTCBスプラインのデータを入力データとしてプログラムに与え、 各区間をエルミートスプライン曲線として内部データとして一旦変換し、 さらに各区間をOpenGLをはじめ各種グラフィックプラットフォームで最適化されている ベジェ曲線として変換しての描画をすることを想定している。


  • 最初にTCBスプラインの基礎となるエルミートスプライン補間の説明を行う
  • エルミート・スプライン補間が接線ベクトルを用いて定義することを示す
  • 接線ベクトルを拡張するTCBの考え方を適用して再定義する
  • 以上からTCBスプラインの定式化を行う
  • 具体的なTCBパラメータをあてはめた例を示す
  • 最後に3次のベジェ曲線とエルミート(Hermite)スプライン曲線は同値であることからその変換を示す

TCBスプラインの最も興味深い点は、一次微分が連続なエルミート・スプライン補間をベースに拡張しつつ、一次微分が不連続な曲線もカバーできるように拡張し、より多彩な曲線を扱うことができることである。


TCBスプラインは、発明者の名前を取って、Kochanek-Bartelsスプラインと呼ばれることもある。

エルミート補間は位置と接線(導関数)を指定して曲線を生成する手法でありTCBスプラインの基礎となる。

  • エルミート補間では、2つの端点とその接線ベクトルから3次多項式曲線を構築する
  • 高々3次の多項式である理由は以下の理由による
    • 合計四つの条件式が成立すること(2点間の位置条件が2つの制約、2点での接線条件から2つの制約)
    • 4つの係数から構成されるのは高々3次多項式であること

3次エルミート多項式の標準形式

Section titled “3次エルミート多項式の標準形式”

u[0,1]u \in [0,1]で定義される正規化された区間での高々3次の多項式P(u)が 曲線を補間するものであると仮定する。

P(u)=au3+bu2+cu+dP(u) = au^3 + bu^2 + cu + d

合計四つの境界条件が与えられたものとして、 係数aa, bb, cc, ddの値を解く。

実際に値を代入すると下記のとおりである

{P(0)=PiP(1)=Pi+1P(0)=Di,i+1P(1)=Di+1,i+\left\{ \begin{align*} P(0) &= P_i \\ P(1) &= P_{i+1} \\ P'(0) &= D_{i,i+1}^- \\ P'(1) &= D_{i+1,i}^+ \end{align*} \right.

エルミート基底関数表現の根拠

Section titled “エルミート基底関数表現の根拠”

エルミート基底関数表現は、補間問題を解くための自然な形式として導出される:

一般的な多項式表現から出発し、

P(u)=au3+bu2+cu+dP(u) = au^3 + bu^2 + cu + d

境界条件を適用すると、

{P(0)=d=PiP(1)=a+b+c+d=Pi+1P(0)=c=Di,i+1P(1)=3a+2b+c=Di+1,i+\left\{ \begin{align*} &P(0) = d = P_i\\ &P(1) = a + b + c + d = P_{i+1}\\ &P'(0) = c = D_{i,i+1}^-\\ &P'(1) = 3a + 2b + c = D_{i+1,i}^+ \end{align*} \right.

さらにa,b,c,da,b,c,dについて解くと、

{a=Di+1,i++Di,i+1+2(PiPi+1)b=3(Pi+1Pi)2Di+1,i+Di,i+1c=Di,i+1d=Pi\left\{ \begin{align*} a &=D_{i+1,i}^+ + D_{i,i+1}^- + 2( P_{i} -P_{i+1})\\ b &=3(P_{i+1} - P_{i}) -2D_{i+1,i}^+ - D_{i,i+1}^-\\ c &= D_{i,i+1}^-\\ d &=P_{i} \end{align*} \right.

最初の式に代入し、Pi,Pi+1,Di+1,i++Di,i+1P_{i},P_{i+1},D_{i+1,i}^+ + D_{i,i+1}^- についてまとめると、

P(u)=(2u33u2+1)Pi+(u32u2+u)Di,i+1+(2u3+3u2)Pi+1+(u3u2)Di,i+1+=h00Pi+h10Di,i+1+h01Pi+1+h11Di,i+1+\begin{align*} P(u) = &(2u^3 - 3u^2 + 1) \cdot P_{i} + (u^3 - 2u^2 + u) \cdot D_{i,i+1}^-\\ &+ (-2u^3 + 3u^2 ) \cdot P_{i+1} + (u^3 - u^2) \cdot D_{i,i+1}^+\\ = &h_{00} \cdot P_{i} + h_{10} \cdot D_{i,i+1}^- + h_{01} \cdot P_{i+1} + h_{11} \cdot D_{i,i+1}^+\\ \end{align*}

ただし、

{h00(u)=2u33u2+1h10(u)=u32u2+uh01(u)=2u3+3u2h11(u)=u3u2\left\{ \begin{align} h_{00}(u) &= 2u^3 - 3u^2 + 1 \\ h_{10}(u) &= u^3 - 2u^2 + u \\ h_{01}(u) &= -2u^3 + 3u^2 \\ h_{11}(u) &= u^3 - u^2 \end{align} \right.

となる。


検算をすると確かに、


  • u=0u = 0のとき:P(0)=PiP(0) = P_i
  • u=1u = 1のとき:P(1)=Pi+1P(1) = P_{i+1}
  • u=0u = 0での接線:P(0)=Di,i+1P'(0) = D_{i,i+1}^-(出力接線)
  • u=1u = 1での接線:P(1)=Di+1,i+P'(1) = D_{i+1,i}^+(入力接線)

となる。

以上より、各接線の値を求めることによりエルミートスプライン曲線による補間が成立することが分かった

TCBスプラインにおける曲線方程式

Section titled “TCBスプラインにおける曲線方程式”

エルミート補間をするときに接線ベクトルを用いた式を前章で導いた。


ここでは、接線ベクトルの一般的な定義から順に拡張してゆき、 TCBスプライン曲線における接線ベクトルの考え方を導き TCBスプラインの定式化を行う。

一般的に2点間の傾きは隣接する制御点の差分に係数 α\alpha を乗じて定義できる。 α\alphaは制御点間の距離で正規化するとより傾きとして理解しやすい形式になるかもしれない。

Di=α(Pi+1Pi1)(α=1Pi+1Pi1)D_i = \alpha(P_{i+1} - P_{i-1})\\ \left( \alpha = \frac{1}{||P_{i+1} - P_{i-1}||} \right)

ここでより柔軟な制御のため、接線計算にパラメータを導入するように拡張する

Di=α[(1β)(Pi+1Pi)+β(PiPi1)]D_i = \alpha[(1-\beta)(P_{i+1} - P_i) + \beta(P_i - P_{i-1})]

これにより、

  • α\alphaは接線ベクトルの大きさを制御する係数とみなせる
  • β\betaは前後の制御点の影響バランスを制御するようにみなせる

β=0.5\beta = 0.5 の場合、前後の影響が均等で、中心差分法に相当すると考えられる。


次に、この2点間の傾きではなく、 3点Pi1,Pi,Pi+1P_{i-1},P_{i},P_{i+1}を考えたときの真ん中の点PiP_{i}の傾きを考える。

PiP_{i}に置ける傾きは、Pi1P_{i-1}側の傾きと、Pi+1P_{i+1}側の傾きを別に定義し 異なることを許した場合、PiP_{i}の一次微分が不連続であることを許容するように拡張する。


この二つの傾きを先ほど導いた傾きの一般系をさらに重みづけのwiw_{i}を用いて下記のように書き下す。

{Di,i+1=w1(PiPi1)+w2(Pi+1Pi)Di,i+1+=w3(PiPi1)+w4(Pi+1Pi)\left\{ \begin{align*} D_{i,i+1}^- &= w_1(P_i - P_{i-1}) + w_2(P_{i+1} - P_i) \\ D_{i,i+1}^+ &= w_3(P_i - P_{i-1}) + w_4(P_{i+1} - P_i) \end{align*} \right.

この重みをt,c,bの3つのパラメータを用いて再定義する。

{w1=(1t)(1+b)(1+c)2w2=(1t)(1b)(1c)2w3=(1t)(1+b)(1c)2w4=(1t)(1b)(1+c)2\left\{ \begin{align*} w_1 &= \frac{(1-t)(1+b)(1+c)}{2} \\ w_2 &= \frac{(1-t)(1-b)(1-c)}{2} \\ w_3 &= \frac{(1-t)(1+b)(1-c)}{2} \\ w_4 &= \frac{(1-t)(1-b)(1+c)}{2} \end{align*} \right.

下記の式をtcbスプラインの点PiP_{i}におけるPi1P_{i-1}側とPi+1P_{i+1}側の傾きとして定義できる

{Di,i+1=(1t)(1+b)(1+c)2(PiPi1)+(1t)(1b)(1c)2(Pi+1Pi)Di,i+1+=(1t)(1+b)(1c)2(PiPi1)+(1t)(1b)(1+c)2(Pi+1Pi)\left\{ \begin{align*} D_{i,i+1}^- &= \frac{(1-t)(1+b)(1+c)}{2}(P_i - P_{i-1}) + \frac{(1-t)(1-b)(1-c)}{2}(P_{i+1} - P_i) \\ D_{i,i+1}^+ &= \frac{(1-t)(1+b)(1-c)}{2}(P_i - P_{i-1}) + \frac{(1-t)(1-b)(1+c)}{2}(P_{i+1} - P_i) \end{align*} \right.

ただし、1t1,1c1,1b1-1 \leq t \leq 1, -1 \leq c \leq 1,-1 \leq b \leq 1


この3つのパラメータにより、直観的な曲線の変形が可能になる

  • c はcontinuityであり、c=0c=0の時に、PiP_{i}における左右の一次微分値が等しく連続である。c=1,c=1c=-1, c=1の時に左右の微分値が非対称に近づいてゆく
  • t はtensionであり、PiP_{i}での直線性を表しており、t=0t=0を標準値として、t=1t=1の時に直線になり、t=1t=-1の時により曲線的になる
  • b はbiasであり、Pi1,Pi+1P_{i-1},P_{i+1}のどちらの影響を受けた傾きを算出するかであり、b=0b=0の時には均等な影響を受ける。
  • ベジェ曲線は制御点の加重和として表現される曲線
  • 特に3次ベジェ曲線は4つの制御点 B0,B1,B2,B3B_0, B_1, B_2, B_3 を用いて定義される
  • 3次のベジェ曲線はエルミートスプラインと同値である
    • 同じ曲線を異なる方法でパラメータ化しているだけで、どちらも3次多項式で表される同じ曲線族を表現しています。
  • 3次ベジェ曲線はその多項式特性を利用して描画アルゴリズムを高速化できるため、OpenGL等で曲線描画として採用されている
  • また制御点による形状制御が直感的であるためUIとして優れた点もある。
  • エルミート曲線は端点と接線による制御が直感的である
B(u)=(1u)3B0+3u(1u)2B1+3u2(1u)B2+u3B3\begin{align*} B(u) &= (1-u)^3B_0 + 3u(1-u)^2B_1 + 3u^2(1-u)B_2 + u^3B_3 \end{align*}

エルミート形式からベジェ形式への変換過程

Section titled “エルミート形式からベジェ形式への変換過程”

エルミート形式からベジェ形式への変換を詳細に導出する。


エルミート形式は下記の通り

P(u)=h00(u)Pi+h10(u)Di,i+1+h01(u)Pi+1+h11(u)Di+1,i+=(2u33u2+1)Pi+(u32u2+u)Di,i+1+(2u3+3u2)Pi+1+(u3u2)Di+1,i+\begin{align*} P(u) &= h_{00}(u)P_i + h_{10}(u)D_{i,i+1}^- + h_{01}(u)P_{i+1} + h_{11}(u)D_{i+1,i}^+ \\ &= (2u^3 - 3u^2 + 1)P_i + (u^3 - 2u^2 + u)D_{i,i+1}^- + (-2u^3 + 3u^2)P_{i+1} + (u^3 - u^2)D_{i+1,i}^+ \end{align*}

一方、ベジェ形式は下記の通り

B(u)=(1u)3B0+3u(1u)2B1+3u2(1u)B2+u3B3\begin{align*} B(u) &= (1-u)^3B_0 + 3u(1-u)^2B_1 + 3u^2(1-u)B_2 + u^3B_3 \end{align*}

両者が等価になるように係数を比較することを目的に端点の値を求めるとそれぞれ、

{P(0)=PiP(1)=Pi+1{B(0)=B0B(1)=B3\left\{ \begin{align*} P(0) &= P_i\\ P(1) &= P_{i+1}\\ \end{align*} \right. \left\{ \begin{align*} B(0) &= B_0\\ B(1) &= B_3 \end{align*} \right.

これより、

{B0=PiB3=Pi+1 \left\{ \begin{equation} \begin{align*} B_0 &= P_i &\\ B_3 &= P_{i+1}& \end{align*} \end{equation} \right.

同様に端点での一次微分の値を求めると、

{P(u)=6(u2u)P0+(3u24u+1)Di,i+1+6(u2+u)Pi+1+(3u22u)Di+1,i+B(u)=3(1u)2(B1B0)+6u(1u)(B2B1)+3u2(B3B2)\left\{ \begin{align*} P'(u) &= 6( u^{2}-u)P_{0}+(3u^{2}-4u+1)D_{i,i+1}^{-}+6(-u^{2}+u)P_{i+1}+(3u^{2}-2u)D_{i+1,i}^{+}\\ B'(u) &= 3(1-u)^2(B_1-B_0) + 6u(1-u)(B_2-B_1) + 3u^2(B_3-B_2) \end{align*} \right. {P(0)=Di,i+1P(1)=Di+1,i+{B(0)=3(B1B0)B(1)=3(B3B2)\left\{ \begin{align*} P'(0) & = D_{i,i+1}^-\\ P'(1) & = D_{i+1,i}^+ \end{align*} \right. \left\{ \begin{align*} B'(0) = 3(B_1-B_0)\\ B'(1) = 3(B_3-B_2) \end{align*} \right.

係数を比較し、先ほどの結果を利用すると、

{Di,i+1=3(B1B0)=3(B1Pi)Di+1,i+=3(B3B2)=3(Pi+1B2) \left\{ \begin{equation} \begin{align*} D_{i,i+1}^- &= 3(B_1-B_0) &\\ &= 3(B_1-P_i) &\\ D_{i+1,i}^+ &= 3(B_3-B_2) &\\ &= 3(P_{i+1}-B_2) \end{align*} \end{equation} \right.

これをB1,B2B_1,B_2について解くと、

{B1=Pi+13Di,i+1B2=Pi+113Di+1,i+ \left\{ \begin{equation} \begin{align*} B_1 &= P_i + \frac{1}{3}D_{i,i+1}^- &\\ B_2 &= P_{i+1} - \frac{1}{3}D_{i+1,i}^+ & \end{align*} \end{equation} \right.

よって、ベジェ形式は、エルミート形式の点や接線によって下記のように書き直すことができ、

P(u)=(1u)3Pi+3u(1u)2(Pi+13Di,i+1)+3u2(1u)(Pi+113Di+1,i+)+u3Pi+1\begin{align*} P(u) &= (1-u)^3P_i + 3u(1-u)^2(P_i + \frac{1}{3}D_{i,i+1}^-) + 3u^2(1-u)(P_{i+1} - \frac{1}{3}D_{i+1,i}^+) + u^3P_{i+1} \end{align*}

この式の中間制御点は、元の点と接線ベクトルから計算されることが分かる。

{Bi1=Pi+13Di,i+1Bi+11=Pi+113Di+1,i+ \left\{ \begin{equation} \begin{align*} B_i^1 &= P_i + \frac{1}{3}D_{i,i+1}^- & \\ B_{i+1}^{-1} &= P_{i+1} - \frac{1}{3}D_{i+1,i}^+ \end{align*} \end{equation} \right.

TCB接線ベクトルDi,i+1D_{i,i+1}^-Di+1,i+D_{i+1,i}^+を用いて、PiP_iPi+1P_{i+1}の間のセグメントの曲線方程式は:

Pi,i+1(u)=(1u)3Pi+3u(1u)2(Pi+13Di,i+1)+3u2(1u)(Pi+113Di+1,i+)+u3Pi+1P_{i,i+1}(u) = (1-u)^3P_i + 3u(1-u)^2(P_i + \frac{1}{3}D_{i,i+1}^-) + 3u^2(1-u)(P_{i+1} - \frac{1}{3}D_{i+1,i}^+) + u^3P_{i+1}

これがTCBスプラインレポートで使用されている最終的な曲線方程式である。

エルミート形式とベジェ形式の関係

Section titled “エルミート形式とベジェ形式の関係”

ベジェ曲線は以下の重要な特性を持つ:

  • 端点補間:曲線は最初と最後の制御点を通過する
  • 凸包性:曲線は制御点の凸包内に収まる
  • 変換不変性:アフィン変換を制御点に適用すると、曲線全体に同じ変換が適用される
  • 制御点の幾何学的影響:
    • 端点 B0B_0, B3B_3 は曲線が通過する点
    • 制御点 B1B_1B0B_0 から出る接線方向を決定
    • 制御点 B2B_2B3B_3 に入る接線方向を決定

エルミート形式とベジェ形式の比較

Section titled “エルミート形式とベジェ形式の比較”

エルミート補間とベジェ表現は数学的に等価であり、変換が可能:

  • エルミート形式の特徴

    • 2つの端点と2つの接線ベクトルで定義
    • 曲線の形状が直感的に理解しやすい
    • アニメーションや物理シミュレーションでの速度・加速度の指定に適している
  • ベジェ形式の特徴

    • 4つの制御点で定義
    • コンピュータグラフィックスでの標準的な表現
    • 分割と結合操作が容易
    • 多くのグラフィックスライブラリやフォーマットでサポートされている

エルミート形式からベジェ形式への変換は、前節で導出した通り:

B0Bezier=PiHermiteB1Bezier=PiHermite+13DiHermiteB2Bezier=Pi+1Hermite13Di+1HermiteB3Bezier=Pi+1Hermite\begin{align*} B_0^{Bezier} &= P_i^{Hermite} \\ B_1^{Bezier} &= P_i^{Hermite} + \frac{1}{3}D_i^{Hermite} \\ B_2^{Bezier} &= P_{i+1}^{Hermite} - \frac{1}{3}D_{i+1}^{Hermite} \\ B_3^{Bezier} &= P_{i+1}^{Hermite} \end{align*}

重要なのは、13\frac{1}{3} の係数が微分条件から直接導出されることである。これはベジェ曲線の特性に基づいており、曲線の端点での接線が端点と隣接制御点を結ぶベクトルに平行で、その大きさが3倍になっていることを表している。

  • Catmull-RomスプラインはTCBスプラインの特殊ケース(t=c=b=0)
  • Uniformパラメータ化は等間隔のパラメータ値を使用
  • Centripetalパラメータ化は弧長の平方根に比例したパラメータ値を使用
  • 補足事項の詳細な理解
  • 曲線の拡大縮小については個々のスプライン区間を再度生成しベジェ曲線に変換する必要があり詳細な検討が必要
  • OpenGL APIへの渡し方としては、各区間を3次ベジェ曲線として、例えば GL_PATCHES と tessellation shader を使用するか、 GL_LINES_ADJACENCY などで制御点を直接渡すかなどの検討が必要
  • 曲線の移動のためにはGroupクラスをTHREE.GroupまたはTHREE.Object3Dを親オブジェクトとして使用するための検討が必要
  • エルミート補間:位置と導関数を境界条件として使用する補間法
  • 基底関数:曲線を表現するための標準的な多項式関数のセット
  • ベジェ曲線:制御点の加重和として表現される滑らかな曲線で、バーンスタイン多項式を重み関数として使用
  • バーンスタイン多項式:ベジェ曲線の基本となる多項式で、二項係数と累乗の積として表現される
  • 凸包:集合に含まれる点を全て含む最小の凸集合
  • パラメータ空間:曲線上の点を特定するためのパラメータの範囲[0,1]
  • 接線ベクトル:曲線の各点における接線の方向と大きさを示すベクトル
  • アフィン変換:平行移動、回転、拡大縮小、せん断などの線形変換と平行移動の組み合わせ
  • 立方エルミートスプライン: 3次多項式と接線ベクトルを使用した補間手法
  • Kochanek-Bartelsスプライン: テンション、バイアス、連続性のパラメータを導入した拡張カトマル-ロムスプライン
  • カトマル-ロムスプライン: 制御点を通過する補間スプライン