macroquad_ply/math/
rect.rs1use glam::*;
2
3#[derive(Clone, Copy, Debug, Default, PartialEq)]
5pub struct Rect {
6 pub x: f32,
8 pub y: f32,
10 pub w: f32,
12 pub h: f32,
14}
15
16impl Rect {
17 pub const fn new(x: f32, y: f32, w: f32, h: f32) -> Rect {
25 Rect { x, y, w, h }
26 }
27
28 pub const fn point(&self) -> Vec2 {
30 vec2(self.x, self.y)
31 }
32
33 pub const fn size(&self) -> Vec2 {
35 vec2(self.w, self.h)
36 }
37
38 pub const fn center(&self) -> Vec2 {
40 vec2(self.x + self.w * 0.5f32, self.y + self.h * 0.5f32)
41 }
42
43 pub const fn left(&self) -> f32 {
45 self.x
46 }
47
48 pub const fn right(&self) -> f32 {
50 self.x + self.w
51 }
52
53 pub const fn top(&self) -> f32 {
55 self.y
56 }
57
58 pub const fn bottom(&self) -> f32 {
60 self.y + self.h
61 }
62
63 pub const fn move_to(&mut self, destination: Vec2) {
65 self.x = destination.x;
66 self.y = destination.y;
67 }
68
69 pub const fn scale(&mut self, sx: f32, sy: f32) {
72 self.w *= sx;
73 self.h *= sy;
74 }
75
76 pub const fn contains(&self, point: Vec2) -> bool {
78 point.x >= self.left()
79 && point.x <= self.right()
80 && point.y <= self.bottom()
81 && point.y >= self.top()
82 }
83
84 pub const fn overlaps(&self, other: &Rect) -> bool {
86 self.left() <= other.right()
87 && self.right() >= other.left()
88 && self.top() <= other.bottom()
89 && self.bottom() >= other.top()
90 }
91
92 pub const fn combine_with(self, other: Rect) -> Rect {
94 let x = f32::min(self.x, other.x);
95 let y = f32::min(self.y, other.y);
96 let w = f32::max(self.right(), other.right()) - x;
97 let h = f32::max(self.bottom(), other.bottom()) - y;
98 Rect { x, y, w, h }
99 }
100
101 pub const fn intersect(&self, other: Rect) -> Option<Rect> {
103 let left = self.x.max(other.x);
104 let top = self.y.max(other.y);
105 let right = self.right().min(other.right());
106 let bottom = self.bottom().min(other.bottom());
107
108 if right < left || bottom < top {
109 return None;
110 }
111
112 Some(Rect {
113 x: left,
114 y: top,
115 w: right - left,
116 h: bottom - top,
117 })
118 }
119
120 pub const fn offset(self, offset: Vec2) -> Rect {
122 Rect::new(self.x + offset.x, self.y + offset.y, self.w, self.h)
123 }
124
125 pub fn normalized(&self) -> Rect {
127 let x = self.x.min(self.x + self.w);
128 let y = self.y.min(self.y + self.h);
129 let w = self.w.abs();
130 let h = self.h.abs();
131 Rect { x, y, w, h }
132 }
133}
134
135#[derive(Clone, Copy, Debug, Default, PartialEq)]
136pub struct RectOffset {
137 pub left: f32,
138 pub right: f32,
139 pub bottom: f32,
140 pub top: f32,
141}
142
143impl RectOffset {
144 pub const fn new(left: f32, right: f32, top: f32, bottom: f32) -> RectOffset {
145 RectOffset {
146 left,
147 right,
148 top,
149 bottom,
150 }
151 }
152}
153
154#[test]
155fn rect_contains_border() {
156 let rect = Rect::new(1.0, 1.0, 2.0, 2.0);
157 assert!(rect.contains(vec2(1.0, 1.0)));
158 assert!(rect.contains(vec2(3.0, 1.0)));
159 assert!(rect.contains(vec2(1.0, 3.0)));
160 assert!(rect.contains(vec2(3.0, 3.0)));
161 assert!(rect.contains(vec2(2.0, 2.0)));
162}