lotus_shared/
math.rs

1use serde::{Deserialize, Serialize};
2
3pub use glam::*;
4
5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub struct Rectangle {
7    start: UVec2,
8    end: UVec2,
9}
10
11impl Rectangle {
12    pub fn new(start: UVec2, end: UVec2) -> Self {
13        assert!(start.x <= end.x);
14        assert!(start.y <= end.y);
15
16        Self { start, end }
17    }
18
19    pub fn from_size(start: UVec2, size: UVec2) -> Self {
20        Self::new(start, start + size)
21    }
22
23    #[inline(always)]
24    pub fn start(&self) -> UVec2 {
25        self.start
26    }
27
28    #[inline(always)]
29    pub fn end(&self) -> UVec2 {
30        self.end
31    }
32
33    #[inline(always)]
34    pub fn width(&self) -> u32 {
35        self.end.x - self.start.x
36    }
37
38    #[inline(always)]
39    pub fn height(&self) -> u32 {
40        self.end.y - self.start.y
41    }
42
43    #[inline(always)]
44    pub fn size(&self) -> UVec2 {
45        UVec2 {
46            x: self.width(),
47            y: self.height(),
48        }
49    }
50
51    #[inline]
52    pub fn contains(&self, point: UVec2) -> bool {
53        self.start.x <= point.x
54            && point.x <= self.end.x
55            && self.start.y <= point.y
56            && point.y <= self.end.y
57    }
58
59    #[inline]
60    pub fn intersects(&self, other: &Rectangle) -> bool {
61        self.start.x <= other.end.x
62            && self.end.x >= other.start.x
63            && self.start.y <= other.end.y
64            && self.end.y >= other.start.y
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_rectangle_creation() {
74        let start = UVec2 { x: 0, y: 0 };
75        let end = UVec2 { x: 5, y: 5 };
76        let rect = Rectangle::new(start, end);
77        assert_eq!(rect.start(), start);
78        assert_eq!(rect.end(), end);
79    }
80
81    #[test]
82    fn test_rectangle_width_and_height() {
83        let start = UVec2 { x: 1, y: 1 };
84        let end = UVec2 { x: 4, y: 6 };
85        let rect = Rectangle::new(start, end);
86        assert_eq!(rect.width(), 3);
87        assert_eq!(rect.height(), 5);
88    }
89
90    #[test]
91    fn test_rectangle_contains() {
92        let start = UVec2 { x: 0, y: 0 };
93        let end = UVec2 { x: 10, y: 10 };
94        let rect = Rectangle::new(start, end);
95        assert!(rect.contains(UVec2 { x: 5, y: 5 }));
96        assert!(!rect.contains(UVec2 { x: 11, y: 5 }));
97    }
98
99    #[test]
100    fn test_rectangle_intersects() {
101        let rect1 = Rectangle::new(UVec2 { x: 0, y: 0 }, UVec2 { x: 5, y: 5 });
102        let rect2 = Rectangle::new(UVec2 { x: 3, y: 3 }, UVec2 { x: 7, y: 7 });
103        let rect3 = Rectangle::new(UVec2 { x: 6, y: 6 }, UVec2 { x: 8, y: 8 });
104
105        assert!(rect1.intersects(&rect2));
106        assert!(!rect1.intersects(&rect3));
107    }
108}