plottery_lib 0.14.1

Core geometry library of Plottery, a creative coding framework for generative vector graphics and pen plotting.
Documentation
#[cfg(test)]
mod test_easing {
    use crate::{Easing, EasingKind, EASING_MAX_AMOUNT};

    const AMOUNTS: [f32; 7] = [-1.0, -0.98, -0.5, 0.0, 0.3, 0.98, 1.0];

    fn samples() -> impl Iterator<Item = f32> {
        (0..=100).map(|i| i as f32 / 100.0)
    }

    #[test]
    fn endpoints_are_fixed() {
        for kind in EasingKind::ALL {
            for amount in AMOUNTS {
                let easing = Easing::new(kind, amount);
                assert!(easing.apply(0.0).abs() < 1e-6, "{easing:?}");
                assert!((easing.apply(1.0) - 1.0).abs() < 1e-6, "{easing:?}");
            }
        }
    }

    #[test]
    fn zero_amount_is_identity() {
        for kind in EasingKind::ALL {
            let easing = Easing::new(kind, 0.0);
            for x in samples() {
                assert!((easing.apply(x) - x).abs() < 1e-5, "{kind:?} at {x}");
            }
        }
    }

    #[test]
    fn midpoint_follows_amount() {
        for kind in [EasingKind::Power, EasingKind::Bias] {
            for amount in [-0.9, -0.5, 0.0, 0.25, 0.9] {
                let mid = Easing::new(kind, amount).apply(0.5);
                assert!(
                    (mid - (0.5 + amount / 2.0)).abs() < 1e-5,
                    "{kind:?} {amount}"
                );
            }
        }
        assert!((Easing::s_curve(0.7).apply(0.5) - 0.5).abs() < 1e-6);
    }

    #[test]
    fn from_exponent_matches_powf() {
        for p in [0.2, 0.5, 1.0, 2.0, 3.5, 6.0] {
            let easing = Easing::from_exponent(p);
            for x in samples() {
                assert!((easing.apply(x) - x.powf(p)).abs() < 1e-4, "p={p} x={x}");
            }
        }
    }

    #[test]
    fn monotonic_and_finite_at_limits() {
        for kind in EasingKind::ALL {
            for amount in [-EASING_MAX_AMOUNT, EASING_MAX_AMOUNT] {
                let easing = Easing::new(kind, amount);
                let values: Vec<f32> = samples().map(|x| easing.apply(x)).collect();
                assert!(values.iter().all(|v| v.is_finite()), "{easing:?}");
                assert!(values.windows(2).all(|w| w[1] >= w[0]), "{easing:?}");
            }
        }
    }
}