1use std::{
2 fmt,
3 ops::{Add, AddAssign, MulAssign, Sub, SubAssign},
4};
5
6use crate::{Div, Mul, Vec2, lerp};
7
8#[repr(C)]
15#[derive(Clone, Copy, Default, PartialEq)]
16#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
17#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
18pub struct Pos2 {
19 pub x: f32,
21
22 pub y: f32,
24 }
26
27#[inline(always)]
29pub const fn pos2(x: f32, y: f32) -> Pos2 {
30 Pos2 { x, y }
31}
32
33impl From<[f32; 2]> for Pos2 {
37 #[inline(always)]
38 fn from(v: [f32; 2]) -> Self {
39 Self { x: v[0], y: v[1] }
40 }
41}
42
43impl From<&[f32; 2]> for Pos2 {
44 #[inline(always)]
45 fn from(v: &[f32; 2]) -> Self {
46 Self { x: v[0], y: v[1] }
47 }
48}
49
50impl From<Pos2> for [f32; 2] {
51 #[inline(always)]
52 fn from(v: Pos2) -> Self {
53 [v.x, v.y]
54 }
55}
56
57impl From<&Pos2> for [f32; 2] {
58 #[inline(always)]
59 fn from(v: &Pos2) -> Self {
60 [v.x, v.y]
61 }
62}
63
64impl From<(f32, f32)> for Pos2 {
68 #[inline(always)]
69 fn from(v: (f32, f32)) -> Self {
70 Self { x: v.0, y: v.1 }
71 }
72}
73
74impl From<&(f32, f32)> for Pos2 {
75 #[inline(always)]
76 fn from(v: &(f32, f32)) -> Self {
77 Self { x: v.0, y: v.1 }
78 }
79}
80
81impl From<Pos2> for (f32, f32) {
82 #[inline(always)]
83 fn from(v: Pos2) -> Self {
84 (v.x, v.y)
85 }
86}
87
88impl From<&Pos2> for (f32, f32) {
89 #[inline(always)]
90 fn from(v: &Pos2) -> Self {
91 (v.x, v.y)
92 }
93}
94
95#[cfg(feature = "mint")]
99impl From<mint::Point2<f32>> for Pos2 {
100 #[inline(always)]
101 fn from(v: mint::Point2<f32>) -> Self {
102 Self::new(v.x, v.y)
103 }
104}
105
106#[cfg(feature = "mint")]
107impl From<Pos2> for mint::Point2<f32> {
108 #[inline(always)]
109 fn from(v: Pos2) -> Self {
110 Self { x: v.x, y: v.y }
111 }
112}
113
114impl Pos2 {
117 pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
121
122 #[inline(always)]
123 pub const fn new(x: f32, y: f32) -> Self {
124 Self { x, y }
125 }
126
127 #[inline(always)]
130 pub fn to_vec2(self) -> Vec2 {
131 Vec2 {
132 x: self.x,
133 y: self.y,
134 }
135 }
136
137 #[inline]
138 pub fn distance(self, other: Self) -> f32 {
139 (self - other).length()
140 }
141
142 #[inline]
143 pub fn distance_sq(self, other: Self) -> f32 {
144 (self - other).length_sq()
145 }
146
147 #[inline(always)]
148 pub fn floor(self) -> Self {
149 pos2(self.x.floor(), self.y.floor())
150 }
151
152 #[inline(always)]
153 pub fn round(self) -> Self {
154 pos2(self.x.round(), self.y.round())
155 }
156
157 #[inline(always)]
158 pub fn ceil(self) -> Self {
159 pos2(self.x.ceil(), self.y.ceil())
160 }
161
162 #[inline(always)]
164 pub fn is_finite(self) -> bool {
165 self.x.is_finite() && self.y.is_finite()
166 }
167
168 #[inline(always)]
170 pub fn any_nan(self) -> bool {
171 self.x.is_nan() || self.y.is_nan()
172 }
173
174 #[must_use]
175 #[inline]
176 pub fn min(self, other: Self) -> Self {
177 pos2(self.x.min(other.x), self.y.min(other.y))
178 }
179
180 #[must_use]
181 #[inline]
182 pub fn max(self, other: Self) -> Self {
183 pos2(self.x.max(other.x), self.y.max(other.y))
184 }
185
186 #[must_use]
187 #[inline]
188 pub fn clamp(self, min: Self, max: Self) -> Self {
189 Self {
190 x: self.x.clamp(min.x, max.x),
191 y: self.y.clamp(min.y, max.y),
192 }
193 }
194
195 pub fn lerp(&self, other: Self, t: f32) -> Self {
197 Self {
198 x: lerp(self.x..=other.x, t),
199 y: lerp(self.y..=other.y, t),
200 }
201 }
202}
203
204impl std::ops::Index<usize> for Pos2 {
205 type Output = f32;
206
207 #[inline(always)]
208 fn index(&self, index: usize) -> &f32 {
209 match index {
210 0 => &self.x,
211 1 => &self.y,
212 _ => panic!("Pos2 index out of bounds: {index}"),
213 }
214 }
215}
216
217impl std::ops::IndexMut<usize> for Pos2 {
218 #[inline(always)]
219 fn index_mut(&mut self, index: usize) -> &mut f32 {
220 match index {
221 0 => &mut self.x,
222 1 => &mut self.y,
223 _ => panic!("Pos2 index out of bounds: {index}"),
224 }
225 }
226}
227
228impl Eq for Pos2 {}
229
230impl AddAssign<Vec2> for Pos2 {
231 #[inline(always)]
232 fn add_assign(&mut self, rhs: Vec2) {
233 *self = Self {
234 x: self.x + rhs.x,
235 y: self.y + rhs.y,
236 };
237 }
238}
239
240impl SubAssign<Vec2> for Pos2 {
241 #[inline(always)]
242 fn sub_assign(&mut self, rhs: Vec2) {
243 *self = Self {
244 x: self.x - rhs.x,
245 y: self.y - rhs.y,
246 };
247 }
248}
249
250impl Add<Vec2> for Pos2 {
251 type Output = Self;
252
253 #[inline(always)]
254 fn add(self, rhs: Vec2) -> Self {
255 Self {
256 x: self.x + rhs.x,
257 y: self.y + rhs.y,
258 }
259 }
260}
261
262impl Sub for Pos2 {
263 type Output = Vec2;
264
265 #[inline(always)]
266 fn sub(self, rhs: Self) -> Vec2 {
267 Vec2 {
268 x: self.x - rhs.x,
269 y: self.y - rhs.y,
270 }
271 }
272}
273
274impl Sub<Vec2> for Pos2 {
275 type Output = Self;
276
277 #[inline(always)]
278 fn sub(self, rhs: Vec2) -> Self {
279 Self {
280 x: self.x - rhs.x,
281 y: self.y - rhs.y,
282 }
283 }
284}
285
286impl Mul<f32> for Pos2 {
287 type Output = Self;
288
289 #[inline(always)]
290 fn mul(self, factor: f32) -> Self {
291 Self {
292 x: self.x * factor,
293 y: self.y * factor,
294 }
295 }
296}
297
298impl Mul<Pos2> for f32 {
299 type Output = Pos2;
300
301 #[inline(always)]
302 fn mul(self, vec: Pos2) -> Pos2 {
303 Pos2 {
304 x: self * vec.x,
305 y: self * vec.y,
306 }
307 }
308}
309
310impl MulAssign<f32> for Pos2 {
311 #[inline(always)]
312 fn mul_assign(&mut self, rhs: f32) {
313 self.x *= rhs;
314 self.y *= rhs;
315 }
316}
317
318impl Div<f32> for Pos2 {
319 type Output = Self;
320
321 #[inline(always)]
322 fn div(self, factor: f32) -> Self {
323 Self {
324 x: self.x / factor,
325 y: self.y / factor,
326 }
327 }
328}
329
330impl fmt::Debug for Pos2 {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 if let Some(precision) = f.precision() {
333 write!(f, "[{1:.0$} {2:.0$}]", precision, self.x, self.y)
334 } else {
335 write!(f, "[{:.1} {:.1}]", self.x, self.y)
336 }
337 }
338}
339
340impl fmt::Display for Pos2 {
341 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
342 f.write_str("[")?;
343 self.x.fmt(f)?;
344 f.write_str(" ")?;
345 self.y.fmt(f)?;
346 f.write_str("]")?;
347 Ok(())
348 }
349}