Corona Quick Thought – more on easing functions

A follow-up as prequel to the previous quick thought (regarding Robert Penner’s easing equations in Corona)

This is just intended as some casual/beginner “background material” on easing, maybe (?) helpful if you might be exploring/creating your own curves at some point.

Let’s take a step back, and ask: what IS easing? Essentially, it’s just a linear interpolation, where the interpolation factor (typically as “t”) has been “tweaked” so that it now has a non-linear response curve.

Let’s consider basic linear interpolation, which is often formulated so:

Where “a” is the initial value, “b” is the target value, and “t” is the parameter on [0..1]. When t==0, a is returned; when t==1, b is returned; when t is some intermediate value, the corresponding intermediate value is returned.

(Aside: The “(b-a)” portion is the “delta” between target and initial values. Often in animation system usage, as with Corona’s implementation, you’ll find the delta pre-calculated instead of passing the target value. Both approaches are equivalent.)

Let’s now “tweak” our lerp function to allow for easing:

So far, not very exciting. All we’ve done is add a “wrapper” around t to potentially allow for it to be altered. Our easing function will take an input value on [0..1] and return a potentially reshaped output value, again on [0..1]. Right now, all we have is a return of the original value, again producing a linear response.

Here’s the input/output curve of our current easing function:

Linear

Again, not yet very exciting. So let’s alter the easing function slightly:

Which now produces a quadratic response that looks this this:

inQuadratic

This curve, when used in an animation system, will cause slower initial movement, gradually speeding up until reaching the target at a more rapid velocity.

We can exaggerate that effect even further by simply using a cubic function (t*t*t). (or even higher order quartic, quintic, sextic/hexic, septic/heptic, etc – though there comes a point of diminishing returns for practical usage)

So far I’ve been presenting just the “in” response curve, but I’ll switch to the in/out response curves below, as I think it’s helpful to start visualizing the symmetry.

CubicSymmetry

See the code in the previous quick thought for implementation details on how the symmetry was accomplished for the in/out curve.

Essentially, the diagonal symmetry of the out curve is achieved by inverting both axes (tin and tout) using 1-easing(1-t). Then the in/out curve is achieved by scaling the in curve into the lower-left quadrant, and scaling/translating the out curve into the upper-right quadrant.

Now let’s look at the “Back” family of curves, as implemented in the previous article, which have an initial “overshoot” (or “undershoot”, depending on your perspective) resulting from differencing a polynomial of one degree from another polynomial of a different degree. That curve looks like this (when s==2.6):

CubicOvershootSymmetry

This curve is a pretty good basis for further exploration, as it has “just enough” complexity to inspire further modifications, yet not so much complexity that it hinders comprehension.

The most obvious tweak has already been addressed: alter the relative scaling between two polynomials by introducing a user-adjustable constant (“s”).

Perhaps the next most “obvious” experiment would be to change the degrees of the polynomials. For example, consider this function:

Producing this response curve:

QuadraticUndershootSymmetry

Having the animation effect of quickly moving to a bit more than halfway, then backing off a bit, then continuing on to the final value. A sort of “briefly unsure”, “moment of doubt”, “hesitant” or “reluctant” motion, if we anthropomorphize it. (as if it were saying: “Wait, did I leave the oven on at home? I’d better go back and check. No, no… I’m sure I turned it off – now I’d better hurry to make up for lost time!” :D)

You can insert that equation into the icurve() function of the prior article if you’d like to tinker further. (and, again, you can adjust the degree of overshoot by adjusting “s” to suit)

All for now.

Corona Quick Thought – a custom inOutBack easing function

I was reminded by a recent post in the forum that the calling convention for Corona’s easing functions isn’t well-documented. It’s fairly easy to “reverse-engineer” by experimenting, if you’re at all familiar with Robert Penner’s easing equations, and doing so will allow you to potentially create your own custom easing formulae.

At some point the subject should be treated with more depth, but I’m not feeling particularly ambitious today. 😀 So without further ado, here’s the aforementioned function:

Note that this function probably doesn’t exactly duplicate Corona/Penner, so I renamed it to avoid “claiming” that it did. Still, it’s mathematically very similar.

For readability, I’ve left it unoptimized to reveal its internal workings and 2t^3-t^2 origin — you can refactor and optimize further as you like. As written, it’s (intended to be) useful as a test-bed for developing new curves – just alter the icurve() function. Once you understand how all the “parts” work together, then you can inline all those unnecessary function calls.

The component in and out curves are in there as well, so if you don’t want the inOut version then just replace the call to iocurve() in the return statement with either icurve() or ocurve(). (or create separate versions of all three)

Test it like this:

Now, for the fun part: See that “s = 2.6” in there? That’s what controls “how much” overshoot occurs, and the 2.6 gives it about a 10% overshoot. If you’d like less overshoot, then reduce the value of s; if you’d like more overshoot, then increase the value of s.