2:平行曲線を描く

滑らかに線は引けたが、太さのある線を引きたい時は両側の縁も知りたい。

平行曲線はどのように引くのだろうか。

単にベジエ曲線をずらして配置しただけでは平行な曲線を得ることは出来ない。 曲線の接線に対して直角に(法線)、一定距離の地点を通る線が必要である。

 

1. 接線を求める

ベジエ曲線の式を微分することで接線の式になる。

[ベジエ曲線の式]

12

Bi, (n i) を定数とみなして、微分を考える。

Bezier変形

このように微分できた。

Bezier微分

これによって、ある地点での接線を知ることができる。

ちなみに3次ベジェ曲線 B(t) の微分はこうなる。

public static SizeF tangental_func(PointF[] pt, float t) {
    PointF total = new PointF(0.0f, 0.0f);
    int i;
    int n = pt.Length - 1;
    for (i = 0; i < pt.Length; i++){
    float d1 = (i == 0) ? 0.0f : (float)i * powFI(t, i - 1);
    float d2 = (n - i == 0) ? 0.0f : (float)(n - i) * powFI(1.0f - t, n - i - 1) * (-1);
    total.X += pt[i].X * mCn(n, i) * (d1 * powFI(1.0f - t, n - i) + powFI(t, i) * d2);
    total.Y += (pt[i].Y * mCn(n, i) * (d1 * powFI(1.0f - t, n - i) + powFI(t, i) * d2));
    }
    return new SizeF(total.X, total.Y);
}

* powFI は float 型をキャストせずに べき乗できるようにした単純な関数。

* d1 と d2 がそれぞれ t^i と (1-t)^(n-i) を微分したものをいれる変数。

2. 長さを1にする

1で求められる接線は、場所により長さがばらばらである。

そこで、x, y にある数をかけて長さを1にする。

 となるようなlをかけておけばよい。

3. 法線にする

接線のベクトルが (x, y) なら、 その直角は ( y, –x ) か、( -y, x ) となる。

http://en.wikipedia.org/wiki/Parallel_curve wikipedia に英語の記事だけあった。

広告

2:平行曲線を描く」への1件のフィードバック

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中