17

我有一组坐标,我将其转换为 svg 路径(使用三次贝塞尔曲线使其平滑)。当我应用一定的笔画宽度时,我得到以下结果(蓝点是我的坐标)具有笔划宽度的立方 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,必须设置为函数的参数。

目前它会一次找到一个偏移侧,但是每侧运行一次可以解决这个问题。

TLDR
实际上通过 svgContour 你可以找到任何 svg 形状的轮廓,目前它不支持填充模式,但下一个目标是实现它。它依赖 getPathData() 来获取任何 SVGGeometryElement 的 pathData,然后这个数据会经历三个阶段:

  • redrawSteepCurve前提:除非曲线足够平坦(在这种情况下,视觉渲染会很好),否则
    仅偏移曲线的点/控制点不会获得与另一个平行的贝泽曲线;这个方法需要一个 SVGPathData,如果它发现一个陡峭的曲线,它会分裂它直到它足够平坦(返回一个视觉上等效的 SVGPathData)。

  • contourPathData
    在这个阶段,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.ps将 PostScript 路径转换为“可填充”的 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 回答