1use serde::{Deserialize, Serialize};
6
7pub use glam::*;
8
9#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub struct Rectangle {
14 start: UVec2,
15 end: UVec2,
16}
17
18impl Rectangle {
19 pub fn new(start: UVec2, end: UVec2) -> Self {
23 assert!(start.x <= end.x);
24 assert!(start.y <= end.y);
25
26 Self { start, end }
27 }
28
29 pub fn from_size(start: UVec2, size: UVec2) -> Self {
33 Self::new(start, start + size)
34 }
35
36 #[inline(always)]
40 pub fn start(&self) -> UVec2 {
41 self.start
42 }
43
44 #[inline(always)]
48 pub fn end(&self) -> UVec2 {
49 self.end
50 }
51
52 #[inline(always)]
56 pub fn width(&self) -> u32 {
57 self.end.x - self.start.x
58 }
59
60 #[inline(always)]
64 pub fn height(&self) -> u32 {
65 self.end.y - self.start.y
66 }
67
68 #[inline(always)]
72 pub fn size(&self) -> UVec2 {
73 UVec2 {
74 x: self.width(),
75 y: self.height(),
76 }
77 }
78
79 #[inline]
83 pub fn contains(&self, point: UVec2) -> bool {
84 self.start.x <= point.x
85 && point.x <= self.end.x
86 && self.start.y <= point.y
87 && point.y <= self.end.y
88 }
89
90 #[inline]
94 pub fn intersects(&self, other: &Rectangle) -> bool {
95 self.start.x <= other.end.x
96 && self.end.x >= other.start.x
97 && self.start.y <= other.end.y
98 && self.end.y >= other.start.y
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_rectangle_creation() {
108 let start = UVec2 { x: 0, y: 0 };
109 let end = UVec2 { x: 5, y: 5 };
110 let rect = Rectangle::new(start, end);
111 assert_eq!(rect.start(), start);
112 assert_eq!(rect.end(), end);
113 }
114
115 #[test]
116 fn test_rectangle_width_and_height() {
117 let start = UVec2 { x: 1, y: 1 };
118 let end = UVec2 { x: 4, y: 6 };
119 let rect = Rectangle::new(start, end);
120 assert_eq!(rect.width(), 3);
121 assert_eq!(rect.height(), 5);
122 }
123
124 #[test]
125 fn test_rectangle_contains() {
126 let start = UVec2 { x: 0, y: 0 };
127 let end = UVec2 { x: 10, y: 10 };
128 let rect = Rectangle::new(start, end);
129 assert!(rect.contains(UVec2 { x: 5, y: 5 }));
130 assert!(!rect.contains(UVec2 { x: 11, y: 5 }));
131 }
132
133 #[test]
134 fn test_rectangle_intersects() {
135 let rect1 = Rectangle::new(UVec2 { x: 0, y: 0 }, UVec2 { x: 5, y: 5 });
136 let rect2 = Rectangle::new(UVec2 { x: 3, y: 3 }, UVec2 { x: 7, y: 7 });
137 let rect3 = Rectangle::new(UVec2 { x: 6, y: 6 }, UVec2 { x: 8, y: 8 });
138
139 assert!(rect1.intersects(&rect2));
140 assert!(!rect1.intersects(&rect3));
141 }
142}