2012-11-30 2 views
8

ストロークパスを塗りつぶしオブジェクトに変換したいと考えています。 (プログラマチックに、JavaScriptで)ストロークのアウトラインを取得する方法は?

この行は単純な曲線です。一連の座標です。私はこの線をパスとしてレンダリングし、それに一定の厚さのストロークを与えることができます...しかし、私はストロークラインではなく塗りつぶしたシェイプを得ようとしていますので、ワーピングその結果、「ストローク」は厚さが変化したり、カスタムビットがカットされたりすることがあります(実際のSVGストロークではこれらのことはできません)。

私は手動で線を太くして太くしています。私はこれを行う関数を見つけることができません - 私はD3.jsRaphaëlのドキュメントを見てきましたが、運はありません。誰でもこれを行うライブラリ/関数を知っていますか?

さらに、私が持っているライン座標のリストを取って効果的にストロークする新しいパスを作成することで、このタスクを手動で行う方法についての幾何学的理論を誰かに教えてもらえれば、素晴らしいだろう。別の言い方をすれば、ブラウザは、パスをストロークするように指示したときに何を行いますか - ストロークがどのような形状になるべきか、どのように動作しますか?最近、同様の質問がありました

答えて

3

svg: generate 'outline path'

すべてのすべてで、これは非自明な課題です。リンクされた質問に対する私の答えで述べたように、PostScriptは、基本的にストロークと同じ出力を生成するパスを生成するコマンドを持っています(strokepath)。あなたがリンクされた質問に投稿したコードを実行するときにGhostscriptが吐き出すものを見れば、それはかなり醜いです。そしてInkscapeでさえ本当に良い仕事をしていません。私はちょうどパス=>アウトラインストロークを試しました(英語のキャプションが言うべきものだと思います)、出てきたものは実際にはストロークされたパスと同じには見えませんでした。

「最も単純な」ケースは、曲線を含まない非自己交差ポリライン、ポリゴン、またはパスしかない場合です。一般に、正確な「平行」ベジェ曲線を右に描画することはできません。ストローク区域を区切る重要ではないベジェ曲線の左にあります - 数学的には存在しません。だからあなたはそれを一方向に近づかなければなりません。直線部分については、正確な解を比較的容易に見つけることができる。

ベクトルパスを曲線/円弧で描画する古典的な方法は、十分に滑らかなポリラインを使用してすべてを近似することです。 De Casteljau's Algorithmは、通常、ベジエ曲線を線分に変換するために使用されます。 (これは基本的にGhostscriptでstrokepathコマンドを使用したときに出てくるものです)。適切なlinejoinとmiterlimitの規則を使用して、平行線分の区切りを見つけることができますが、それらを正しく結合する必要があります。もちろん、折り返しを忘れないでください。

パス内に中空領域ができる、つまり黒いパスの「交差領域」が白くなる可能性があるため、自己交差パスが難しいと考えました。 nonzero winding ruleを使用している場合、これはオープンパスの問題ではないかもしれませんが、私はこれについて慎重に考えています。閉じたパスの場合、逆方向に実行するには、おそらく2つの「区切り」パスが必要です。しかし、私は今、これが本当にすべての潜在的な落とし穴をカバーしているかどうかは分かりません。

申し訳ありませんが、私はこれと多くの混乱を引き起こし、多分助けにはならないでしょう。

1

標準的な方法は、Tiller-Hansonアルゴリズム(2次元プロファイルのオフセット、1984年、刺激的に無料でオンラインになっていない)です。これは良い近似を作成します。各ベジェ曲線の制御点は曲線の始点と終点に接する線上にあるため、平行曲線は同じプロパティを持つことになります。そこで、カーブの開始点と終了点をオフセットしてから、これらの交点を使用して新しい制御点を見つけます。しかし、これは急なカーブでは非常に悪い結果をもたらします。そのため、最初のステップは、ベジェ曲線に対して非常に簡単な元のカーブを、十分に小さな角度になるまで2等分することです。

(i)各頂点の内側で、平行線の間の交差点に対処するには、他の改良が必要です。 (ii)各頂点の外側の隙間を埋める円弧を挿入するステップと、 (iii)端部キャップを追加する - 正方形、突合せまたは円形。

Tiller-Hansonは実装が難しいですが、FreeTypeライブラリのftstroke.c(http://git.savannah.gnu.org/cgit/freetype/freetype2.git/)にはオープンソース実装があります。 tree/src/base/ftstroke.c)を参照してください。

このコードを統合することは非常に難しいかもしれませんが、私はそれをうまく使い、うまくいきました。

1

このページには、ベゼル曲線に関する一般的なチュートリアルがあり、オフセットカーブの良いセクションがあります。

http://pomax.github.io/bezierinfo/

あまり正確ますが、おそらくより速い方法はここで見つけることができます。ベジエ曲線にカーブの平行が、一般的にベジェ曲線ではありませんので、

http://seant23.wordpress.com/2010/11/12/offset-bezier-curves/

は、数学的な答えはありません。ほとんどの方法は、特に一連の曲線を扱う場合、縮退したケースを持っています。

問題点のない単純な曲線を考えてみましょう。カスプなし、ループなし、屈曲なし、そして理想的には厳密に増加する湾曲。すべての開始曲線をこれらの単純な曲線に切り詰めます。これらの単純な曲線のすべてのオフセット曲線を探します。すべてのオフセットカーブをギャップと交差を処理して戻します。二次曲線は、それらを操作するオプションがあれば、はるかに扱いやすくなります。

私はほとんどのブラウザが2次曲線でも縮退しているので、processingjsに似たようなことをすると思います。例えば、曲線200,300,719,301,500,300を100以上の厚さで見る。

関連する問題