科学・技術
曲率ベジェ曲線
要約
この記事は、CADやコンピュータグラフィックスで広く使われているベジェ曲線について、その歴史、単純さ、そして欠点を掘り下げています。従来の制御点や接線ではなく、曲率に焦点を当てることでベジェ曲線を改善する新しいアプローチを提案しています。特に、「曲率ハンドル」という、より直感的で安定した編集方法を紹介し、既存のベジェ曲線技術を無効にすることなく、その使いやすさと精度を向上させる可能性を示唆しています。
全文翻訳
曲率ベジェ曲線
時代を超えたレシピの改善
ベジェ曲線は、CADやコンピュータグラフィックスの定番です。Bicペンと同じように、そのデザインは数十年前のもので、どこにでもあります。多くのイラストレーションやアニメーションツールで、デフォルトまたは唯一の選択肢として見かけることが多いでしょう。
1959年にポール・ド・カステリョーによって考案され、1960年代にルノーのピエール・ベジェによって洗練されたベジェ曲線の永続的な魅力は、その単純さにあります。より洗練された曲線が発明され、新しいものも引き続き提案されていますが、これらは高精度CADや道路設計のような特定の領域に限定されています。一般的な用途では、欠点があるにもかかわらず、ベジェ曲線は王座から退くことを頑なに拒否しています。したがって、ベジェ曲線は私たちが stuck with しているレガシー技術の一部なのです。
ソフトウェアエンジニアとしての私の問いは、それらとそれらで構築されたすべての技術を無効にすることなく、ベジェ曲線をより良くできるかということです。答えはイエスです。
ソース Lerp-a-derp
ベジェ曲線を描くことは、驚くほどシンプルで線形なプロセスです。
ヒント: この投稿のすべての図は完全にインタラクティブです。
制御点の列を与え、それらを線で結びます。次に、これらの線に沿って同時に進み、新しい点を生成し、それを再び接続します。このプロセスを、曲線上に位置する単一の点だけが残るまで繰り返します。この構成により、ベジェ曲線は最初に見えるよりもはるかに規則的になります。
線形補間(lerpsとしても知られる)は、例えば4つの制御点 (A, B, C, D) に対して、単一のコンパクトな式に要約できます。
γ(t) = A・(1 - t)^3 + B・3(1 - t)^2 t + C・3(1 - t) t^2 + D・t^3
ルールは単純です:(1 - t) の降べきの順、t の昇べきの順で、係数はパスカルの三角形のn行目から取ります。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
... ...
2Dおよび3Dの曲線では、式は個々のX、Y、またはZ座標に適用されます。
ベジェ曲線は任意の数の制御点で構築できますが、一般的な慣習は、4つの制御点を持つ3次ベジェ曲線のみを使用することです。これは、曲線が最初と最後の制御点のみを通過することが保証されているため、高次のベジェ曲線は形状を整えるのが難しいためです。
より大きな曲線は、複数の3次ベジェセグメントを結合することによって構築され、接線が整列されて、滑らかに見えるセグメント化された曲線が作成されます。
これが一般的に理解されている3次ベジェスプラインです。
ほとんどの描画アプリの「精密ペンツール」は、曲線に直接描画するのではなく、制御点を描画および編集することで構成されています。
どこでも語られる嘘
ペンツールには通常、制御点のいくつかの異なるモードがあります。
直感的には、これらは様々な程度の滑らかさを表します。対称接線は最も滑らかなオプションとして提供され、制約を緩和すると滑らかさの質が失われます。
実際にはこれは完全に間違っており、簡単に証明できます。
ベジェ曲線は、補間図から新しい制御点を読み取ることで正確に分割できます。
左右のセグメントは元の曲線と100%同一であり、常に継ぎ目で完璧に結合します。しかし、中央の接線は、中央近くの1つの分割を除いて非対称になります。
これは、曲率の(逆)半径を各点で表す曲率コームを使用して確認できます。
曲率コームは連続しており、ジャンプはありません。これは、隣接する接線の長さが等しいかどうか、つまり対称かどうかは完全に無関係であることを意味します。
このように滑らかで直感的なベジェ曲線を描こうとするのは、無駄な努力です。
これを改善する簡単な方法は、接線を絶対的なものとしてではなく相対的なものとして扱うことです。例えば、それらを各セグメントの開始点と終了点の間の距離に比例させることができます。
このスプラインは編集が容易です。なぜなら、各曲線点を移動すると、隣接するセグメントが自然に曲がって邪魔にならないようにするためです。この方法では、カスプ(尖点)がはるかに少なくなります。
接線の編集は同じままです。
しかし、曲率を再びプロットすると、これが良い解決策ではないことがわかります。
接線を比例してスケーリングしても、編集時に曲率が保存されることは保証されませんし、セグメント間での曲率の連続性も保たれません。
これはまた、ユーザーに「役立つツール」として曲率コームの可視化を提供することが、実際には非常に意地悪であることを示しています。
片端の曲率を調整すると、反対側にも影響するため、十分な値になるまで繰り返し調整する必要があります。
慎重に扱う
より効果的な戦略は、曲率を直接扱うことです。
これは一般的に難しい問題ですが、驚くべき関係があることが判明しており、直接観察できます。
セグメント A-B-C-D の開始点での曲率を考えます。これは A、B、C の位置のみに影響されます。D は C から切り離されていれば自由に移動できます。さらに、接線 A-B が水平であるため、C の垂直位置のみが重要です。
これは、多くの項を式でキャンセルする、基盤となる線形補間の結果です。
したがって、A における曲率は、A-B の長さと、C から A-B までの垂直距離のみに影響されます。
反対側では、C-D と B を持つ D についても同様です。
これはそれ自体ではあまり役に立ちません。
曲線点 (A または D) を移動すると、通常、接線を維持するために隣接する制御点 (B または C) も移動します。そして、対称または非対称の接線を回転させると、次のセグメントの隣接する接線も同じ角度で回転し、その側の曲率が変化します。
それでも、曲率を維持することが、単独ではクレイジーなアイデアではなく、接線を適切にスケーリングするだけで実行できることを示しています。
ルールは単純になるはずです。
曲線点を移動するときは、隣接するセグメントの開始と終了の曲率を維持する必要があります。
接線を移動するときは、現在のセグメントの反対側の端の曲率、および隣接するセグメントの両側の曲率を維持する必要があります。
これにより、曲線が意図を実際に尊重する編集エクスペリエンスが得られるはずです。
ただし、完全ではありません。
曲線点の移動はうまくいきますが、接線を回転させるとき、その接線の長さ自体がユーザーの意図の乏しい表現になります。
小さな変更が大きな曲率の変化を引き起こす可能性があり、一致する解を見つけようとする際に、曲線が予期せずジャンプしたり爆発したりする可能性があります。
したがって、曲率ハンドルで作業する方が良いです。そこでは、長さが曲率の(非逆数の)半径に直接対応します。
曲率コームとは異なり、ハンドルの長さは曲率の非逆数の半径であり、より自然な選択です。
これらのハンドルは非常に安定しており、2つの表現の間を行き来する必要なく、必要に応じて(just-in-time)従来のベジェ制御点に変換できます。
これは数値ドリフトも回避するのに役立ちます。
ゴルディロックス
これを実際に実現するには、所望の曲率 k0 と k1、開始/終了点 A と D、および開始/終了点の単位長接線が与えられた場合、接線の長さ l0 と l1 を解く必要があります。
曲線 γ(t) を与えると、単位接線ベクトル T(t) を、正規化された導関数として表現できます。
T(t) = γ'(t) / |γ'(t)|
これを使用して、最初の導関数と2番目の導関数を使用した2つのベクトル外積によって、曲率ベクトル K(t) を見つけることができます。
K(t) = T(t) × (γ''(t) / |γ'(t)|^2) × T(t)
外積は、K(t) が T(t) に垂直であることを保証します。つまり、それらは抽出します。