17

svgパスに変換する一連の座標があります(立方体のベジエを使用してスムーズにします)。特定のストローク幅を適用すると、次の結果が得られます(青い点は私の座標です)ストローク幅の3次SVGパス

私が興味を持っているのは、灰色の図形の周りを走るパスを取得することです(たとえば、灰色と白の境界線上の任意の点を選択し、開始点に戻るまで図形の周りを丸めます)。

そのようなパスをどのように計算しますか?

参考までに、これは私のsvg情報です:

 <g>
  <title>number 3</title>
  <path d="m238,50c5.67569,-1.01351 11.8327,-3.8229 20.92029,-2.14724c8.68106,0.69732 14.21173,4.90255 18.07971,7.14724c6.23697,3.61945 13.47556,9.5931 15,18c1.07056,5.90372 1.17343,10.97649 -4,16c-6.76816,6.57204 -19.45392,9.57738 -25.69687,10.59046c-3.94836,0.64074 4.73492,3.29883 10.69687,5.40954c8.05417,2.85142 15,8 21,14c6,6 5.26578,10.94739 5.26578,17.03015c-2.4541,7.30975 -4.23343,11.08675 -11.26578,12.96985c-3.98279,1.0665 -11.92578,3.49756 -17,4c-8.95618,0.88684 -15.80411,2.97838 -26,0l-9.19197,-3.44464" id="svg_1" opacity="0.5" stroke-width="10" stroke-linejoin="round" stroke="#000000" fill="none"/>
 </g>
4

2 に答える 2

3

これに似たシナリオで考えられるsvgContour関数を作成しました
。結果の輪郭オフセットはstroke-width値とは関係がなく、関数のパラメーターとして設定する必要があります。

現時点では、一度に1つのオフセットサイドが検出されますが、サイドごとに1回実行すると、この問題を解決できます。

TLDR
実際にはsvgContourを介して、任意のsvg形状の輪郭を見つけることができます。現在、塗りつぶしモードはサポートされていませんが、次の目標の1つはそれを実装することです。getPathData()に依存してSVGGeometryElementのpathDataを取得し、このデータは次の3つのフェーズを通過します。

  • redrawSteepCurve前提:曲線が十分に平坦でない限り、曲線
    の点/制御点をオフセットするだけでは、バイザー曲線を別の曲線と平行に描画することはできません(この場合、視覚的なレンダリングは問題ありません)。このメソッドはSVGPathDataを取得し、急な曲線が見つかった場合は、十分に平坦になるまで分割します(視覚的に同等のSVGPathDataを返します)。

  • この段階では、 pathData
    はポイントでディスアンブルされ、ポイントはセグメントで接続され、各セグメントはオフセットされ、隣接するセグメントごとに交点が検出されます(オフセットされたポイントのリストが返されます)。

  • drawLine
    このフェーズでは、ステップ2のポイントをステップ1のpathDataに配置し、最後に等高線を描画します。

例:

const path = document.querySelector('path')

svgContour(path, 5)
svg {
  width: 100vw;
  height: 100vh
}
<script src="https://cdn.rawgit.com/fracalo/svg-contour/master/dist/svg-contour.js"></script>

<svg viewBox='300 0 100 200'>
  <g>
    <title>number 3</title>
    <path d="m238,50c5.67569,-1.01351 11.8327,-3.8229 20.92029,-2.14724c8.68106,0.69732 14.21173,4.90255 18.07971,7.14724c6.23697,3.61945 13.47556,9.5931 15,18c1.07056,5.90372 1.17343,10.97649 -4,16c-6.76816,6.57204 -19.45392,9.57738 -25.69687,10.59046c-3.94836,0.64074 4.73492,3.29883 10.69687,5.40954c8.05417,2.85142 15,8 21,14c6,6 5.26578,10.94739 5.26578,17.03015c-2.4541,7.30975 -4.23343,11.08675 -11.26578,12.96985c-3.98279,1.0665 -11.92578,3.49756 -17,4c-8.95618,0.88684 -15.80411,2.97838 -26,0l-9.19197,-3.44464"
    id="svg_1" opacity="0.5" stroke-width="10" stroke-linejoin="round" stroke="#000000" fill="none" />
  </g>
</svg>

輪郭がトレースされます!

于 2016-12-02T18:13:19.977 に答える
1

これで問題が解決するかどうかはわかりません。アウトラインパスで何をしたいかによります。

PostScriptには、ストロークされたパスのアウトラインを計算する機能があり、それを埋めると、元のパスをストロークしたときと同じ視覚的な出力が生成されます。ただし、結果のパスデータは、予想よりも洗練されていない可能性があります。

次のPostScriptプログラム(path2outlines.psPostScriptパスを「入力可能な」SVGパスに変換します。

%!
% First, we're converting to outlines.
strokepath

% This is just a string buffer
/S 99 string def

% This defines a procedure for printing coordinates to stdout
/printCoordinates {     % coord* number command
  print                 % coord* number
  array astore          % array
  {                     % coord
    ( )print            % coord
    //S cvs             % string
    print               % 
  }forall
  (\n)print
} bind def

% This iterates over the path segments and prints the SVG path data.
{2(M) printCoordinates}
{2(L) printCoordinates}
{6(C) printCoordinates}
{(Z\n)print}
pathforall

quit

このようにデータファイルをフィードする必要があります(%コメントを開始します)。これを呼びましょうdata.ps

%!
% First, set up the graphics state parameters
% Equivalent to stroke-width="10"
10 setlinewidth 

% Equivalent to stroke-linejoin="round" (0 = miter, 1 = round, 2 = bevel)
1 setlinejoin

% Now, we're defining the path.
% Use postfix notation, i.e. first coordinates, then command.
% m/M = moveto
% l = rlineto
% L = lineto
% c = rcurveto
% C = curveto

238 50 moveto
5.67569 -1.01351 11.8327 -3.8229 20.92029 -2.14724 rcurveto
8.68106 0.69732 14.21173 4.90255 18.07971 7.14724 rcurveto
6.23697 3.61945 13.47556 9.5931 15 18 rcurveto
1.07056 5.90372 1.17343 10.97649 -4 16 rcurveto
-6.76816 6.57204 -19.45392 9.57738 -25.69687 10.59046 rcurveto
-3.94836 0.64074 4.73492 3.29883 10.69687 5.40954 rcurveto
8.05417 2.85142 15 8 21 14 rcurveto
6 6 5.26578 10.94739 5.26578 17.03015 rcurveto
-2.4541 7.30975 -4.23343 11.08675 -11.26578 12.96985 rcurveto
-3.98279 1.0665 -11.92578 3.49756 -17 4 rcurveto
-8.95618 0.88684 -15.80411 2.97838 -26 0 rcurveto
-9.19197 -3.44464 rlineto

使用しているプラ​​ットフォームに応じて、Ghostscriptを使用して次のように呼び出すことができます。

gs -q data.ps path2outlines.ps > outlinePath.txt

試してみてください。でも、満足できるかどうかはわかりません。出力の複雑さは、問題の実際の複雑さについてのヒントを与える可能性があります。特に自己交差するパスは問題です。

編集(問題について言えば):一般に、与えられたベジェ曲線に完全に「平行」なベジェ曲線を作成することは数学的に不可能であると私は信じています。

于 2012-11-18T22:18:27.347 に答える