Instantly share code, notes, and snippets.

Noitidart/_js-snippet-CubicBezierSplit2.js

Created May 5, 2014
_js-snippet-CubicBezierSplit2 - This split method is from iScriptDesign.com under "Tutorial > Split Bezier" I'm posting here in case that site goes down.
 Split bezier Shows the possibility to split a bezier curve, two separate techniques are used: Bernstein's Polynomials Casteljau's Algorithm Bernstein's Polynomials The Bernstein Polynomial implemented in javascript reads as: getBezier = function getBez(percent,p1,cp1,cp2,p2) { function b1(t) { return t*t*t } function b2(t) { return 3*t*t*(1-t) } function b3(t) { return 3*t*(1-t)*(1-t) } function b4(t) { return (1-t)*(1-t)*(1-t) } return {x: p1.x*b1(percent) + cp1.x*b2(percent) + cp2.x*b3(percent) + p2.x*b4(percent) , y: p1.y*b1(percent) + cp1.y*b2(percent) + cp2.y*b3(percent) + p2.y*b4(percent) } }; Returning xy coordinates of the point laying on the given percentage of the curve. Bernsteins polynomial at Wikipedia physics forum Bezier at Wikipedia de Casteljau's algorithm is an recursive or iterative algorithm for finding the fixed point and the control point of a given point (percent) on the bezier curve. It does this by calculation tangents and interpolating the controlpoints on the tangent lines. It is way more suitable for splitting a bezier curve as the Bernstein's polynomial only gives a point on the curve, with Casteljau it is relatively easy to return the control points of the split point. below an iterative javascript implementation for splitting a bezier using the de-Casteljau's algorithm // returns an object containing properties b1 & b2 each holding an array representing the either side of the split argument. // be aware that the argument is destructively modified. Call splitBezier(array.slice(0)) if you need to keep the original array. // The argument array is a representation of a quadratic bezier like [controlpoint1, controlpoint2, endpoint] (with points being objects holding x&y properties. // Bezier2Poly.prototype.splitBezier = function(array, perc) { array.unshift({x:0, y:0}); var coll = []; while (array.length > 0) { for (var i = 0;i < array.length-1; i++) { coll.unshift(array[i]); array[i] = this.interpolate(array[i], array[i+1], perc); } coll.unshift(array.pop()); } return {b1: [{x:coll[5].x, y:coll[5].y}, {x:coll[2].x, y:coll[2].y},{x:coll[0].x, y:coll[0].y}] , b2: [{x:coll[1].x - coll[0].x,y:coll[1].y-coll[0].y}, {x:coll[3].x - coll[0].x,y:coll[3].y-coll[0].y}, {x:coll[6].x - coll[0].x,y:coll[6].y-coll[0].y}]}; } Bezier2Poly.prototype.interpolate = function (p0, p1, percent) { if (typeof percent === 'undefined') percent = 0.5; return {x: p0.x + (p1.x - p0.x) * percent , y: p0.y + (p1.y - p0.y) * percent}; } stores all the points of the tangentlines in an array which is returned. Note that the 1-percentage equals the percentage for the parametric bezier version. You can use it like: pts_red = getPoints(perc, [{x:0, y:0}, {x:x1, y:y1}, {x:x2, y:y2}, {x:x3, y:y3}]); pts_blue = getPoints(1-perc, [{x:x3, y:y3}, {x:x2-x3, y:y2-y3}, {x:x1-x3, y:y1-y3}, {x:-1*x3, y:-1*y3}]);
Owner Author