I’ve been trying to untangle the mathematics behind various interpolations and I’ve come across a rather serious issue. It seems that the linear interpolation is implemented incorrectly, at least with the ease in/out interpolation.
As far as I can tell, all interpolations except constant are given by a cubic spline, which is to say that they are governed by the differential equation y’’’’ = 0 (see the topic I linked to for a somewhat more detailed treatment of the subject). The only difference between the interpolations should be the boundary conditions. The linear interpolation has no cubed or squared terms, and so it appears to be implemented slightly differently effectively with the differential equation y’’ = 0 and boundary conditions something like y(0) = y_0, y’(t_f) = (y_f-y_0)/(t_f-t_0). (I’m not sure if this is actually what’s going on “under the hood”, but I’ll show in a moment that something is going wrong.)
We expect that when we use some waypoint at one end and a linear waypoint at the other end, the value should change in a, you know, linear fashion near its final time. How would we model this mathematically? We expect y’’(t_f) = 0.
Is that what we see? In a word, no. I set an ease in/out waypoint at frame 0 with a value of 0 and a linear waypoint at frame 100 with a value of 1 and tabulated the values in Excel (actually LibreOffice Calc). Here’s the resulting graph:
This may not look bad at first glance. The left end certainly reflects the ease in/out waypoint, but a close look at the right end only looks linear-ish. In fact, it looks like it’s tapering off slightly. I confirmed this by graphing the derivative:
Blech. A linear interpolation should produce a constant derivative at its right end. That parabola being graphed should reach its maximum at frame 100.
Here’s what I propose the interpolation should actually look like:
Much better! It’s easing in from the left end and it looks nice and linear at the right end. Let’s also graph the derivative to confirm that this is correct:
Note how the derivative is constant near frame 100, as we would hope.
This latter function was produced by changing the boundary conditions to:
y(0) = 0
y’(0) = 0
y(100) = 1
y’’(100) = 0
That last boundary condition is the only one that was changed. Note that it is now based on the second derivative.
How do we fix this? I’ll be honest: this is a real mess. If we were to suddenly change the linear interpolation, then every animation made before the change with a (something)-linear interpolation will be affected, possibly ruining those animations. I propose the new, correct interpolation be phased in slowly. First, we introduce “new linear” as an interpolation. Then, in a subsequent revision, we relable the current (broken) linear interpolation “legacy linear”. In the following revision, we relabel “new linear” to “linear” and make a warning box pop up warning users whenever they use it that the legacy linear interpolation is being deprecated soon. Finally, some years down the line, we scrap the legacy linear interpolation entirely and leave it to users to correct their animations as necessary.
I can’t seem to remember my credentials for the bug report site, so I kindly ask that someone submit this there. I hope I’ve made it clear that this is a rather serious issue and if you think it’s not a big deal, I’ll try to do a better job of explaining why this is oh-so-very-wrong.
I’m continuing my investigation into other interpolations.