Drag the circles to modify the curve

Catmull-Rom Spline

Splines are a mathematical means of representing a curve. The curve can be defined by series of "Control Points" and a defining a function that allows additional points within an interval to be calculated. There are various functions available to approximate a curve, the Catmull-Rom spline is one of them. What makes the Catmull-Rom spline interesting if that the specified curve will pass through all of the control points - this is not true of all types of splines.


//default setting will just draw a straight line
var _hermiteValues = [ 0, 0, 1, 0 ];

//...

function setResolution( value )
{
    var resolution = 1 / value;

    _hermiteValues = [];

    for( var t = resolution; t <= 1; t += resolution )
    {
        var h00 = (1 + 2 * t) * (1 - t) * (1 - t);
        var h10 = t * (1 - t) * (1 - t);
        var h01 = t * t * (3 - 2 * t);
        var h11 = t * t * (t - 1);

        _hermiteValues.push( h00, h10, h01, h11 );
    }
}

                    

function drawSpline( context, segmentStart, segmentEnd, prevSegmentEnd, nextSegmentStart )
{
    if( !prevSegmentEnd )
    {
        prevSegmentEnd = segmentStart;
    }

    if( !nextSegmentStart )
    {
        nextSegmentStart = segmentEnd;
    }

    var m1 = { x: (segmentEnd.x - prevSegmentEnd.x) / 2, y: (segmentEnd.y - prevSegmentEnd.y) / 2 };
    var m2 = { x: (nextSegmentStart.x - segmentStart.x) / 2, y: (nextSegmentStart.y - segmentStart.y) / 2 };

    var n = _hermiteValues.length;

    for( var i = 0; i < n; i += 4 )
    {
        var h00 = _hermiteValues[ i ];
        var h10 = _hermiteValues[ i + 1 ];
        var h01 = _hermiteValues[ i + 2 ];
        var h11 = _hermiteValues[ i + 3 ];

        var px = h00 * segmentStart.x + h10 * m1.x + h01 * segmentEnd.x + h11 * m2.x;
        var py = h00 * segmentStart.y + h10 * m1.y + h01 * segmentEnd.y + h11 * m2.y;

        context.lineTo( px, py );
    }
}