7:ベジェ曲線の分割

ベジエ曲線は、好きなところで2つのベジエ曲線に分割できる。

曲線を t : 1-t に分割したければ、 制御点 1-2,  2-3,  3-4 を  t : 1-t に分割し、 それを結んで出来た2本の直線を、再び t : 1-t に分割し、 残りの1本を t : 1-t に分割する。

分割した点は、新たな曲線の制御点になっている。

        //曲線を切断する
        static public Vec2D[][] BezierCut(Vec2D[] points, double t)
        {
            Vec2D[][] result = new Vec2D[2][];
            result[0] = new Vec2D[points.Length];
            result[1] = new Vec2D[points.Length];

            //0か1で切断しようとしている場合
            if (t == 0 || t == 1) {
                result[(int)t][0] = result[(int)t][1] =
                result[(int)t][2] = result[(int)t][3] =
                    points[(int)t * (points.Length - 1)];

                result[((int)t + 1) % 2] = points;
                return result;
            }

            //stでくぎられる点を見つける
            //分割前の P0, Pn が分割後の L0, Rn になる
            result[0][0] = points[0];
            result[1][points.Length - 1] = points[points.Length - 1];

            Vec2D[] prev = points;
            for (int i = 1; i < points.Length; i++) {
                Vec2D[] tmp = new Vec2D[points.Length - i];
                for (int j = 0; j < points.Length - i; j++) {
                    //tmp[j] - tmp[j+1] の間を st で区切る
                    tmp[j].x = prev[j].x + (prev[j + 1].x - prev[j].x) * t;
                    tmp[j].y = prev[j].y + (prev[j + 1].y - prev[j].y) * t;
                }
                result[0][i].x = tmp[0].x;
                result[0][i].y = tmp[0].y;
                result[1][points.Length - i - 1].x = tmp[tmp.Length - 1].x;
                result[1][points.Length - i - 1].y = tmp[tmp.Length - 1].y;

                prev = tmp; //算出したものを保持
            }

            return result;
        }
広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中