Найти параллельный или смещенный путь SVG - PullRequest
0 голосов
/ 21 ноября 2018

Мне нужен параллельный путь 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]

Любой алгоритм или способ найти путь смещения дляотдельные сегменты или в целом ??

Обновленное изображение: Красные линии представляют смещенное изображение SVG, которое мне нужно получить. Пример смещения SVG Path

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Алгоритмическое решение

Смещение линий относительно тривиально.Для дуг это можно решить, изменив оба радиуса на одно и то же значение.(Вам все еще нужно найти конечные точки.)

Проблема в кривых Безье.Существует библиотека bezier.js , которая решает это математически.Для справки, посмотрите на сопутствующий «Учебник по кривым Безье» Pomax, особенно главу о смещении кривой .

Как указано там, невозможно найти единственную кривую Безьеэто смещает другую кривую;вам нужно разделить его на «более простые» части.Библиотека реализует функцию, которая снова объединяет эти части и возвращает путь смещения: .offset(d).

Графическое решение

Графические графические интерфейсы векторной графики реализуют подобные вещи.Далее описывается это для Inkscape, но я уверен, что Adobe Illustrator (и, возможно, Sketch) может делать более или менее то же самое.

  • Нарисуйте свой путь.В Inkscape имеется «XML-редактор», в который можно напрямую ввести строку определения пути.
  • Удалите заливку и определите обводку с шириной, которая в два раза превышает смещение, которое вы хотите достичь.
  • Выберите«Stroke to Path» из меню «Path».
  • Выберите «Break Apart» в меню «Path».
  • Теперь у вас есть два (заполненных) пути, один из которых смещен наружупо смещению внутрь;откажитесь от того, что вам не нужно.

Обратите внимание, что ваше определение пути неверно.Дуга между точками [50, 0] и [100, 50] задается с радиусом 20, но две точки находятся на расстоянии 70,71.В соответствии с spec вместо этого путь рисуется как

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

. Если я нахожу путь, вставленный на 2 с помощью Inkscape, я получаю

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
V 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

Примечание.что Inkscape вычислил кубическое приближение Безье для сегмента дуги.Вы можете вернуться к дуге, просто увеличив радиус на 2, изменив флаг большой дуги и сохранив конечные точки:

M 2,2 H 45.7988 A 37.3533 37.3533 0 0 0 98,54.2012
V 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
0 голосов
/ 21 ноября 2018

Я понимаю, что у вас есть этот путь, и вам нужно нарисовать линию внутри границы.Мое решение - использовать фильтр <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>
...