幅をどうやって定義するか
左の幅、右の幅とは3次ベジェ曲線の接線ベクトルの方法に対しての左右です。
左と右を3次ベジェ曲線のパラメータを用いて定義します。
左の幅を、右の幅を とします。
左右別々に求めていきます。
幅関数のパラメータの求め方
左右どちらでもよいので、どちらかの関数を とします。
4点 より、パラメータ を求めます。3次ベジェ曲線の太さを決めるものなので、 とします。
すると以下が成り立ちます。式 を式 に代入します。とおきます。
この が正則であれば、 は求まるので、行列式を計算してみます。おっと、びっくりするぐらい式がキレイになりました。
式 が となるのは、 または または または または のときです。
が共に または のときは、 の2点からなる線分を求めればよいです。
のどちらかが または のときは、 と の3点からなる2次曲線を求めればよいです。
のときは の3点からなる2次曲線を求めればよいです。
では、3点の場合の2次曲線も求めておきましょう。3点 より、パラメータ を求めます。
とします。
すると以下が成り立ちます。式 を式 に代入します。式 の は存在します。
なぜなら以下のように、いかなる時も行列式が にならないためです。
まとめ
4点 からなる幅関数 は以下のようになります。
以下で使用する 関数は次の通りです。
(1) が共に または のときは、
を更新し、2点 から直線を求めそれを とします。
(2) のどちらか一方のみが または のときは、
を更新し、3点 から2次曲線を求めそれを とします。()
(3) であり、 のときは、
を更新し、3点 から2次曲線を求めそれを とします。
(3) であり、 のときは、
4点 から3次曲線を求めそれを とします。
大事なのは、その4点をどのように入力させるかですね、それにより使いやすさが決まると思います。
最後に
行列式の値が0に近くなると、計算が不安定なるので、例えばアプリケーションで とするなど、工夫するのもありだと思います。
また、今回は検討していませんが、一般逆行列を求めればこんな場合分け不要になるかと思います。(本件に一般逆行列をを適用した場合の記事は別途書く予定)
は幅を返す関数なので正の値を返す必要があります。本記事ではそれについて考慮していませんので、アプリに組み込む際、4点が決まったときに が0以下の値を取るときは警告でも出せば良いんじゃないでしょうか?
追記
中心となる曲線はCatmullスプラインで左右の幅は区分ごとに直線でよいと思う
(ex. 0-0.5: x=0.5t + 0.8, 0.5-0.8: x=-0.2t + 2.3, 0.8-1: 0.9)