Skip to main content

blockworx/router/
point.rs

1use crate::router::coord::{CoordX, CoordY};
2use blockworx_geom::Pos2;
3
4// A point on the grid is a pair of coordinates
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct Point {
7    pub x: CoordX,
8    pub y: CoordY,
9}
10
11impl std::fmt::Display for Point {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        write!(f, "({},{})", self.x, self.y)
14    }
15}
16
17impl Point {
18    /// The grid origin, used as the inert fallback where a point must exist.
19    pub const ZERO: Point = Point {
20        x: CoordX::ZERO,
21        y: CoordY::ZERO,
22    };
23
24    pub fn manhattan_distance(self, other: Point) -> i32 {
25        (self.x - other.x).abs() + (self.y - other.y).abs()
26    }
27}
28
29pub fn point(x: impl Into<CoordX>, y: impl Into<CoordY>) -> Point {
30    Point {
31        x: x.into(),
32        y: y.into(),
33    }
34}
35
36impl std::ops::Add<CoordX> for Point {
37    type Output = Self;
38    fn add(self, rhs: CoordX) -> Self {
39        Point {
40            x: self.x + rhs,
41            y: self.y,
42        }
43    }
44}
45
46impl std::ops::Add<CoordY> for Point {
47    type Output = Self;
48    fn add(self, rhs: CoordY) -> Self {
49        Point {
50            x: self.x,
51            y: self.y + rhs,
52        }
53    }
54}
55
56impl std::ops::Add<Point> for Point {
57    type Output = Self;
58    fn add(self, rhs: Point) -> Self {
59        Point {
60            x: self.x + rhs.x,
61            y: self.y + rhs.y,
62        }
63    }
64}
65
66// Conversion from a Pos2 to a point cannot fail unless there is an
67// overflow/underflow situation, which we do not handle.
68impl From<Pos2> for Point {
69    fn from(pos: Pos2) -> Self {
70        Point {
71            x: CoordX::from(pos.x),
72            y: CoordY::from(pos.y),
73        }
74    }
75}
76
77// Round tripping will move any Pos2 to the nearest lattice point.
78impl From<Point> for Pos2 {
79    fn from(point: Point) -> Self {
80        Pos2::new(
81            (point.x.raw() as f32) * crate::grid::GRID_SIZE,
82            (point.y.raw() as f32) * crate::grid::GRID_SIZE,
83        )
84    }
85}
86
87// Convert a document grid coordinate directly into a router point — no
88// floating-point detour, since both are lattice-aligned.
89impl From<blockworx_doc::geometry::GridPoint> for Point {
90    fn from(g: blockworx_doc::geometry::GridPoint) -> Self {
91        Point {
92            x: CoordX::from(g.x),
93            y: CoordY::from(g.y),
94        }
95    }
96}
97
98impl From<Point> for blockworx_doc::geometry::GridPoint {
99    fn from(p: Point) -> Self {
100        blockworx_doc::geometry::GridPoint {
101            x: p.x.raw(),
102            y: p.y.raw(),
103        }
104    }
105}