Function CubicSpline

Summary

#include <Source/Falcor/Utils/Math/CubicSpline.h>

(1) CubicSpline(const T *controlPoints, uint32_t pointCount)

(2) CubicSpline(const T *points, uint32_t pointCount, float const *durations)

Function overload

Synopsis

#include <Source/Falcor/Utils/Math/CubicSpline.h>

CubicSpline(const T *controlPoints, uint32_t pointCount)

Description

Creates a position-based cubic spline.

Parameters:

[ in ] controlPoints - Array of control points

[ in ] pointCount - Number of control points

Source

Lines 40-87 in Source/Falcor/Utils/Math/CubicSpline.h.

CubicSpline(const T* controlPoints, uint32_t pointCount)
{
    // The following code is based on the article from http://graphicsrunner.blogspot.co.uk/2008/05/camera-animation-part-ii.html
    static const T kHalf  = T(0.5f);
    static const T kOne = T(1);
    static const T kTwo = T(2);
    static const T kThree = T(3);
    static const T kFour = T(4);
    // Calculate Gamma
    std::vector<T> gamma(pointCount);
    gamma[0] = kHalf;
    for(uint32_t i = 1; i < pointCount - 1; i++)
    {
        gamma[i] = kOne / (kFour - gamma[i - 1]);
    }
    gamma[pointCount - 1] = kOne / (kTwo - gamma[pointCount - 2]);
    // Calculate Delta
    std::vector<T> delta(pointCount);
    delta[0] = kThree * (controlPoints[1] - controlPoints[0]) * gamma[0];
    for(uint32_t i = 1; i < pointCount; i++)
    {
        uint32_t index = (i == (pointCount - 1)) ? i : i + 1;
        delta[i] = (kThree * (controlPoints[index] - controlPoints[i - 1]) - delta[i - 1]) * gamma[i];
    }
    // Calculate D
    std::vector<T> D(pointCount);
    D[pointCount - 1] = delta[pointCount - 1];
    for(int32_t i = int32_t(pointCount - 2); i >= 0; i--)
    {
        D[i] = delta[i] - gamma[i] * D[i + 1];
    }
    // Calculate the coefficients
    mCoefficient.resize(pointCount - 1);
    for(uint32_t i = 0; i < pointCount - 1; i++)
    {
        mCoefficient[i].a = controlPoints[i];
        mCoefficient[i].b = D[i];
        mCoefficient[i].c = kThree * (controlPoints[i + 1] - controlPoints[i]) - kTwo * D[i] - D[i + 1];
        mCoefficient[i].d = kTwo * (controlPoints[i] - controlPoints[i + 1]) + D[i] + D[i + 1];
    }
}

Synopsis

#include <Source/Falcor/Utils/Math/CubicSpline.h>

CubicSpline(const T *points, uint32_t pointCount, float const *durations)

Description

Create a position and time-based cubic spline

Parameters:

[ in ] controlPoints - Array of control points

[ in ] pointCount - Number of control points

[ in ] durations - Array containing durations/intervals for each control point

Source

Lines 94-137 in Source/Falcor/Utils/Math/CubicSpline.h.

CubicSpline(const T* points, uint32_t pointCount, float const* durations)
{
    // The following code is based on the article from http://graphicsrunner.blogspot.co.uk/2008/05/camera-animation-part-ii.html
    // http://math.stackexchange.com/questions/62360/natural-cubic-splines-vs-piecewise-hermite-splines
    // https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm
    if (pointCount >= 2)
    {
        mCoefficient.resize(pointCount);
        // Calculate Gamma =: mCoefficient.a
        mCoefficient[0].a = T(.5f);
        for (size_t i = 1; i < pointCount - 1; i++) {
            mCoefficient[i].a = durations[i] / (T(2.f) * (durations[i - 1] + durations[i]) - durations[i - 1] * mCoefficient[i - 1].a);
        }
        mCoefficient[pointCount - 1].a = 1.0f / (T(2) - mCoefficient[pointCount - 2].a);
        // Calculate Delta =: mCoefficient.b
        mCoefficient[0].b = T(3) / durations[0] * (points[1] - points[0]) * mCoefficient[0].a;
        for (size_t i = 1; i < pointCount - 1; i++) {
            mCoefficient[i].b = (T(3) / (durations[i - 1] * durations[i]) * (
                durations[i - 1] * durations[i - 1] * (points[i + 1] - points[i])
                + durations[i] * durations[i] * (points[i] - points[i - 1])
                )
                - durations[i - 1] * mCoefficient[i - 1].b) * mCoefficient[i].a / durations[i];
        }
        mCoefficient[pointCount - 1].b = (T(3) / durations[pointCount - 2] * (points[pointCount - 1] - points[pointCount - 2]) - mCoefficient[pointCount - 2].b) * mCoefficient[pointCount - 1].a;
        // Calculate D := mCoefficient.d
        mCoefficient[pointCount - 1].d = mCoefficient[pointCount - 1].b;
        for (size_t i = pointCount - 1; i-- > 0;) {
            mCoefficient[i].d = mCoefficient[i].b - mCoefficient[i].a * mCoefficient[i + 1].d;
        }
        // Calculate actual spline
        for (size_t i = 0; i < pointCount - 1; i++) {
            mCoefficient[i].a = points[i];
            mCoefficient[i].b = mCoefficient[i].d * durations[i];
            mCoefficient[i].c = T(3) * (points[i + 1] - points[i]) - T(2) * mCoefficient[i].d * durations[i] - mCoefficient[i + 1].d * durations[i];
            mCoefficient[i].d = T(2) * (points[i] - points[i + 1]) + mCoefficient[i].d * durations[i] + mCoefficient[i + 1].d * durations[i];
        }
        mCoefficient.resize(pointCount - 1);
    }
}





Add Discussion as Guest

Log in to DocsForge