こんにちは、even_ekoです。
今回の記事は、前回の記事の続きです。実装してみた曲線は、以下の4つです。
- ベジェ曲線
- Ferguson/Coon曲線
- Catmull/Rom曲線
- Bスプライン曲線
この中で、なめらかな曲線が描けたのは、Bスプライン曲線だけでした。他の曲線でも特殊な処理をすれば、なめらかな曲線が描けるのかもしれません。
ベジェ曲線
ベジェ曲線は、illustratorやPainterなどの様々なペイントツールに実装されています。CADなどにも用いられ、比較的有名なパラメトリック曲線です。
実装したベジェ曲線の軌跡は、こんな感じになりました。
ところどころに不連続な箇所があります。今回実装したのは、3次のベジェ曲線です。3次のベジェ曲線は、4つの制御点を使ってひとつの曲線を描きます。ベジェ曲線のアルゴリズムを簡単に説明します。 詳しいアルゴリズムは、参考サイトに載ってるのでそちらを参照して下さい。
ベジェ曲線を言葉だけで説明するのは、ほぼ不可能だと思うので画像を使用します。
Start,cont1,cont2,endの4点は制御点になります。制御点は、ベジェ曲線の形を決める大事な点です。今回実装したアルゴリズムでは、制御点はイベントから取得する座標と同じにしています。
この制御点どうしを直線でつなぎます。この処理は、視覚的に分かりやすくするための処理です。なので、実際にこの処理が行われてるわけではありません。
次にこの直線を以下の式の比で分割します。
tは媒介変数です。ただ、今回は数式は用いずに説明するので0から1で変化する数字だと割り切って大丈夫です。
分割した点にそれぞれ、pA,pB,pCと名前をつけます。
実際に分割した画像になります。
StartとpAの間の長さをs1とし、pAとcont1の間の長さをs2としています。同様に他の直線にも名称をつけます。
簡単化のためtを0.5とすると、比は以下のようになります。
つまり、この場合ですとそれぞれの制御点どうしの中点がpA,pB,pCとなります。
次に、pAとpB、pBとpCを直線でつなぎます。
そして、先ほど同様に直線を分割します。分割した点をそれぞれpD,pEとします。
ここでも、tを0.5とすると、pDとpEはそれぞれの直線の中点になります。
次にくる処理は予想できるでしょうか。
pDとpEを直線でつなぎ、比の式に従ってその直線を分割します。分割した点をpFとします。
分割した結果得られた点pFがベジェ曲線のひとつの点となります。
以上の処理をtを0から1の間で変化させることで、ベジェ曲線が描けます。
ベジェ曲線は、最初の制御点と最後の制御点を通過します。そのため、4つの制御点をためて曲線を描くという処理を繰り返します。冒頭に挙げた他の曲線では、最初に4つの制御点を貯め、その後はひとつの制御点を取得するごとに曲線を描画します。ベジェ曲線でこういった処理ができない理由は、制御点を再利用できないからです。ベジェ曲線は、最初と最後の点を通過するように描かれるため、制御点を再利用すると、線が重なってしまいます。ただ重なるだけなら問題は少ないのですが、制御点が変更されているため少しずれて重なります。
以下の画像がずれて重なってしまったベジェ曲線になります。
ベジェ曲線では、曲線どうしをつなげる点(節点)での連続性は保証されていません。そのため、ベジェ曲線ではなめらかな曲線は描けませんでした。