1 заметка с тегом

кривая Безье

Координаты кривых из СВГ файла

Скачать конвертер

Для работы мне необходимы контуры микроорганизмов, которые я использую для сравнения форм. Я получаю контуры из фотографий, очерчивая объект в векторном редакторе. Программа сохраняет результат в СВГ файле, а мне нужны живые координаты точек. Чтобы получить координаты, я анализирую СВГ файл.

СВГ файл состоит из тегов. Я разберу только один — path, — остальные мне не нужны. Он хранит описание криволинейных и замкнутых траекторий. Траектория — это и есть тот самый контур микроорганизма.

Учим синтаксис тега path

Описание траектории вложено в тег svg. Примерно так:

Заголовок подтверждающий, что это СВГ
<svg>
  <path ... />
</svg>

Тег path содержит один атрибут d с алгоритмом рисования траектории.

<path d="алгоритм рисования" />

Алгоритм состоит из букв-команд и цифр-координат, которые разделенны пробелом, запятой или знаком минус. Траекторию рисует перо, буквы-команды управляют, цифры-координаты показывают куда или как сместить перо, а разделители отделяют одно от другого.

Разделители разделяют

Пробел — это стандартный разделитель. Его можно ставить везде между командами и координатами. Спецификация СВГ разрешает не писать пробел, когда из контекста понятно, что здесь две разные сущности. Это сокращает объем СВГ-файла.

Запомним:

  • пробел не нужен между командой и числом;
  • пробел не нужен после запятой;
  • пробел не нужен перед знаком минус.

Запятая тоже разделяет два числа, но вместо нее можно написать пробел. Что именно написать — дело вкуса.

Следующие три записи эквивалентны, но последняя компактнее.

<path d="M 15 17 L 18 -23 Z" />
<path d="M 15, 17 L 18, -23 Z" />
<path d="M15,17L18-23Z" />

Теперь о цифрах.

Цифры хранят координаты

СВГ предназначен для хранения двумерной графики. Поэтому цифры задают координаты точек на плоскости. Для каждой точки используется два числа — первое для x, второе для y.

Координаты бывают абсолютными и относительными. Абсолютные координаты отсчитываются от нуля, относительные — от конечной точки предыдущей команды. Относительные — это шаг, на который надо сдвинуть перо относительно последней позиции.

Тип координат определяет регистр буквы-команды: большая буква обозначает абсолютную позицию, маленькая — относительную.

Заглавная буква-команда — для абсолютных координат, прописная — для относительных

Точка является десятичным разделителем вещественных чисел. Запись 12,75 — это два числа: 12 и 75, тогда как 12.75 — это одно вещественное число.

Точка — десятичный разделитель, запятая отделяет два числа.

Цифры еще описывают дополнительные параметры команды A, которая рисует дуги.

Буквы управляют пером

Буквы — это команды, которые управляют пером. За каждой командой следуют пары координат, которые показывают, куда сместить перо или как закруглить линию. Тег path использует следующие команды:

  • M — начать новую траекторию: переместить перо в заданную точку без рисования.
  • Z — замкнуть траекторию: переместить перо в начальную точку и нарисовать линию.
  • С, S — нарисовать кубическую кривую Безье.
  • Q, T — нарисовать квадратную кривую Безье.
  • L, Н и V — нарисовать произвольную, вертикальную или горизонтальную прямую.
  • A — нарисовать дугу окружности или эллипса.

Команду A я пропущу, но рассмотрю остальные.

M x y

М или m начинает новую траекторию. Команда перемещает перо в заданную точку и ничего не рисует. Большое М — первая обязательная команда тега path.

<path d="M20 50..." />
Z

Z или z замыкает траекторию — проводит прямую линию от последней позиции пера к первой точке траектории. Регистр буквы не важен. Обычно это последняя команда тега. Если нет, тогда после z опять стоит большое M, которое начинает новую траекторию. Если z не написано, траектория незамкнута.

