1#[repr(C)]
3#[derive(Debug, Clone, Copy, PartialEq, Default)]
4pub struct Point {
5 pub x: f32,
7 pub y: f32,
9}
10
11impl Point {
12 pub const ORIGIN: Self = Self::new(0.0, 0.0);
14
15 pub const fn new(x: f32, y: f32) -> Self {
17 Self { x, y }
18 }
19
20 #[must_use]
22 pub fn offset(self, dx: f32, dy: f32) -> Self {
23 Self::new(self.x + dx, self.y + dy)
24 }
25
26 pub const fn to_array(self) -> [f32; 2] {
28 [self.x, self.y]
29 }
30}
31
32impl From<[f32; 2]> for Point {
33 fn from([x, y]: [f32; 2]) -> Self {
34 Self::new(x, y)
35 }
36}
37
38#[repr(C)]
48#[derive(Debug, Clone, Copy, PartialEq, Default)]
49pub struct Rect {
50 pub x0: f32,
52 pub y0: f32,
54 pub x1: f32,
56 pub y1: f32,
58}
59
60impl Rect {
61 pub fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
63 Self::from_edges(x, y, x + width, y + height)
64 }
65
66 pub fn from_edges(left: f32, top: f32, right: f32, bottom: f32) -> Self {
69 let (x0, x1) = ordered(left, right);
70 let (y0, y1) = ordered(top, bottom);
71 Self { x0, y0, x1, y1 }
72 }
73
74 pub fn left(&self) -> f32 {
76 self.x0
77 }
78
79 pub fn top(&self) -> f32 {
81 self.y0
82 }
83
84 pub fn right(&self) -> f32 {
86 self.x1
87 }
88
89 pub fn bottom(&self) -> f32 {
91 self.y1
92 }
93
94 pub fn width(&self) -> f32 {
96 self.x1 - self.x0
97 }
98
99 pub fn height(&self) -> f32 {
101 self.y1 - self.y0
102 }
103
104 pub fn is_empty(&self) -> bool {
106 !(self.x1 > self.x0 && self.y1 > self.y0)
107 }
108
109 pub fn contains(&self, point: Point) -> bool {
112 point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1
113 }
114
115 #[must_use]
117 pub fn translate(self, by: Point) -> Self {
118 Self {
119 x0: self.x0 + by.x,
120 y0: self.y0 + by.y,
121 x1: self.x1 + by.x,
122 y1: self.y1 + by.y,
123 }
124 }
125
126 pub fn to_xywh(self) -> [f32; 4] {
128 [self.x0, self.y0, self.width(), self.height()]
129 }
130
131 pub fn origin(&self) -> Point {
133 Point::new(self.x0, self.y0)
134 }
135
136 pub fn size(&self) -> Size {
138 Size::new(self.width(), self.height())
139 }
140
141 #[must_use]
143 pub fn intersect(self, other: Self) -> Self {
144 if self.is_empty() || other.is_empty() {
145 return Self::default();
146 }
147 Self {
148 x0: self.x0.max(other.x0),
149 y0: self.y0.max(other.y0),
150 x1: self.x1.min(other.x1),
151 y1: self.y1.min(other.y1),
152 }
153 }
154
155 pub const EVERYTHING: Self = Self {
157 x0: f32::NEG_INFINITY,
158 y0: f32::NEG_INFINITY,
159 x1: f32::INFINITY,
160 y1: f32::INFINITY,
161 };
162}
163
164#[repr(C)]
166#[derive(Debug, Clone, Copy, PartialEq, Default)]
167pub struct Size {
168 pub width: f32,
170 pub height: f32,
172}
173
174impl Size {
175 pub const ZERO: Self = Self::new(0.0, 0.0);
177
178 pub const fn new(width: f32, height: f32) -> Self {
180 Self { width, height }
181 }
182}
183
184fn ordered(a: f32, b: f32) -> (f32, f32) {
186 if b < a {
187 (b, a)
188 } else {
189 (a, b)
190 }
191}