I have an array of control points that represent a high-order Bezier curve.
How can I draw this curve using a single SVG-path?
UPD:
For example, I have a set of points: (x1, y1) (x2, y2) (x3, y3) (x4, y4) (x5, y5).
How SVG-path will look like in the terms of C
, S
, Q
or T
?
UPD 2: SOLUTION
I asked this question to depict a object path animated with TweenMax.
Later I received reply on GreenSock forum.
Here's CodePen example.
Short answer: you can't.
SVG only has built in Quadratic (2nd order) and Cubic curves (3rd order), whereas the curve you're showing is Quartic (4th order). SVG has no generic "N term Bezier" draw instruction, so you're going to have to compromise here.
Some options:
toDataURL
function and then load that image as image in your SVG. This will work perfectly fine, but if you use created SVG path styling, making the canvas generate the same style could be a challenge.Bottom line: if you need to show higher order Bezier curves, SVG is not an appropriate technology to use (I'd recommend just doing your animation using the canvas, or better yet, something like d3.js or paper.js. Probably the latter).
And if you end up rolling your own, the sampling function is ludicrously simple. Curves are parametric, controlled by a value t
that runs from 0 to 1 (inclusive), and can be written as a nested linear interpolation:
getCurvePoint(t, points) {
if (points.length === 1) return points[0];
var newpoints = [];
for(var i=0,j=1; j<points.length; i++,j++) {
newpoints[i] = lerp2d(t, points[i], points[j]);
}
return getCurvePoint(t,newpoints);
}
with the lerp
function being the standard linear interpolation function:
lerp(ratio, start, end) {
return ratio*start + (1-ratio)*end;
}
lerp2d(ratio, start, end) {
return {
x: lerp(ratio, start.x, end.x),
y: lerp(ratio, start.y, end.y)
};
}
And a simple jsbin example: http://jsbin.com/pesutibefu/edit?html,js,output using points
var points = [
{x:50, y:100},
{x:50, y:250},
{x:210, y:250},
{x:250, y:50},
{x:380, y:150}
];
gives us:
Although a Paper.js sketch would be easier to work with if you need animated pretty paths, with draggable control points, etc.