Parametric Curves

Easing functions are an immensely useful tool for animators. They are very handy when we want to spice up an animation and give it an extra cool or polished look, and are incredibly simple to implement in code.

The main idea is that you have a starting point A and an ending point B, and you want something to move from A to B along a (not necessarily straight) path connecting both points.

However, the path between the points is not the only thing to consider: there’s also how the object will traverse this path, how fast it’ll move at each point, how it will accelerate, etc.

What we are looking for is a uniform “speed” parameterization of the path, that is, we want a function f(t) that returns a point in space along the path. The function is built so f(t=0) gives us the starting point and f(t=1) gives us the ending point. Additionally, for equally spaced values of t in the unit interval [0,1], we want equally spaced points along the path.

Unit speed parameterization of curves is not a trivial thing, but for a straight line path using linear interpolation — which is by far the most common — it is very straightforward: we don’t have to do anything. It is already uniform in speed!

This is where easing functions come in. The easing function e(t) takes an input value t, from 0 to 1, and returns a new value, not necessarily from 0 to 1 (to account for overshoots). The only constraint is is that e(0) = 0 and e(1) = 1. The value returned by the easing function is what we use to get the current position along the path.

In math terms, if our path is given by f(t) and our easing function is e(t), we’ll use f(e(t)) in our animation code.

In the animation above, you see the result of using several different easing functions on a simple linear path.

The horizontal value of each graph is the t time parameter, and the vertical value is the value returned by e(t). The box delimits the interval from [0,1] in both directions.

Shown at right of each graph is the movement you get with this easing function. You can see that even the slightest variation from the super-lame straight line (top left) is already much nicer to look at.

The functions shown here were all custom made, and are part of my personal animation library. Linear, power and sine are found everywhere, and are the most basic ones.

Most libraries also include “elastic” and “bounce”, among others, but these are always fixed Bézier curve or polynomial approximations, which are pretty bad since you can’t fine-tune them to your needs. So I wrote my own.

The trade off for being totally tunable is that they are not optimized for real time, but that isn’t an issue for me.

You’ll also notice that I haven’t included ease-in and ease-out separately. I find it mostly useless. I’ve never seen anyone using “elastic/bounce ease in”, for instance, and I hope it has never been used by anyone. It looks like garbage, as you can see when the animations run backwards.

In any case, creating mixed functions from these is very easy, just a matter of acting in reverse on half the interval, and subtracting the function from 1 for the ease-in parts.

POWER

This is usually found in three flavors out there: quad(tratic), cubic and quart(ic). I decided to just wrap them all in the same thing, as it’s the same construction, except using different powers

The idea is to use a variation of tp and its reflection to create the ease-in and ease-out bits.

In particular, you have (2t)p/2 for t in [0,0.5] and 1 - (2(1-x))p/2 (non-expanded for clarity) for t in (0.5,1]. All values p > 0 are well-behaved in the unit interval.

SINE

This one is just simply sin(t·π/2)2. You can easily get rid of that power using the familiar identity, but it looks cleaner this way.

BOUNCE

The bounce one is based on the actual physics of parabolic motion. It is tuned by two parameters: decay power and number of times it hits the ground. This means you can set, precisely, how many times you want it to bounce around, and you can fine tune how sharply it will lose energy after each bounce.

I usually avoid using exponential decay on its own because it doesn’t reach zero exactly at the end of the interval, which is usually more desirable than physically accurate decay rates. So I tend to use a factor of (1-t)p for decays in general. It offers more freedom anyway.

PHYSICAL

Most libraries include “elastic” and “back” (which overshoots a bit). They look all right, but are not accurate models of physical motion, and you can’t fine tune them much.

My “physical” easing function replaces both with a solution for dampened harmonic oscillation, where you can manually set the decay rate and frequency of oscillation. This means you can have exactly as many back-and-forth motions as you want. The exponential decay rate was also replaced by the more malleable (1-t)p expression.

Using frequencies like 1 or 0.5 gives you a replacement for the “back” easing in other libraries, with the benefit of tuning. Frequencies that are not multiples of 1/2 tend to look bad, but thanks to the decay function they still end up at 1 no matter what.

UNIFORM

This is one of the most useful ones, and something like it is lacking everywhere I looked. In a lot of situations, it is desirable to have a “mostly linear” movement, with a steady speed in the middle of it. The biggest problem with linear interpolation is the ending points. Having the object static and suddenly starting to move looks jarring and unrealistic.

The “uniform” easing I came up with is a way of keeping the best of both worlds: you can tune how much of the path will be linear, and how much of the remaining will be used by acceleration/deceleration. You can also tune how aggressive acceleration/deceleration will be.

Due to its almost-linear nature, it works exceptionally well with other easing functions. This is shown in the last one (bottom right), where I used it along with the bounce function to give it an extra anticipation in both ends. It makes the bounce feel heavier. Looks pretty good!

Can you release these functions somewhere?

