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_spline {
    use crate::{
        Angle, Bezier, BoundingBox, Line, Plottable, Rotate, SampleSettings, Segment, Spline, V2,
    };
    use itertools::Itertools;

    fn line_and_curve() -> Spline {
        let mut spline = Spline::default();
        spline.push(Segment::Line(Line::new(
            V2::new(0.0, 0.0),
            V2::new(10.0, 0.0),
        )));
        spline.push(Segment::Bezier(Bezier::cubic(
            V2::new(10.0, 0.0),
            V2::new(15.0, 5.0),
            V2::new(15.0, 10.0),
            V2::new(10.0, 15.0),
        )));
        spline
    }

    #[test]
    fn points_have_no_duplicate_join() {
        let points = line_and_curve().points(SampleSettings::new(1.0));
        assert_eq!(points[0], V2::new(0.0, 0.0));
        assert_eq!(points[points.len() - 1], V2::new(10.0, 15.0));
        assert!(points
            .iter()
            .tuple_windows()
            .all(|(a, b)| a.dist(*b) > 1e-4));
    }

    #[test]
    fn point_at_half_of_two_equal_lines_is_the_join() {
        let mut spline = Spline::default();
        spline.push(Segment::Line(Line::new(
            V2::new(0.0, 0.0),
            V2::new(5.0, 0.0),
        )));
        spline.push(Segment::Line(Line::new(
            V2::new(5.0, 0.0),
            V2::new(5.0, 5.0),
        )));
        assert_eq!(spline.point_at(0.5), V2::new(5.0, 0.0));
        assert_eq!(spline.point_at(0.0), V2::new(0.0, 0.0));
        assert_eq!(spline.point_at(1.0), V2::new(5.0, 5.0));
    }

    #[test]
    fn rotation_round_trip_keeps_control_points() {
        let spline = line_and_curve();
        let angle = Angle::from_degrees(33.0);
        let round_trip = spline.rotate(angle).rotate(-angle);
        for (a, b) in spline.control_points().zip(round_trip.control_points()) {
            assert!(a.dist(b) < 1e-4);
        }
    }

    #[test]
    fn bounding_box_contains_all_sampled_points() {
        let spline = line_and_curve();
        let bounds = spline.bounding_box().unwrap().expand(1e-4);
        for point in spline.points(SampleSettings::default()) {
            assert!(bounds.contains_point(point), "{point:?} outside {bounds:?}");
        }
    }
}