use crate::{intersection::intersect_quad_bez_path, LayerId}; use glam::{DAffine2, DVec2}; use serde::{Deserialize, Serialize}; use std::fmt::Write; use super::{style, LayerData}; #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct PolyLine { points: Vec, } impl PolyLine { pub fn new(points: Vec>) -> PolyLine { PolyLine { points: points.into_iter().map(|it| it.into()).collect(), } } } impl LayerData for PolyLine { fn to_kurbo_path(&self, transform: glam::DAffine2, _style: style::PathStyle) -> kurbo::BezPath { let mut path = kurbo::BezPath::new(); self.points .iter() .map(|v| transform.transform_point2(*v)) .map(|v| kurbo::Point { x: v.x, y: v.y }) .enumerate() .for_each(|(i, p)| if i == 0 { path.move_to(p) } else { path.line_to(p) }); path } fn render(&mut self, svg: &mut String, transform: glam::DAffine2, style: style::PathStyle) { if self.points.is_empty() { return; } let _ = write!(svg, r#""#, style.render()); } fn intersects_quad(&self, quad: [DVec2; 4], path: &mut Vec, intersections: &mut Vec>, style: style::PathStyle) { if intersect_quad_bez_path(quad, &self.to_kurbo_path(DAffine2::IDENTITY, style), false) { intersections.push(path.clone()); } } } #[cfg(test)] #[test] fn polyline_should_render() { use super::style::PathStyle; use glam::DVec2; let mut polyline = PolyLine { points: vec![DVec2::new(3.0, 4.12354), DVec2::new(1.0, 5.54)], }; let mut svg = String::new(); polyline.render(&mut svg, glam::DAffine2::IDENTITY, PathStyle::default()); assert_eq!(r##""##, svg); }