vsvg 0.5.0

Core library for pen-plotter graphics.
Documentation
#[derive(Debug, Clone, Copy, PartialEq, Default, serde::Serialize, serde::Deserialize)]
pub struct Point {
    data: [f64; 2],
}

impl Point {
    pub const ZERO: Point = Point { data: [0.0, 0.0] };

    #[must_use]
    #[inline]
    pub fn new<T, U>(x: T, y: U) -> Self
    where
        T: Into<f64>,
        U: Into<f64>,
    {
        Self {
            data: [x.into(), y.into()],
        }
    }

    #[must_use]
    #[inline]
    pub fn x(&self) -> f64 {
        self.data[0]
    }

    #[must_use]
    #[inline]
    pub fn y(&self) -> f64 {
        self.data[1]
    }

    #[must_use]
    #[inline]
    pub fn x_mut(&mut self) -> &mut f64 {
        &mut self.data[0]
    }

    #[must_use]
    #[inline]
    pub fn y_mut(&mut self) -> &mut f64 {
        &mut self.data[1]
    }

    #[must_use]
    pub fn distance(&self, other: &Self) -> f64 {
        let dx = self.x() - other.x();
        let dy = self.y() - other.y();
        dx.hypot(dy)
    }
}

impl From<(f64, f64)> for Point {
    fn from((x, y): (f64, f64)) -> Self {
        Self::new(x, y)
    }
}

impl From<(f32, f32)> for Point {
    fn from((x, y): (f32, f32)) -> Self {
        Self::new(f64::from(x), f64::from(y))
    }
}

impl From<Point> for (f64, f64) {
    fn from(p: Point) -> Self {
        (p.x(), p.y())
    }
}

impl From<[f64; 2]> for Point {
    fn from([x, y]: [f64; 2]) -> Self {
        Self::new(x, y)
    }
}

impl From<[f32; 2]> for Point {
    fn from([x, y]: [f32; 2]) -> Self {
        Self::new(f64::from(x), f64::from(y))
    }
}

impl From<Point> for [f64; 2] {
    fn from(p: Point) -> Self {
        p.data
    }
}

impl AsRef<[f64]> for Point {
    fn as_ref(&self) -> &[f64] {
        &self.data
    }
}

impl AsRef<[f64; 2]> for Point {
    fn as_ref(&self) -> &[f64; 2] {
        &self.data
    }
}

impl From<kurbo::Point> for Point {
    fn from(p: kurbo::Point) -> Self {
        Self::new(p.x, p.y)
    }
}

impl From<Point> for kurbo::Point {
    fn from(p: Point) -> Self {
        Self { x: p.x(), y: p.y() }
    }
}

impl From<&Point> for [f64; 2] {
    fn from(p: &Point) -> Self {
        p.data
    }
}

impl From<Point> for [f32; 2] {
    fn from(p: Point) -> Self {
        #[allow(clippy::cast_possible_truncation)]
        [p.x() as f32, p.y() as f32]
    }
}

impl From<&Point> for [f32; 2] {
    fn from(p: &Point) -> Self {
        #[allow(clippy::cast_possible_truncation)]
        [p.x() as f32, p.y() as f32]
    }
}

impl From<&Point> for kurbo::Point {
    fn from(p: &Point) -> Self {
        Self { x: p.x(), y: p.y() }
    }
}

impl From<&kurbo::Point> for Point {
    fn from(p: &kurbo::Point) -> Self {
        Self::new(p.x, p.y)
    }
}

#[cfg(feature = "egui")]
impl From<Point> for egui::Pos2 {
    fn from(p: Point) -> Self {
        #[allow(clippy::cast_possible_truncation)]
        egui::pos2(p.x() as f32, p.y() as f32)
    }
}

#[cfg(feature = "egui")]
impl From<&Point> for egui::Pos2 {
    fn from(p: &Point) -> Self {
        #[allow(clippy::cast_possible_truncation)]
        egui::pos2(p.x() as f32, p.y() as f32)
    }
}

#[cfg(feature = "glam")]
impl From<glam::Vec2> for Point {
    fn from(p: glam::Vec2) -> Self {
        Self::new(f64::from(p.x), f64::from(p.y))
    }
}

impl std::ops::Add for Point {
    type Output = Self;

    #[inline]
    fn add(self, other: Self) -> Self {
        Self::new(self.x() + other.x(), self.y() + other.y())
    }
}

impl std::ops::Sub for Point {
    type Output = Self;

    #[inline]
    fn sub(self, other: Self) -> Self {
        Self::new(self.x() - other.x(), self.y() - other.y())
    }
}

impl std::ops::Mul<f64> for Point {
    type Output = Self;

    #[inline]
    fn mul(self, other: f64) -> Self {
        Self::new(self.x() * other, self.y() * other)
    }
}

impl std::ops::Mul<Point> for f64 {
    type Output = Point;

    #[inline]
    fn mul(self, other: Point) -> Point {
        other * self
    }
}

impl std::ops::Div<f64> for Point {
    type Output = Self;

    #[inline]
    fn div(self, other: f64) -> Self {
        Self::new(self.x() / other, self.y() / other)
    }
}

impl std::ops::Mul<Point> for kurbo::Affine {
    type Output = Point;

    #[inline]
    fn mul(self, other: Point) -> Point {
        let coeffs = self.as_coeffs();
        Point::new(
            coeffs[0] * other.x() + coeffs[2] * other.y() + coeffs[4],
            coeffs[1] * other.x() + coeffs[3] * other.y() + coeffs[5],
        )
    }
}