plottery_lib 0.12.0

Core geometry library of Plottery, a creative coding framework for generative vector graphics and pen plotting.
Documentation
#[cfg(test)]
mod test_bezier {
    use crate::{Bezier, SampleSettings, V2};
    use itertools::Itertools;

    fn bendy() -> Bezier {
        Bezier::cubic(
            V2::new(0.0, 0.0),
            V2::new(0.0, 10.0),
            V2::new(10.0, 10.0),
            V2::new(10.0, 0.0),
        )
    }

    #[test]
    fn ends_and_symmetric_midpoint() {
        let bezier = bendy();
        assert_eq!(bezier.point_at(0.0), bezier.from());
        assert_eq!(bezier.point_at(1.0), bezier.to());
        assert!((bezier.point_at(0.5).x - 5.0).abs() < 1e-5);
        assert_eq!(bezier.degree(), 3);
    }

    #[test]
    fn split_halves_match_point_at() {
        let bezier = bendy();
        let (left, right) = bezier.split(0.3);
        assert_eq!(left.from(), bezier.from());
        assert_eq!(right.to(), bezier.to());
        assert_eq!(left.to(), bezier.point_at(0.3));
        assert_eq!(right.from(), bezier.point_at(0.3));
        assert_eq!(left.point_at(0.5), bezier.point_at(0.15));
        assert_eq!(right.point_at(0.5), bezier.point_at(0.3 + 0.7 * 0.5));
    }

    #[test]
    fn elevated_is_the_same_curve() {
        let quad = Bezier::quadratic(V2::new(0.0, 0.0), V2::new(3.0, 8.0), V2::new(10.0, 1.0));
        let cubic = quad.elevated();
        assert_eq!(cubic.degree(), 3);
        for t in [0.0, 0.25, 0.5, 0.75, 1.0] {
            assert_eq!(quad.point_at(t), cubic.point_at(t));
        }
    }

    #[test]
    fn length_of_collinear_cubic_is_the_chord() {
        let bezier = Bezier::cubic(
            V2::new(0.0, 0.0),
            V2::new(1.0, 0.0),
            V2::new(2.0, 0.0),
            V2::new(3.0, 0.0),
        );
        assert!((bezier.length() - 3.0).abs() < 1e-3);
    }

    #[test]
    fn points_are_evenly_spaced() {
        let bezier = bendy();
        let points = bezier.points(SampleSettings::new(2.0));
        assert_eq!(points[0], bezier.from());
        assert_eq!(points[points.len() - 1], bezier.to());
        let distances: Vec<f32> = points
            .iter()
            .tuple_windows()
            .map(|(a, b)| a.dist(*b))
            .collect();
        let max = distances.iter().cloned().fold(0.0, f32::max);
        let min = distances.iter().cloned().fold(f32::INFINITY, f32::min);
        assert!(max / min < 1.05, "spacing ratio {}", max / min);
    }
}