|
<!DOCTYPE HTML> |
|
<html lang="en"> |
|
<head> |
|
<title>Bezier splitting</title> |
|
<meta charset="utf-8"> |
|
|
|
<script type="text/javascript" |
|
src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"> |
|
</script> |
|
|
|
<script type="text/javascript"> |
|
/** |
|
* @brief De Casteljau's algorithm splitting n-th degree Bezier curve |
|
*/ |
|
function bsplit(points, t0) { |
|
var n = points.length - 1; // number of control points |
|
var b = []; // coefficients as in De Casteljau's algorithm |
|
var res1 = []; // first curve resulting control points |
|
var res2 = []; // second curve resulting control points |
|
var t1 = 1 - t0; |
|
|
|
// multiply point with scalar factor |
|
var pf = function(p, f) { |
|
var res = []; |
|
for(var i = 0; i < p.length; i++) { |
|
res.push(f * p[i]); |
|
} |
|
return res; |
|
}; |
|
// add points as vectors |
|
var pp = function(p1, p2) { |
|
var res = []; |
|
for(var i = 0; i < Math.min(p1.length, p2.length); i++) { |
|
res.push(p1[i] + p2[i]); |
|
} |
|
return res; |
|
}; |
|
|
|
// set original coefficients: b[i][0] = points[i] |
|
for(var i = 0; i <= n; i++) { |
|
points[i] = (typeof points[i] == "object") ? points[i] : [points[i]]; |
|
b.push([ points[i] ]); |
|
} |
|
// get all coefficients |
|
for(var j = 1; j <= n; j++) { |
|
for(var i = 0; i <= (n-j); i++) { |
|
b[i].push( pp( |
|
pf(b[i][j-1], t1), |
|
pf(b[i+1][j-1], t0) |
|
)); |
|
} |
|
} |
|
// set result: res1 & res2 |
|
for(var j = 0; j <= n; j++) { |
|
res1.push(b[0][j]); |
|
res2.push(b[j][n-j]); |
|
} |
|
|
|
return [res1, res2]; |
|
}; |
|
</script> |
|
|
|
<script type="text/javascript"> |
|
var paper; |
|
/** |
|
* @brief example using bsplit |
|
*/ |
|
window.onload = function() { |
|
// load Raphael |
|
paper = Raphael("paper", 1100, 560); |
|
// original Bezier curve |
|
p0 = [0, 0]; |
|
p1 = [1000, 100]; |
|
p2 = [500, 500]; |
|
draw(p0, p1, p2).attr({ |
|
"stroke-width": "3", |
|
"stroke": "#FDD1BD" |
|
}); |
|
// split at 0.3 |
|
var points = bsplit([p0, p1, p2], 0.3); |
|
// part1 split Bezier curve |
|
var curve1 = points[0]; |
|
draw(curve1[0], curve1[1], curve1[2], 50).attr({ |
|
"stroke-width": "3", |
|
"stroke": "#E0AE9F" |
|
}); |
|
// part2 split Bezier curve |
|
var curve2 = points[1]; |
|
draw(curve2[0], curve2[1], curve2[2], 50).attr({ |
|
"stroke-width": "3", |
|
"stroke": "#573E44" |
|
}); |
|
}; |
|
var draw = function(p0, p1, p2, dx, dy) { |
|
dx = (typeof dx == "undefined") ? 0 : dx; |
|
dy = (typeof dy == "undefined") ? 0 : dy; |
|
return paper.path("M "+(p0[0]+dx).toString()+" "+(p0[1]+dy).toString()+ |
|
" Q "+(p1[0]+dx).toString()+" "+(p1[1]+dy).toString()+ |
|
" "+(p2[0]+dx).toString()+" "+(p2[1]+dy).toString() |
|
); |
|
}; |
|
</script> |
|
</head> |
|
|
|
<body style="background: #9B8586;"> |
|
<div id="center"> |
|
<div id="paper"></div> |
|
</div> |
|
</body> |
|
</html> |