Как SVG / EPS (векторы) обрезать путь другим путем? - PullRequest
2 голосов
/ 08 мая 2020

Я пытаюсь понять, как программы SVG (например, браузеры) рисуют фигуру по заданным путям. Я с трудом понимаю, как нарисован путь и как одна часть фигуры обрезается.

Например, рассмотрим букву Å и A с верхним кольцом. Код SVG выглядит как

<svg viewBox="0 0 1800 1800" xmlns="http://www.w3.org/2000/svg">
<path 
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M426 822q0 -47 -24 -71.5t-80 -24.5q-104 0 -104 96q0 46 25.5 71t78.5 25q56 0 80 -25t24 -71z
M319 515h-1l-85 -264h169z
M374 822q0 51 -52 51q-50 0 -50 -51q0 -49 50 -49q52 0 52 49z
" />
</svg>

JSFIDDLE

  • Первая строка: dr aws тело A.
  • Вторая строка: dr aws верхний кружок.
  • Третья строка: отсекает треугольник от первой строки.
  • Четвертая строка: отрезает маленький кружок от второй линии.

Мой вопрос: как программы SVG понимают рисование фигуры по второй линии, но вырезание фигуры из существующая форма?

Очевидно, ответ таков: если путь находится внутри другого пути, он обрезается, в противном случае это dr aws.

Есть две причины, по которым я думаю, что это не вся картина :

  1. Требуются огромные вычисления, чтобы определить, находится ли путь внутри другого пути.
  2. Порядок линий не важен (путь отсечения не обязательно следует после пути рисования) .

Это, конечно, не ограничивается SVG, так как другие векторные форматы, такие как EPS, делают то же самое.

Чтобы добавить прагматичную перспективу c, прочтите вопрос как: как мы можем проанализировать (на любом языке программирования) указанный выше элемент d, чтобы узнать, какой путь отрисовывается (черный), а какой отсекается (белый) из четырех путей, указанных в приведенном выше SVG ?

Ответы [ 2 ]

3 голосов
/ 07 июня 2020

Вообще говоря, вы вообще не анализируете пути.

Вместо этого вы «сканируете», конвертируете каждый путь в серию прямоугольников с текущим разрешением. Каждый реакционный угол может быть высотой всего один пиксель, и может быть более одного прямоугольника при данном значении y.

Сделайте это как для пути, который будет заполнен или обведен, так и для пути, который будет применяться как клип , затем пересечь серию прямоугольников. Это, очевидно, гораздо более простая задача. Затем заполните прямоугольники.

Это, конечно же, дает результат, который будет правильным только при заданном разрешении. Измените разрешение, и вы получите другую серию прямоугольников. Однако он дает правильный результат на приличной скорости. Пересечение двух произвольных путей для создания нового произвольного пути, очевидно, является гораздо более сложной задачей, и для получения результата нам не нужно выполнять.

1 голос
/ 07 июня 2020

В следующих примерах я использую путь для буквы A в вашем примере.

В первом элементе svg буква A рисуется справа налево, в то время как отверстие отображается в противоположном направлении: вы получаете «вырезку».

Во втором примере I ' Мы перевернули часть, которая рисует отверстие. Теперь эта часть нарисована в том же направлении, что и основная часть буквы A. Теперь вы не получите "отсечения"

В третьем примере я использую обратный путь, как и раньше, но я m добавление fill-rule="evenodd" Теперь отверстие отсекается, поскольку атрибут "fill-rule является атрибутом представления, определяющим алгоритм, который будет использоваться для определения внутренней части фигуры" .

svg{width:30%;border:solid}
<svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
<path 
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M319 515h-1l-85 -264h169z
" />
</svg>
<svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
<path 
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M319,515L402,251L233,251L318,515L319,515z
" />
</svg>

<svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M319,515L402,251L233,251L318,515L319,515z
" />
</svg>
...