cleak's picture

Catmull-Rom interpolation for vectors

Project:The Open Toolkit library
Version:1.x-dev
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:open
Description

Hi,

I'd like to see Catmull-Rom interpolation support added to the vector classes. It would help with animation interpolation as well as adding some XNA compatibility. Below is an implementation I made which produces results that look correct and appear compatible with XNA. As mentioned in http://www.opentk.com/node/2419, I'd like to see (and am willing to implement) a static generic helper class that can implement this and similar functionality.

        /// <summary>
        /// Interpolates values using Catmull-Rom.
        /// </summary>
        /// <param name="value1">The first value of interpolation, which is outside of the knot interval.</param>
        /// <param name="value2">The second value of the interpolation, which is the lower bound of the knot interval.</param>
        /// <param name="value3">The third value of the interpolation, which is the upper bound of the knot interval.</param>
        /// <param name="value4">The fourth value of the interpolation, which is outside of the knot interval.</param>
        /// <param name="t">The knot value in the range [0, 1].  0 returning value2, 1 returning value3, and (0, 1) returning an intermediate value.</param>
        /// <returns>The interpolated point.</returns>
        public static Vector2 CatmullRom(Vector2 value1, Vector2 value2,
            Vector2 value3, Vector2 value4, float t)
        {
            // Tangents for value2 and value3
            Vector2 tan1 = (value3 - value1) / 2.0f;
            Vector2 tan2 = (value4 - value2) / 2.0f;
 
            // Powers of t
            float t2 = t * t;
            float t3 = t2 * t;
 
            float f1 = 2 * t3 - 3 * t2 + 1;
            float f2 = -2 * t3 + 3 * t2;
            float f3 = t3 - 2 * t2 + t;
            float f4 = t3 - t2;
 
            Vector2 point = value2 * f1 + tan1 * f3;
            point += value3 * f2 + tan2 * f4;
 
            return point;
        }