You are currently viewing the GMLscripts.com static mirror. Forum access and script submissions are not available through this mirror.

Invert GMLscripts.com

spline

A Catmull-Rom spline interpolates smoothly between knot[1] and knot[n-2], where n is the number of knots. Because the spline is a cubic polynomial, there must be at least four knots. See spline4 for a version optimized for four knots.

Wikipedia: The curve is named after Edwin Catmull and Raphie Rom. In computer graphics, Catmull-Rom splines are frequently used to get smooth interpolated motion between key frames. For example, most camera path animations generated from discrete key-frames are handled using Catmull-Rom splines. They are popular mainly for being relatively easy to compute, guaranteeing that each key frame position will be hit exactly, and also guaranteeing that the tangents of the generated curve are continuous over multiple segments.

spline

spline(t, knotlist)
Returns the Catmull-Rom interpolation of the given knot values at the given parameter position.
COPY/// @func   spline(t, knotlist)
///
/// @desc   Returns the Catmull-Rom interpolation of the given
///         knot values at the given parameter position.
///
///         If (t) is 0, returns knot[2], if (t) is 1, returns knot[N-1],
///         (where 1 is the first knot and N is the last knot). For other
///         values of (t), interpolates smoothly from knot[2] to knot[N-1].
///         The first and last knots determine the derivatives of the spline
///         end points. Because the spline is a cubic polynomial, there must
///         be at least four knots.
///
/// @param  {real}      t           interpolation parameter [0..1]
/// @param  {list}      knotlist    ds_list of spline knot values
///
/// @return {real}      value on the spline
///
/// GMLscripts.com/license

function spline(t, knotlist)
{
    var nknots, nspans, span, k, c3, c2, c1, c0;
    nknots = ds_list_size(knotlist);
    nspans = nknots - 3;
    if (nspans < 1) return 0; // ERROR: too few knots
    t = clamp(t, 0, 1) * nspans;
    span = floor(t);
    if (span >= nknots - 3) span = nknots - 3;
    t -= span;
    k[0] = ds_list_find_value(knotlist,span);
    k[1] = ds_list_find_value(knotlist,span+1);
    k[2] = ds_list_find_value(knotlist,span+2);
    k[3] = ds_list_find_value(knotlist,span+3);
    c3 = -0.5 * k[0] + 1.5 * k[1] - 1.5 * k[2] + 0.5 * k[3];
    c2 = k[0] - 2.5 * k[1] + 2 * k[2] - 0.5 * k[3];
    c1 = -0.5 * k[0] + 0.5 * k[2];
    c0 = k[1];
    return ((c3 * t + c2) * t + c1) * t + c0;
}

Contributors: xot

GitHub: View · Commits · Blame · Raw