I will write a detailed post about each of them along with pseudocode if there’s enough interest. Since these functions aren’t meant to be used in real time applications, they are not ready to be used in a lot of contexts out there with a lot of moving objects. It would be pretty easy to cache these and make it super fast during run time, though.

However, most people seem to be happy enough with their easing libraries, so I’m not sure if it’s worth the trouble, nor if tumblr is the best way to go about it.

So if you are interested, please drop me a request so I know I won’t be wasting time posting them here.

Pi’s parametric coordinate functions

This is the second of three animations I’ll be posting today (here’s the first). Be sure to check them out later if you miss them!

The polygonal trigonometric functions I described earlier were based on the interior angle, instead of the length along the polygon’s border.

This simplified things a lot, and created some interesting uses for the functions. However, since I could only have one value of radius for each angle (they were based on polar equations), I could not draw arbitrary shapes with a continuous line based on the [0,2π] interval.

The solution is to extend the idea to general closed curves, by using the position along the curve to define the sine and cosine analogues. In other words, we want “path trigonometric functions” for which the input parameter is the position along the path, and whose periods are the curve’s total arc-length.

But the concept of “sine” and “cosine”, as well as “trigonometric”, completely lose their meaning at this point. It has nothing to do with triangles or angles.

We’re now dealing with the functions x(s) (in blue) and y(s) (in red) that together describe the curve, by being used in the parametric equation r(s) = ( x(s) , y(s) ), where r(s) is a vector function and s is the arc-length. This is very standard stuff, so it isn’t incredibly exciting anymore.

Notice that if the green curve was a unit circle, the functions would become the usual sine and cosine.

But we do get to see what these functions look like and what they are doing. So here’s the coordinate functions for the arc-length parametrization of a pi curve!

Happy Pi day!


Manipulate[ParametricPlot3D[ {Cos[\[Pi] \[Alpha] (3 - \[Alpha] - (-1 + \[Alpha]) Cos[\[Pi] Cos[ x + y]])] Sin[x] + Cos[y] Sin[\[Pi] \[Alpha] (3 - \[Alpha] - (-1 + \[Alpha]) Cos[\ \[Pi] Cos[x + y]])], Cos[\[Pi] Cos[x + y]], Cos[y] Cos[\[Pi] \[Alpha] (3 - \[Alpha] - (-1 + \[Alpha]) \ Cos[\[Pi] Cos[x + y]])] - Sin[x] Sin[\[Pi] \[Alpha] (3 - \[Alpha] - (-1 + \[Alpha]) Cos[\ \[Pi] Cos[x + y]])]}, {x, 0, 2 \[Pi]}, {y, 0, 2 \[Pi]}, PerformanceGoal -> Quality], {\[Alpha], 0, 1} ]



music: abby lee tee / speechless affairs / side b

Happy Pi day!

This is just the first post for today. There’ll be two more, so be sure to check them out later if you miss them!

Here’s an arc-length parametrization of a closed curve for the Greek lowercase letter pi, famously used for the circle constant, π = 3.1415926535897932384626… (that’s what I bothered memorizing!)

Arc-length parametrizations are also called unit-speed parametrizations, because a point moving along the path will move with speed 1: the point moves 1 unit of arc-length per 1 unit of time.

It is generally very hard, if not impossible, to find this parametrization in closed form. But it always exists for nice continuous curves. Since it has some pretty cool uses, just knowing it exists is a powerful enough tool for mathematicians to use it on other cool theorems.

Using computers, we can usually approximate it numerically to any degree of accuracy we desire. The basic algorithm is pretty simple: just make a table of arc-length for each value of t. Then, the unit parametrization is just reading the table in reverse: find t given arc-length. Some interpolation is usually necessary.

3

The image is not mine. It is a fantastic creation by bigblueboo that has caught some attention outside of the usual math tumblverse. You should definitely check out eir blog and if you like this post you should (also?) reblog the original. With that out of the way:

Classical mechanics. Mechanics is the oldest subfield of physics, concerned with predicting the movement of objects in simple systems. “Classical” in the physical sense is a word used to mean that there is no consideration of relativistic or quantum effects. Modern mechanics borrows heavily from the tools developed by analysis, and introductory calculus classes tend to teach the tools that physicists find useful for mechanics.

In lieu of a mathematical definition, I’ll let you in on a little secret: Wolfram Alpha is the website your high school math teachers hoped you didn’t know about.

bigblueboo’s image happens to be an excellent source of mathematical content: this post is part three of an ongoing series as I discover some of its secrets. In the first post you can see a derivation of its symbolic equations of motion, and part two contains a sweet characterization. This post quantifies the result of the third post, which explains that the non-constant speed in the gif is not (entirely) a result of the viewing angle.

I have one more post of material mostly written before I officially end the series, and a couple more questions that I want to answer but will probably not be able to churn out in two days apiece. Maybe I’ll think of some more questions and do a “future work” post.

vimeo

Powerless Structure