Skip to main content

merman_core/
geom.rs

1#![forbid(unsafe_code)]
2
3pub type Unit = euclid::UnknownUnit;
4
5pub type Point = euclid::Point2D<f64, Unit>;
6pub type Vector = euclid::Vector2D<f64, Unit>;
7pub type Size = euclid::Size2D<f64, Unit>;
8pub type Rect = euclid::Rect<f64, Unit>;
9pub type Transform = euclid::Transform2D<f64, Unit, Unit>;
10
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub struct Box2(pub euclid::Box2D<f64, Unit>);
13
14impl Box2 {
15    pub fn from_min_max(min_x: f64, min_y: f64, max_x: f64, max_y: f64) -> Self {
16        Self(euclid::Box2D::new(point(min_x, min_y), point(max_x, max_y)))
17    }
18
19    pub fn from_center(x: f64, y: f64, width: f64, height: f64) -> Self {
20        let hw = width / 2.0;
21        let hh = height / 2.0;
22        Self(euclid::Box2D::new(
23            point(x - hw, y - hh),
24            point(x + hw, y + hh),
25        ))
26    }
27
28    pub fn width(&self) -> f64 {
29        self.0.max.x - self.0.min.x
30    }
31
32    pub fn height(&self) -> f64 {
33        self.0.max.y - self.0.min.y
34    }
35
36    pub fn min_x(&self) -> f64 {
37        self.0.min.x
38    }
39
40    pub fn min_y(&self) -> f64 {
41        self.0.min.y
42    }
43
44    pub fn max_x(&self) -> f64 {
45        self.0.max.x
46    }
47
48    pub fn max_y(&self) -> f64 {
49        self.0.max.y
50    }
51
52    pub fn center(&self) -> (f64, f64) {
53        (
54            (self.0.min.x + self.0.max.x) / 2.0,
55            (self.0.min.y + self.0.max.y) / 2.0,
56        )
57    }
58
59    pub fn center_point(&self) -> Point {
60        let (x, y) = self.center();
61        point(x, y)
62    }
63
64    pub fn union(&mut self, other: Self) {
65        let min_x = self.0.min.x.min(other.0.min.x);
66        let min_y = self.0.min.y.min(other.0.min.y);
67        let max_x = self.0.max.x.max(other.0.max.x);
68        let max_y = self.0.max.y.max(other.0.max.y);
69        self.0 = euclid::Box2D::new(point(min_x, min_y), point(max_x, max_y));
70    }
71
72    pub fn translate(&mut self, dx: f64, dy: f64) {
73        let d = vector(dx, dy);
74        self.0 = euclid::Box2D::new(self.0.min + d, self.0.max + d);
75    }
76
77    pub fn pad(&mut self, padding: f64) {
78        self.0.min.x -= padding;
79        self.0.min.y -= padding;
80        self.0.max.x += padding;
81        self.0.max.y += padding;
82    }
83
84    pub fn contains_point(&self, x: f64, y: f64) -> bool {
85        x >= self.min_x() && x <= self.max_x() && y >= self.min_y() && y <= self.max_y()
86    }
87}
88
89pub fn point(x: f64, y: f64) -> Point {
90    euclid::point2(x, y)
91}
92
93pub fn vector(x: f64, y: f64) -> Vector {
94    euclid::vec2(x, y)
95}