Question

I am currently working on an app for which I need to convert VML shapes into SVG shapes. While I can handle all other aspects of it, I am facing problem in correctly converting the path of the shape from VML path to SVG path. I am using a combination of XSLT and Javascript for my codes.

I have enough control on conversion of angular shapes (i.e. shapes containing only straight lines) but I am facing difficulty in converting path with curves.

For instance, for a simple shape this:

enter image description here

The VML path is: m10800,qx21600,10800,10800,21600l,21600,,xe

Now if I replace m with M, l with L and qx with Q and do the necessary scaling of the coordinates I get the following SVG shape:

enter image description here

The SVG path treats first set of coordinates in Q/qx as a control point and hence the actual path doesn't passes through the point whereas the VML intended those coordinates as the point over which the path should pass through. I don't understand how I can achieve that with SVG (i.e. making sure that the path passes through a specific point or points).

Currently I am using this and this for researching SVG and VML respectively. I also tried using Vector Converter 1.2 but that doesn't works either.

Can anyone suggest me a way, a library, any study links or tutorials where I can find a solution to my problem?

Thanks in advance!!

Était-ce utile?

La solution

"qx" in VML is an "elliptical quadrant", "Q" in SVG is a quadratic bezier. Completely different things.

The simplest solution to converting a "qx" is to approximating it with a cubic bezier. Using an arc would be most accurate, but there will be some tricky maths involved in order to determine the correct value for "sweep flag". Although a cubic bezier is not a perfect approximation to a quadrant, it is very close, and the error will not be noticeable enough to affect your drawings.

The secret to drawing circular/elliptical quadrants is the constant 0.5522847498. It defines how long the control point lines have to be to simulate the elliptical curve. You can find explanations for how it is derived by googling that number.

So VML defines "qx" as an elliptical quadrant starting out in the X direction. So given the path command "qx21600,10800", the algorithm for conversion will be:

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;

Now your curve has a second set of coordinates to the qx. The spec says that it means a repeat of the "qx" command. However it makes no sense for the second set to behave exactly the same as the qx (ie. start out horizontal). So I think they must actually behave as a "qy" (start out vertical). Ie. the qx and qy alternate. Assuming that is the case, the calculation for the qy should be:

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

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

Demo fiddle is here

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top