interpolated 0.1.2

Generic, smooth value interpolation and easing functions for Rust.
Documentation
//! Easing functions for interpolation.
//!
//! An easing function maps a normalized time \(t \in [0,1]\) to an eased
//! ratio in \([0,1]\), allowing for custom animation curves.

use std::f32::consts::PI;

/// A function that maps \(t \in [0,1]\) to an eased ratio in \([0,1]\).
pub type EasingFn = fn(f32) -> f32;

/// “No animation” (always jump to the end).
///
/// # Examples
///
/// ```rust
/// use interpolated::none;
/// assert_eq!(none(0.5), 1.0);
/// ```
#[inline]
pub fn none(_: f32) -> f32 {
    1.0
}

/// Linear easing.
///
/// Maps \(t\) to \(t\) unchanged.
///
/// # Examples
///
/// ```rust
/// use interpolated::linear;
/// assert_eq!(linear(0.3), 0.3);
/// ```
#[inline]
pub fn linear(t: f32) -> f32 {
    t
}

/// Ease in/out exponential.
///
/// Accelerates until halfway, then decelerates for smooth transitions.
///
/// # Examples
///
/// ```rust
/// use interpolated::ease_in_out_expo;
/// let mid = ease_in_out_expo(0.5);
/// assert!(mid > 0.5);
/// ```
#[inline]
pub fn ease_in_out_expo(t: f32) -> f32 {
    if t < 0.5 {
        0.5 * (20.0 * t - 10.0).exp2()
    } else {
        1.0 - 0.5 * (10.0 - 20.0 * t).exp2()
    }
}

/// Ease out “back”.
///
/// Overshoots the target before settling.
///
/// # Examples
///
/// ```rust
/// use interpolated::ease_out_back;
/// let out = ease_out_back(0.8);
/// assert!(out > 0.8);
/// ```
#[inline]
pub fn ease_out_back(t: f32) -> f32 {
    const C1: f32 = 1.70158;
    const C3: f32 = C1 + 1.0;
    1.0 + C3 * (t - 1.0).powi(3) + C1 * (t - 1.0).powi(2)
}

/// Ease in “back”.
///
/// Starts by moving backwards before accelerating forward.
///
/// # Examples
///
/// ```rust
/// use interpolated::ease_in_back;
/// let into = ease_in_back(0.2);
/// assert!(into < 0.2);
/// ```
#[inline]
pub fn ease_in_back(t: f32) -> f32 {
    const C1: f32 = 1.70158;
    const C3: f32 = C1 + 1.0;
    C3 * t * t * t - C1 * t * t
}

/// Ease out “elastic”.
///
/// Creates an elastic oscillation effect before settling.
///
/// # Examples
///
/// ```rust
/// use interpolated::ease_out_elastic;
/// let elastic = ease_out_elastic(0.75);
/// assert!(elastic > 0.75);
/// ```
#[inline]
pub fn ease_out_elastic(t: f32) -> f32 {
    const TWO_PI: f32 = 2.0 * PI;
    const C4: f32 = TWO_PI / 3.0;
    if t == 0.0 {
        return 0.0;
    }
    if t == 1.0 {
        return 1.0;
    }
    (-10.0 * t).exp2() * ((t * 10.0 - 0.75) * C4).sin() + 1.0
}