【问题标题】:svg: generate 'outline path'svg:生成“大纲路径”
【发布时间】:2012-11-05 04:25:42
【问题描述】:

我有一组坐标,我将其转换为 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>

【问题讨论】:

  • 这很难。您需要以编程方式完成,还是可以使用 Illustrator 或 Inkscape?
  • 我需要以编程方式执行此操作,但如果您能告诉如何在程序中执行此操作,那也很有用...谢谢!
  • 在 Illustrator 中选择路径和菜单对象 > 展开外观。我对这背后的数学只有一个模糊的概念,但这不是一项简单的任务。
  • 如果不是为了不透明度,你可以克隆你的路径,给它一个更大的笔画宽度并改变颜色,你很容易得到你的第二个外部笔画。可能有一种裁剪蒙版的方法,但到目前为止,它们似乎是在蒙版之外裁剪而不是穿过蒙版存在的位置

标签: vector svg coordinates shapes


【解决方案1】:

我创建了 svgContour 函数,该函数被认为适用于与此类似的场景,
生成的轮廓偏移与stroke-width 值无关,必须设置为函数的参数。

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

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

  • 重绘陡峭曲线
    前提:绘制一条与另一条平行的贝泽曲线不是仅仅偏移曲线的点/控制点除非曲线足够平坦(在这种情况下,视觉渲染会很好);此方法采用 SVGPathData,如果发现陡峭的曲线,则将其拆分,直到足够平坦(返回视觉上等效的 SVGPathData)。

  • 轮廓路径数据
    在这个阶段 pathData 以点为单位解散,点以段连接,每个段偏移,然后为每个连续段找到一个交点(我们得到的是偏移点的列表)。

    李>
  • 画线
    此阶段将步骤 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>

轮廓被追踪!

【讨论】:

    【解决方案2】:

    我不确定这是否能解决您的问题。这取决于你想对大纲路径做什么。

    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
    

    试一试,但我不确定你是否会满意。输出的复杂性可能会暗示问题的实际复杂性。尤其是自相交路径是个问题。

    编辑(谈到问题): 我相信,一般来说,在数学上不可能创建一个与给定贝塞尔曲线完全“平行”的贝塞尔曲线。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 2016-07-19
      • 2020-12-14
      • 1970-01-01
      • 2013-06-16
      相关资源
      最近更新 更多