查找平行或偏移 SVG 路径

use*_*853 4 javascript math svg polygon

我需要一个并行的 SVG 路径。我的路径为“M0 0 H50 A20 20 0 1 0 100 50 v25 C50 125 0 85 0 85 z”。令偏移量为 2px。

原始路径 O/P: 路径图像 进一步划分时的路径段:

0:  ["M", 0, 0]
1:  ["H", 50]
2:  ["A", 20, 20, 0, 1, 0, 100, 50]
3:  ["V", 75]
4:  ["C", 50, 125, 0, 85, 0, 85]
Run Code Online (Sandbox Code Playgroud)

有什么算法或方法可以找到各个段或整体的偏移路径吗?

更新图像: 红线代表我需要获取的偏移 SVG 图像。 偏移 SVG 路径示例

ccp*_*rog 6

算法解法

\n\n

偏移线相对来说是微不足道的。对于圆弧,可以通过将两个半径更改相同的值来解决。(你仍然需要找到终点。)

\n\n

问题是贝塞尔曲线。有一个库bezier.js可以用数学方法解决这个问题。有关背景知识,请参阅 Pomax 所著的“Primer on B\xc3\xa9zier Curves”,特别是有关曲线偏移的章节。

\n\n

正如那里所指出的,不可能找到一条贝塞尔曲线来抵消另一条曲线;您需要将其分为“更简单”的子部分。该库实现了一个函数,再次组合这些部分并返回偏移路径:.offset(d)

\n\n

图解

\n\n

矢量图形 GUI 实现了这种功能。下面描述了 Inkscape,但我确信 Adob​​e Illustrator(也许还有 Sketch)可以做或多或少相同的事情。

\n\n
    \n
  • 画出你的道路。Inkscape 有一个“XML 编辑器”,您可以在其中直接输入路径定义字符串。
  • \n
  • 删除填充并定义宽度为您想要实现的偏移量两倍的笔划。
  • \n
  • 从“路径”菜单中选择“描边到路径”。
  • \n
  • 从“路径”菜单中选择“分离”。
  • \n
  • 现在你有两条(填充的)路径,一条偏移到外部,一条偏移到内部;丢弃不需要的。
  • \n
\n\n

请注意,您的路径定义无效。点 [50, 0] 和 [100, 50] 之间的圆弧半径为 20,但两点之间的距离为 70.71。根据规范,路径被绘制为

\n\n
M 0,0 H 50 A 35.3553,35.3553 0 1 0 100,50 V 75 C 50,125 0,85 0,85 Z\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我用 Inkscape 找到一条插入 2 的路径,我得到

\n\n
M 2,2 H 45.7988 C 34.2583,16.6514 35.0764,37.9045 48.5859,51.4141 62.0955,64.9236 83.3486,65.7417 98,54.2012\nV 74.1094 C 73.6278,98.1373 49.7442,100.409 31.6426,96.7891 14.9635,93.4533 3.8673,85.3962 2,83.9785 Z\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,Inkscape 计算了圆弧段的三次贝塞尔近似值。您只需将半径增加 2、更改大圆弧标志并保留端点即可恢复圆弧:

\n\n
M 2,2 H 45.7988 A 37.3533 37.3533 0 0 0 98,54.2012\nV 74.1094 C 73.6278,98.1373 49.7442,100.409 31.6426,96.7891 14.9635,93.4533 3.8673,85.3962 2,83.9785 Z\n
Run Code Online (Sandbox Code Playgroud)\n


enx*_*eta 5

我知道你有这条路,你需要在边界内画一条线。我的解决方案是将<feMorphology>过滤器与operator="erode". 我希望这就是您所需要的。

<svg viewBox="-10 -10 120 120" width="300">
 <defs>
   
<filter id="erode">
<feMorphology in="SourceAlpha" result="eroded"
operator="erode" radius="2"/>
<feFlood flood-color="white" result="white" />
<feComposite in ="white" in2="eroded" operator="in" />
</filter>

   
<filter id="erode1">
<feMorphology in="SourceAlpha" result="eroded1"
operator="erode" radius="3"/>


</filter>
<path id="g" d="M0, 0
         H50
         A20, 20, 0, 1, 0, 100, 50
         V75
         C50, 125, 0, 85, 0, 85" />
</defs>

<use xlink:href="#g" />
<use xlink:href="#g" filter="url(#erode)" /> 
<use xlink:href="#g" filter="url(#erode1)" /> 
</svg>
Run Code Online (Sandbox Code Playgroud)