Catmull-Rom to Bézier
Drawing a curve through points by interpreting a Bézier curve (for canvas bezierCurveTo) from a Catmull-Rom spline.
HTML
<canvas id="canvas" width="500" height="500"></canvas>
JavaScript
var TWO_PI = Math.PI * 2;
var points = [];
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
function drawPoints(points, ctx) {
ctx.strokeStyle = 'rgba(0,0,0,0.25)';
for (var i = 0, n = points.length, p; i < n; i++) {
p = points[i];
ctx.beginPath();
ctx.arc(p.x, p.y, 3, 0, TWO_PI, false);
ctx.closePath();
ctx.stroke();
ctx.fillText('p' + i, p.x + 6, p.y + 2);
}
}
function generatePoints(list, count) {
for (var i = 0; i < count; i++) {
list.push({
x: (width * 0.1) + Math.random() * (width * 0.8),
y: (height * 0.1) + Math.random() * (height * 0.8)
});
}
}
function curveThroughPoints(points, ctx) {
ctx.beginPath();
var p0, p1, p2, p3, i6 = 1 / 6;
for (var i = 3, n = points.length; i < n; i++) {
p0 = points[i - 3];
p1 = points[i - 2];
p2 = points[i - 1];
p3 = points[i];
if (i === 3) {
ctx.moveTo(p1.x, p1.y);
}
ctx.bezierCurveTo(
(p2.x * i6) + p1.x + (p0.x * -i6),
p2.y * i6 + p1.y + p0.y * -i6,
p3.x * -i6 + p2.x + p1.x * i6,
p3.y * -i6 + p2.y + p1.y * i6,
p2.x,
p2.y
);
}
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(255,0,255,0.8)';
ctx.stroke();
}
generatePoints(points, 10);
curveThroughPoints(points, context);
drawPoints(points, context);