imj-base-0.1.0.2: Game engine with geometry, easing, animated text, delta rendering.

Safe Haskell Safe Haskell2010

Imj.Graphics.Math.Ease

Synopsis

# 4th order inverse easing, continuous

Easing is traditionally seen as a function from time to value.

Here, it is a function from value to time, hence the use of the term Inverse in the title.

Arguments

 :: Float Value : $$y$$ -> Float Time : $$t$$

Returns the time $$t \in [\,0,1]\,$$ at which a value $$y \in [\,0,1]\,$$ is reached given a 4th order ease in-out function $$quartEaseInOut$$:

$y = quartEaseInOut(t) = \begin{cases} {1 \over 2} * (2*t)^4, & \;\;\;\; \text{if t < {1 \over 2}} \\[2ex] -{1 \over 2} * \left( [ 2*(t-1) ]^4 - 2 \right), & \;\;\;\; \text{if t > {1 \over 2}} \end{cases}$

To find the formulas of invQuartEaseInOut, we need to invert $$quartEaseInOut$$, i.e. we need to express $$t$$ in terms of $$y$$:

$\text{quartEaseInOut is strictly increasing} \implies \begin{cases} t<{1 \over 2} \iff y<{1 \over 2} \\ t>{1 \over 2} \iff y>{1 \over 2} \end{cases}$

\begin{alignedat}{3} \text{if y < {1 \over 2} , given the quartEaseInOut equation for t < {1 \over 2}  :} && y &= {1 \over 2} * (2*t)^4 && \\ \implies && \quad t &= \left({y \over 2^3}\right)^{1/4} && \quad \forall y < {1 \over 2} \\ \text{if y > {1 \over 2} , given the quartEaseInOut equation for t > {1 \over 2}  :} && y &= - {1 \over 2} * \left( [2*(t-1)]^4 - 2 \right) && \\ \implies && \quad t &= 1-\left[{1-y \over 2^3}\right]^{1/4} && \quad \forall y > {1 \over 2} \end{alignedat}

Note that there are multiple solutions, we chose the ones that produce results in the $$[\,0,1]\,$$ range.

Hence, the formulas for invQuartEaseInOut are :

$t = invQuartEaseInOut(y) = \begin{cases} \left({y \over 2^3}\right)^{1/4}, & \text{if y < {1 \over 2}} \\[2ex] 1-\left[{1-y \over 2^3}\right]^{1/4}, & \text{if y > {1 \over 2}} \end{cases}$

# From continuous to discrete

Easing in a continuous world is easy (no pun intended), but easing in a discrete world is harder : we have to make sure the discretization will not break the visual easing effect.

The discreteAdaptor function does just that, making a continuous easing function usable in a discrete context.

Arguments

 :: (Float -> Float) Continuous (optionally inverse) ease in/out function -> Int The number of discrete steps -> Float Input value -> Float (optionnaly inverse) Eased value

Adapts continuous inout ease functions to the discrete case.

# 4th order inverse easing, discrete

Using discreteAdaptor on invQuartEaseInOut we can make discreteInvQuartEaseInOut :

Arguments

 :: Int The number of discrete steps -> Float Value -> Float Time

Returns the time (in range [0 1]) at which a value (in range [0 1]) is reached given a 4th order ease in-out function, and a total number of discrete steps.