2 added 3 characters in body
source | link

To do that, all you needHere's code to docalculate the velocity at any particular point of the spline: (This is to takejust the derivative of the calculation above. To save you from that effort, here's pseudocode that I prepared earlier: calculation)

With thatSo with the information from these two functions, you can seamlessly change from one interpolation to another. Whenever you interrupt a transition with a new one, begin the new one using the item's current position and velocity (as determined by the two functions above), set 'end' to the new desired endpoint, and set endVelocity to 0 if you want an "ease-out", or to whatever other velocity you want the item to have at the end of the motion. (end-start is often a reasonable choice, if you don't want ease-out on the motion)

To do that, all you need to do is to take the derivative of the calculation above. To save you from that effort, here's pseudocode that I prepared earlier:

With that information, you can seamlessly change from one interpolation to another. Whenever you interrupt a transition with a new one, begin the new one using the item's current position and velocity (as determined by the two functions above), set 'end' to the new desired endpoint, and set endVelocity to 0 if you want an "ease-out", or to whatever other velocity you want the item to have at the end of the motion. (end-start is often a reasonable choice, if you don't want ease-out on the motion)

Here's code to calculate the velocity at any particular point of the spline: (This is just the derivative of the above calculation)

So with the information from these two functions, you can seamlessly change from one interpolation to another. Whenever you interrupt a transition with a new one, begin the new one using the item's current position and velocity (as determined by the two functions above), set 'end' to the new desired endpoint, and set endVelocity to 0 if you want an "ease-out", or to whatever other velocity you want the item to have at the end of the motion. (end-start is often a reasonable choice, if you don't want ease-out on the motion)

1
source | link

A standard "tween" algorithm usually works by simplifying a more general hermite spline function, to eliminate the necessity of manually providing initial and terminating velocity values.

But if you wish to be able to switch from one tween to another, you can no longer do that, and you'll need to use a full, non-simplified spline calculation.

Here's some pseudocode which will work for floats or mathematical vectors (substitute 'type' for whatever value type you're interpolating between):

type SplineValueAtTime( float t, type start, type startVelocity, type end, type endVelocity )
{
    float tSquared = t * t;
    float tCubed = tSquared * t;

    float a = 2.f * tCubed - 3.f * tSquared + 1.f;  // 2t^3 - 3t^2 + 1
    float b = tCubed - 2.f * tSquared + t;          // t^3 - 2t^2 + t
    float c = -2.f * tCubed + 3.f * tSquared;       // -2t^3 + 3t^2
    float d = tCubed - tSquared;                    // t^3 - t^2

    type result = (a * start) +
                  (b * startVelocity) +
                  (c * end) +
                  (d * endVelocity);

    return result;
}

The code above calculates a spline with the specified start, end, and velocities at each end. 't' is assumed to vary in the range [0..1]. (If 'startVelocity' and 'endVelocity' are both zero, then this math simplifies down into the standard hermite interpolator, start + ((3*t*t-2*t*t*t) * end-start))

Now all you need is to be able to figure out the object's current velocity at the time when it changes its interpolation target, so that you can create a new interpolation spline starting from its current position and velocity, and ending up at the desired new location.

To do that, all you need to do is to take the derivative of the calculation above. To save you from that effort, here's pseudocode that I prepared earlier:

type SplineVelocityAtTime( float t, type start, type startVelocity, type end, type endVelocity )
{
    float tSquared = t * t;

    float a = 6.f * tSquared - 6.f * t;             // 6t^2 - 6t
    float b = 3.f * tSquared - 4.f * t + 1;         // 3t^2 - 4t + 1
    float c = -6.f * tSquared + 6.f * t;            // -6t^2 + 6t
    float d = 3.f * tSquared - 2.f * t;             // 3t^2 - 2t

    type result = (a * start) +
                  (b * startVelocity) +
                  (c * end) +
                  (d * endVelocity);

    return result;
}

With that information, you can seamlessly change from one interpolation to another. Whenever you interrupt a transition with a new one, begin the new one using the item's current position and velocity (as determined by the two functions above), set 'end' to the new desired endpoint, and set endVelocity to 0 if you want an "ease-out", or to whatever other velocity you want the item to have at the end of the motion. (end-start is often a reasonable choice, if you don't want ease-out on the motion)

Hope that helps!