Как преобразовать путь VML в путь SVG?

В настоящее время я работаю над приложением, для которого мне нужно преобразовать формы VML в формы SVG. Хотя я могу справиться со всеми другими аспектами этого, я столкнулся с проблемой правильного преобразования path формы из пути VML в путь SVG. Я использую комбинацию XSLT и Javascript для своих кодов.

У меня достаточно контроля над преобразованием угловых форм (то есть фигур, содержащих только прямые линии), но я сталкиваюсь с трудностями при преобразовании пути с кривыми.

Например, для простой формы это:

введите описание изображения здесь

Путь VML: m10800,qx21600,10800,10800,21600l,21600,,xe

Теперь, если я заменю m на M, l на L и qx на Q и сделаю необходимое масштабирование координат, я получу следующую форму SVG:

введите описание изображения здесь

Путь SVG рассматривает первый набор координат в Q/qx как контрольную точку и, следовательно, фактический путь не проходит через точку, тогда как VML предназначал эти координаты как точку, через которую путь должен проходить. Я не понимаю, как я могу добиться этого с помощью SVG (т.е. убедиться, что путь проходит через определенную точку или точки).

В настоящее время я использую this и this для исследования SVG и VML соответственно. Я также пробовал использовать Vector Converter 1.2, но это не так. тоже работает.

Может ли кто-нибудь предложить мне способ, библиотеку, какие-либо учебные ссылки или учебные пособия, где я могу найти решение моей проблемы?

Заранее спасибо!!


person Surender Thakran    schedule 02.02.2014    source источник


Ответы (1)


«qx» в VML - это «эллиптический квадрант», «Q» в SVG - это квадратичный безье. Совершенно разные вещи.

Самым простым решением преобразования qx является аппроксимация его кубической кривой Безье. Использование дуги было бы наиболее точным, но для определения правильного значения для «флага развертки» потребуется сложная математика. Хотя кубическая кривая Безье не является идеальным приближением к квадранту, она очень близка, и ошибка не будет достаточно заметной, чтобы повлиять на ваши рисунки.

Секрет рисования круговых / эллиптических квадрантов - это постоянная 0,5522847498. Он определяет длину линий контрольных точек для имитации эллиптической кривой. Вы можете найти объяснения того, как это число получено, погуглив это число.

Итак, VML определяет «qx» как эллиптический квадрант, начинающийся в направлении X. Таким образом, для команды пути "qx21600,10800" алгоритм преобразования будет следующим:

arcFactor = 0.5522847498;
currentX = 10800;
currentY = 0;      // start coords (from the move)

x = 21600;
y = 10800;  // first coords in "qx"

dx = x - currentX;
dy = y - currentY;

// Calculate first control point
cp1x = currentX + dx * arcFactor;
cp1y = currentY;   // starts out horizontal

// Calculate second control point
cp2x = x;
cp2y = y - dy * arcFactor;

svgBezier = "C" + cp1x + "," + cp1y + "," + cp2x + "," + cp2y + "," + x + "," + y;

Теперь ваша кривая имеет второй набор координат для qx. В спецификации сказано, что это означает повторение команды «qx». Однако для второго набора нет смысла вести себя точно так же, как qx (т. Е. Начинать горизонтально). Так что я думаю, что они должны вести себя как «цы» (начать вертикально). Т.е. qx и qy чередуются. Предполагая, что это так, расчет qy должен быть:

// Calculate first control point
cp1x = currentX;   // starts out vertical
cp1y = currentY + dy * arcFactor;

// Calculate second control point
cp2x = x - dx * arcFactor;
cp2y = y;

Демо-скрипт здесь

person Paul LeBeau    schedule 03.02.2014
comment
не должно ли значение currentY быть равным нулю для qx? - person Surender Thakran; 03.02.2014
comment
Да, ты прав. Я исправил это. Однако код в демонстрации был правильным. - person Paul LeBeau; 03.02.2014
comment
Интересно узнать, откуда взялось 0,5522847498, я обнаружил следующее: hansmuller-flex.blogspot.com/2011/04/ и itc.ktu.lt/itc354/Riskus354.pdf. Это k = 0,5522847498, и его обычно называют магическим числом. Я не выдумываю. - person technomalogical; 22.04.2015
comment
Если вы возьмете функцию Безье и вставите координаты точки 45deg в четверть круга (например, x = 1 / sqrt (2); y = 1 / sqrt (2)). Значение, которое вы получите в конце, будет (4/3) * (sqrt (2) -1) = 0,5522847498. На самом деле это не так сложно сделать, если вы хотите немного поупражняться в математике :) - person Paul LeBeau; 23.04.2015