| INDEX |

久しぶりのエントリーです。仕事が忙しくなると物欲がたくましくなる今日この頃です。年末はゲームもプラモもいろいろ発売でゆるゆるです。バーチャとシュトルヒが欲しい…。で、懲りずにベジェです。3次ベジェの切り分けです。

上の図は、3次ベジェを調べたことのある方なら見慣れた図かと思います。図のtpの座標をスクリプトで書くと、

/**
* Bezier Function
* @param	t
* @return	Point
*/
/*
_point0:Point 始点
_point1:Point 終点
_control0:Point 制御点
_control1:Point 制御点
*/
function f(t:Number):Point
{
  var tp:Number = 1.0 - t;
  return new Point( _point0.x*tp*tp*tp + 3*_control0.x*t*tp*tp + 3*_control1.x*t*t*tp + _point1.x*t*t*t,
                    _point0.y*tp*tp*tp + 3*_control0.y*t*tp*tp + 3*_control1.y*t*t*tp + _point1.y*t*t*t );
}

な感じのtに関する関数になります。
で、任意のt値、例えばポイントtpで3次ベジェを2つに分けようというものです。

2つに分けるには、2つの3次ベジェの新しい制御点を求めることになりますが、図を眺めているとすでに見えているのですね。2分割した後の曲線は、以下の図のようになります。勢いでやってみると、案外すんなりいくものです。

図でいうところの、■□、△▲が新しい制御点になります。
ベタにスクリプトで書くと、

/**
* Split Bezier at t.
* @param	t( 0 to 1 )
*/
function split(t:Number):Array
{
  var tp:Point   = f(t); //上に書いた関数
  var m:Point   = Point.interpolate( _control1, _control0, t);

  //制御点■□
  var ac0:Point = Point.interpolate( _control0, _point0, t);
  var ac1:Point = Point.interpolate( m, ac0, t);

  //制御点△▲
  var bc1:Point = Point.interpolate( _point1, _control1, t);
  var bc0:Point = Point.interpolate( bc1, m, t);

  return [ {p0:_point0.clone(),p1:tp,cp0:ac0,cp1:ac1},
           {p0:tp.clone(),p1:_point1.clone(),cp0:bc0,cp1:bc1}];
}

のような感じです。

青、オレンジの曲線が切り取った線で、中の黒い線がもともとの曲線です。

SVGの読み込みをしようと思って、その過程で3次ベジェを2次ベジェに変換したくて、その前処理に使ったりしてます。

“[as]3次ベジェ切り分け” への3件のフィードバック

  1. ちあき より:

    ベジェ曲線で検索したら、このページに来ました。CGに関する情報ばかりでとても勉強になりました(感謝)
    早速、「ベジェ曲線と直線の交点」のソースを参考にVBに書き直して実行してみたら確かに交点を出してくれました。大感激です。ありがとうございました。
    さて、ご質問があります。ベジェ曲線同士の交点を求める方法はやはり難しいでしょうか?もし何かお分かりでしたらご教授願えませんでしょうか。よろしくお願いします。

  2. nutsu より:

    ちあきさんこんにちは。
    コメントありがとうございます。
    ベジェ曲線同士の交点ですが、BezierClippingという方法が参考になると思います。
    http://b.hatena.ne.jp/entry/4946480
    交点に関して大雑把に言うと、交点部分の曲線を絞り込んで、最終的に、曲線と直線の交点問題にしてしまおう、という感じです。
    僕はまだ実装していないですが、この方法を参考にしてぼちぼちやろうかなぁと思ってたりしてます。

  3. ちあき より:

    NUTSU様 ご返事ありがとうございます(感謝、感激)
    西田先生のPage、以前にも拝見し「BezierClipping法による解法」の数式を見たことがあるのですが、お恥ずかしながら私には異次元の記号の羅列にしか見えず(汗)断念していました。
    ぜひNUTSU様のページにてコード化した内容をエントリーしてくださることを心待ちにいたしております。よろしくお願いします。

| INDEX |