<path d="M20 50 L 10 10, 140 10, 110 50z" />
<path d="M20 50 L 10 10, 140 10, 110 50z" />
<path d="M20 50 L 10 10, 140 10z M110 50, 80 60, 95 90z" />
L x y

L или l рисует прямую линию от последней позиции пера до заданной точки. Несколько следующих друг за другом команд описывают ломаную. В такой записи, для краткости, все L, кроме первой, не пишут. Если L стоит после M, ее тоже не пишут. Вот так:

<path d="M 70,12 L 24,30 L 60,70 L 120,50" />
<path d="M 70,12 L 24,30 60,70 120,50" />
<path d="M 70,12 24,30 60,70 120,50" />
H x

H или h рисует горизонтальную линию от последней позиции пера до указанной точки. Координата у не меняется.

V x

V или v рисует вертикальную линию от последней позиции пера до указанной точки. Координата x не меняется.

C cx1 cy1 cx2 cy2 x2 y2

С или с строит кубическую кривую Безье. Она состоит из четырех точек: первая и последняя задают начало и конец кривой, две промежуточные управляют формой. Так как первая точка совпадает с текущим положением пера, то после команды C указывают только три точки: две управляющие вершины (cx1 cy1), (cx2 cy2) и последнюю точку кривой (x2 y2).

<path d="M40 50 C 60 10, 90 90, 110 50" />

Поликривая Безье — это несколько соприкасающихся кривых Безье, где конец одной кривой становится началом следующей. Последовательные команды C описывают поликривую. Для экономии байтов все команды, кроме первой C, не пишут.

<path d="M30 100C50 50,70 20,100 100,110 130,45 150,65 100" />

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

S cx2 cy2 x2 y2

S или s строит гладкую кубическую кривую Безье так, что ее первая управляющая вершина является зеркальным отражением второй управляющей вершины предыдущей кривой Безье. Отражение относительно начальной точки данной кривой.

Q cx1 cy1 x2 y2

Q или q строит квадратную кривую Безье. Синтаксис команды аналогичен C, только здесь используется одна управляющая вершина.

Несколько команд Q описывают квадратную поликривую Безье. Для краткости все команды, кроме первой Q, не пишут. Чтобы квадратная поликривая получилась гладкой, используют команду T.

T x2 y2

T или t строит гладкую квадратную кривую Безье так, что ее единственная управляющая вершина является зеркальным отражением управляющей вершины предыдущей кривой Безье.

Со структурой файла разобрались.

Пишем конвертер СВГ в текст

Конвертер готов. Это экзешник. Инсталировать не нужно. Сохраните на диск и запустите.

Скачать конвертер

Для описания любого контура достаточно трех команд: M, C и Z. Конвертер понимает еще и четвертую: L, остальные — нет.

Конвертер выбирает из СВГ-файла теги path, вычисляет координаты точек траектории и сохраняет их в текстовом файле.

Конвертер не проверяет валидность СВГ-файла. Ему все равно, какая информация находится вокруг тега path. На вход конвертера можно подать любой мусор с корректными данными только в теге path.

Конвертер поддерживает пропорциональное и произвольное масштабирование координат: перед сохранением он спрашивает размер области, в которую надо вписать траекторию.

Конвертер позволяет задать позицию начала координат: в одном из углов, на середине стороны или в центре прямоугольника, ограничивающего контур.

Конвертер сохраняет в текстовом файле пары чисел — двумерные координаты точек контура. Десятичный разделитель — точка. Числа разделены пробелом.

12.3 15.6 78.4 24.1 15 123

Детали

Конвертер написан на Дельфи 7.

Пары чисел вырезаю из СВГ-файла с помощью регулярного выражения. Понимает числа разделенные пробелом, запятой или минусом.

/(-?\d+(\.\d+)?)[,|\s]?(-?\d+(\.\d+)?)\s?/

Для построения кубической кривой Безье применяю адаптивное разбиение.

Полученные данные анализирую методами геометрической морфометрии. Но это уже другая история.

С Новым годом!

 2   2015   векторная графика   кривая Безье   регулярные выражения   СВГ