# Easing Functions in Processing

**TLDR: I implemented a more flexible map() function for Processing incorporating
various common easing functions. You can find all the source code over
here on Github.**

In my last post I had made the following image using Cohen-Sutherland line clipping.

To create the above image, I had picked a random angle for the lines in each square and varied the spacing between lines based on the Y-axis location of the square.

Something about the above image bothered me: I wanted more darkness in the
lower half. Unfortunately, Processing’s `map()`

function that I use only does
linear interpolation in the range that it is provided (as far as I know).

So I went ahead and implemented some more options! Here is the same image using
my custom `map()`

replacement (called `map2()`

of course) with a quartic
ease-out to calculate the spacing between
the parallel lines in each grid square, in place of the standard linear mapping. If that doesn’t make any
sense yet, keep reading!

## Processing’s map() Function

Let’s first try to understand how the Processing `map()`

function works. The
`map()`

function translates an input range into an output range linearly.

A simply way to visualize this is to look at a 2D space as shown below, where I’ve used a value between 0 and 100 on the X axis, and map it to a color between white and black on the Y axis.

*A visual representation of Processing’s linear map() function.*

The `map()`

function essentially allows one to “traverse” this space in a
straight line.

The effect of this is shown in the color slider above, where each shade of
gray is represented equally. That is, gray values are uniformly distributed.
Unfortunately, that means that simply sticking with the default `map()`

implementation limits our options. What if we want darker tones
to be represented more with only a quick transition at the end to lighter ones?

Luckily, a straight line through the 2D space shown above is not the only route we can take! In fact, we can take an arbitrary walk through this space to get to our destination. Enter easing functions.

## Easing Functions

The idea behind easing functions is to use a more complex curve rather than a straight line, to traverse the 2D region mapping our input range (on the X axis) to our output range (on the Y axis).

Here is an example of a quartic curve, where the Y-axis values are a function of $x^4$. (This is in contrast to a line which is simply a function of $x$.)

*A visual representation of a sinusoidal easing function.*

### Understanding the Visualization

Let’s try to understand what is going on in the above animation a bit more.

First, the animation shows three curves, which correspond to different types
of *easings* or transitions. The red curve shows *easing in*, where it starts
out slowly and then speeds up to the final speed. You can see this if you
look at the Y position of the red dot as the slider below moves at a fixed
speed. It stays for a while in the lower part and only later jumps up to the
upper area.

The green curve shows *easing out*, which is the opposite of easing in. The
green dot moves through the output range (the Y position) very quickly in
the beginning but slows down once it reaches the upper regions.

Finally, the blue curve shows a *combined easing in and out*. In this case,
the initial and final parts of the range are traversed slowly, with only
the middle region being fast.

### Easing Functions & Color Distribution

In the animation above, the three bars at the bottom capture the Y value of the curve (in the form of a gray value) as a function of the X value (the position of the slider).

What we see is that **easing in stays primarily in the lighter regions**.

In contrast, **easing out stays primarily in the darker regions**.

Finally, **combined easing in and out results in a lot of light and dark with very
little mid-tone**.

This way, we can play with the curves and easings to achieve the right distribution of the output range (in this case, gray values) that we want.

## A Better map() Replacement

I’ve gone ahead and implemented a set of easing functions (see Robert Penner’s easing equations here)
in Processing within a new `map2()`

function. The function takes two
more arguments compared to the standard Processing `map()`

function.

The first is the easing type and is one of `LINEAR`

, `SINUSOIDAL`

, `QUADRATIC`

, `CUBIC`

, `QUARTIC`

,
`QUINTIC`

, `EXPONENTIAL`

, `CIRCULAR`

, and `SQRT`

.

The second is a parameter specifying where to apply the easing, and is one of
`EASE_IN`

, `EASE_OUT`

, and `EASE_IN_OUT`

.

```
/* Old map() function */
map(value, 0, 100, 0, 255);
/* New map2() function */
map2(value, 0, 100, 0, 255, QUADRATIC, EASE_IN_OUT);
```

## SINUSOIDAL to EXPONENTIAL Easing

From the easing functions mentioned above, the **curves become steeper and steeper**
as we go through the sequence `SINUSOIDAL`

–> `QUADRATIC`

–> `CUBIC`

–> `QUARTIC`

–>
`QUINTIC`

–> `EXPONENTIAL`

. The animations for the first and last one are
shown below for comparison.

You can clearly see that under the `EXPONENTIAL`

easing (right side) the dots spend more time in the extremes and move very quickly through
the middle areas, while it is more gentle in the case of the `SINUSOIDAL`

easing (left side).

What this means for our visualization is that the colors that you will primarily
see in the case of our exponential easing are either very light or very dark
(depending on where you apply the easing), with a relatively sharp transition
and very few mid-tones.
The sinusoidal easing on the other hand is more gentle in its transitions.
This is particularly evident when looking at the middle
region of the blue `EASE_IN_OUT`

bar.

## LINEAR and CIRCULAR Easing

The `LINEAR`

easing function is equivalent to the standard `map()`

function
provided by Processing, while ** CIRCULAR easing is relatively gentle** when
only easing in or out, but

**very sharp in the middle region when combining easing in and out**.

## SQRT and Polynomial Easing

So far, we’ve seen that as we go from `SINUSOIDAL`

to `EXPONENTIAL`

, the focus
is removed more and more from the middle regions and pushed towards the extremes.
What if we want to do the opposite? That is, emphasize the mid-tones and de-emphasize
the extreme lights and darks?

This is where the `SQRT`

easing function comes in. Below is the `SQRT`

animation
(left) compared with a `QUADRATIC`

animation (right). You can see that it’s
basically flipped, and the dots stay for a longer time in the middle region
in the case of `SQRT`

. The resulting bars show the contrast between the two.

Finally, we can generalize this to a mapping where you specify what power the
X variable is raised to. This allows us to have even stronger focus on the
mid-tones using an exponent less that one. I’ve implemented a `map3()`

function
that allows this. Here are two examples with an exponent of `0.3`

(left) and `0.1`

(right).

Notice how the focus in the bars has changed almost entirely towards the mid-ranges and de-emphasize the extremes.

## Concluding Thoughts

Easing functions provide a lot of control over the distribution of values of
your output range. I started with my example of using it to create more darks
for the image below: I used a quartic ease-out to map the spacing between
the parallel lines in each grid square instead of the
standard linear `map()`

function. All of that should make sense to you now!

If you’re interested in learning more, you should check out the following video recommended to me by Benjamin Kovach:

You can find all the source code for the easing functions in Processing over here on Github