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}