きままにものづくり

日々の気付いたことなんかを書いてます。

なめらかな曲線を描く ~その2~

こんにちは、even_ekoです。

今回の記事は、前回の記事の続きです。実装してみた曲線は、以下の4つです。

  • ベジェ曲線
  • Ferguson/Coon曲線
  • Catmull/Rom曲線
  • Bスプライン曲線

この中で、なめらかな曲線が描けたのは、Bスプライン曲線だけでした。他の曲線でも特殊な処理をすれば、なめらかな曲線が描けるのかもしれません。

ベジェ曲線

ベジェ曲線は、illustratorやPainterなどの様々なペイントツールに実装されています。CADなどにも用いられ、比較的有名なパラメトリック曲線です。
実装したベジェ曲線の軌跡は、こんな感じになりました。
f:id:even_eko:20120913105513p:plain
ところどころに不連続な箇所があります。今回実装したのは、3次のベジェ曲線です。3次のベジェ曲線は、4つの制御点を使ってひとつの曲線を描きます。ベジェ曲線のアルゴリズムを簡単に説明します。 詳しいアルゴリズムは、参考サイトに載ってるのでそちらを参照して下さい。
ベジェ曲線を言葉だけで説明するのは、ほぼ不可能だと思うので画像を使用します。
f:id:even_eko:20120913102150p:plain
Start,cont1,cont2,endの4点は制御点になります。制御点は、ベジェ曲線の形を決める大事な点です。今回実装したアルゴリズムでは、制御点はイベントから取得する座標と同じにしています。
この制御点どうしを直線でつなぎます。この処理は、視覚的に分かりやすくするための処理です。なので、実際にこの処理が行われてるわけではありません。
f:id:even_eko:20120913102448p:plain
次にこの直線を以下の式の比で分割します。
f:id:even_eko:20120913102540p:plain
tは媒介変数です。ただ、今回は数式は用いずに説明するので0から1で変化する数字だと割り切って大丈夫です。
分割した点にそれぞれ、pA,pB,pCと名前をつけます。
実際に分割した画像になります。
f:id:even_eko:20120913102751p:plain
StartとpAの間の長さをs1とし、pAとcont1の間の長さをs2としています。同様に他の直線にも名称をつけます。
簡単化のためtを0.5とすると、比は以下のようになります。
f:id:even_eko:20120913102640p:plain
つまり、この場合ですとそれぞれの制御点どうしの中点がpA,pB,pCとなります。
次に、pAとpB、pBとpCを直線でつなぎます。
そして、先ほど同様に直線を分割します。分割した点をそれぞれpD,pEとします。
f:id:even_eko:20120913102930p:plain
ここでも、tを0.5とすると、pDとpEはそれぞれの直線の中点になります。
次にくる処理は予想できるでしょうか。

pDとpEを直線でつなぎ、比の式に従ってその直線を分割します。分割した点をpFとします。
f:id:even_eko:20120913103005p:plain
分割した結果得られた点pFがベジェ曲線のひとつの点となります。
以上の処理をtを0から1の間で変化させることで、ベジェ曲線が描けます。

ベジェ曲線は、最初の制御点と最後の制御点を通過します。そのため、4つの制御点をためて曲線を描くという処理を繰り返します。冒頭に挙げた他の曲線では、最初に4つの制御点を貯め、その後はひとつの制御点を取得するごとに曲線を描画します。ベジェ曲線でこういった処理ができない理由は、制御点を再利用できないからです。ベジェ曲線は、最初と最後の点を通過するように描かれるため、制御点を再利用すると、線が重なってしまいます。ただ重なるだけなら問題は少ないのですが、制御点が変更されているため少しずれて重なります。
以下の画像がずれて重なってしまったベジェ曲線になります。
f:id:even_eko:20120913105529p:plain
ベジェ曲線では、曲線どうしをつなげる点(節点)での連続性は保証されていません。そのため、ベジェ曲線ではなめらかな曲線は描けませんでした。

参考サイト
Rui Ueyamaさんのブログ記事
Hiroyuki Satoさんの記事
Nichibun.netの記事