//! Point arithmetic for the code-drawn centre-line scenes. use std::ops::{Add, Mul, Neg, Sub}; /// A point or vector in pixel coordinates (pixel `(x, y)` covers `[x, x+1] × [y, y+1]`, y down). #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct P { pub x: f64, pub y: f64, } impl P { pub const fn new(x: f64, y: f64) -> Self { Self { x, y } } pub fn dot(self, o: P) -> f64 { self.x * o.x + self.y * o.y } pub fn len(self) -> f64 { self.x.hypot(self.y) } pub fn dist(self, o: P) -> f64 { (self - o).len() } /// Unit vector, or `None` for a (near) zero vector. pub fn unit(self) -> Option
{
let l = self.len();
(l > 1e-12 && l.is_finite()).then(|| P::new(self.x / l, self.y / l))
}
pub fn lerp(self, o: P, t: f64) -> P {
self + (o - self) * t
}
}
impl Add for P {
type Output = P;
fn add(self, o: P) -> P {
P::new(self.x + o.x, self.y + o.y)
}
}
impl Sub for P {
type Output = P;
fn sub(self, o: P) -> P {
P::new(self.x - o.x, self.y - o.y)
}
}
impl Mul