10:ベジエ曲線に平行なベジエ曲線

平行曲線を描くだけであれば、2:平行曲線を描く の方法で十分である。 しかし、 この方法で生成した式は複雑で、これまでに考えてきた方法で交点を算出することができない。 もし、ベジエ曲線に平行な曲線を、ベジエ曲線の形式で求めることができれば、これまでの方法を適用することができる。

始点・終点

ベジェ曲線の最初の制御点と最後の制御点は、曲線の端を表しているので、新しい曲線の両端は、もとの曲線の両端から法線方向にずらした場所にする。

第1制御点・第2制御点

始点・終点から、隣り合う制御点を結ぶ直線(P0P1とP3P2)の方向は、始点・終点での接線の方向と等しい。 元曲線の両端P0, P3に対応する平行曲線の両端p0, p3の接線も、元曲線のP0P1, P3P2と同じ方向になっていなければならないので、平行曲線のp1, p2は、p0, p3から引かれる直線上に存在することになる。 パラメータt=0.5 を代入した平行曲線の式の値を、元の曲線のt=0.5の位置からずらした場所Mであると仮定し、平行曲線の第1制御点・第2制御点の中点を仮に求める。

p1とp2の中点が求まることによって、p1からp2が一意に求められるようになる。

矛盾

p1とp2の中点が求まったので、以下のように角を設定し、Oが中点になるようなθ1, θ2を求めることができる。 atan2は数学関係のライブラリの多くに含まれている関数。 a=m2/m1

しかし、Mが中点になるように角度を設定しても、Mの接線と、対応する元曲線の接線が平行にならず、平行な曲線が得られなかった。平行曲線のt=0.5地点は、元の曲線のt=0.5地点であるとは限らないことがわかった。

数値計算

「元の曲線のどの地点から法線方向に太さ分ずらした位置が、平行曲線のt=0.5地点となるか。」を知りたい。 最初はt=0.5地点であると仮定し、0.5地点の線の向きがずれていたら、たとえば0.5+0.1の場所であると仮定して元曲線の0.6と平行曲線の0.5の方向を比較する。ずれが大きくなったら逆方向に少しずつ進むようにする。誤差が少なくなるまで繰り返す。

        //数値計算によって正確な平行ベジェ曲線の制御点を算出
        public Bezier ParallelBezier2(double w) {
            double t = 0.5;
            double delta = 0.01;
            Bezier result;
            double rad = 100;
            double rad_prev;

            string test = "";
            do
            {
                result = ParallelBezier(w, t);

                rad_prev = rad;

                rad = Math.Acos(Vec2D.inproduct(result.d_val(0.5), d_val(t)) / (result.d_val(0.5).length * d_val(t).length));

                if (rad_prev > Math.PI * 2)//初回
                {
                }
                else
                {
                    if (Math.Abs(rad) - Math.Abs(rad_prev) > 0)
                    {
                        delta *= -0.5;
                    }
                }
                t += delta;
                test += t + "," + rad + "n";
            } while ((rad > Math.PI / 18000) && (Math.Abs(rad-rad_prev)>0.000000001 ));

            return ParallelBezier(w, t);
        }

これでも、変な形の曲線では誤差が出てきます。そんな時には曲線を分割すれば良いと思います。とりあえずは。

広告

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中