1use std::fmt;
2use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
3
4use crate::Vec2b;
5
6#[repr(C)]
13#[derive(Clone, Copy, Default, PartialEq)]
14#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
15#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
16pub struct Vec2 {
17 pub x: f32,
19
20 pub y: f32,
22}
23
24#[inline(always)]
26pub const fn vec2(x: f32, y: f32) -> Vec2 {
27 Vec2 { x, y }
28}
29
30impl From<[f32; 2]> for Vec2 {
34 #[inline(always)]
35 fn from(v: [f32; 2]) -> Self {
36 Self { x: v[0], y: v[1] }
37 }
38}
39
40impl From<&[f32; 2]> for Vec2 {
41 #[inline(always)]
42 fn from(v: &[f32; 2]) -> Self {
43 Self { x: v[0], y: v[1] }
44 }
45}
46
47impl From<Vec2> for [f32; 2] {
48 #[inline(always)]
49 fn from(v: Vec2) -> Self {
50 [v.x, v.y]
51 }
52}
53
54impl From<&Vec2> for [f32; 2] {
55 #[inline(always)]
56 fn from(v: &Vec2) -> Self {
57 [v.x, v.y]
58 }
59}
60
61impl From<(f32, f32)> for Vec2 {
65 #[inline(always)]
66 fn from(v: (f32, f32)) -> Self {
67 Self { x: v.0, y: v.1 }
68 }
69}
70
71impl From<&(f32, f32)> for Vec2 {
72 #[inline(always)]
73 fn from(v: &(f32, f32)) -> Self {
74 Self { x: v.0, y: v.1 }
75 }
76}
77
78impl From<Vec2> for (f32, f32) {
79 #[inline(always)]
80 fn from(v: Vec2) -> Self {
81 (v.x, v.y)
82 }
83}
84
85impl From<&Vec2> for (f32, f32) {
86 #[inline(always)]
87 fn from(v: &Vec2) -> Self {
88 (v.x, v.y)
89 }
90}
91
92impl From<Vec2b> for Vec2 {
93 #[inline(always)]
94 fn from(v: Vec2b) -> Self {
95 Self {
96 x: v.x as i32 as f32,
97 y: v.y as i32 as f32,
98 }
99 }
100}
101
102#[cfg(feature = "mint")]
106impl From<mint::Vector2<f32>> for Vec2 {
107 #[inline]
108 fn from(v: mint::Vector2<f32>) -> Self {
109 Self::new(v.x, v.y)
110 }
111}
112
113#[cfg(feature = "mint")]
114impl From<Vec2> for mint::Vector2<f32> {
115 #[inline]
116 fn from(v: Vec2) -> Self {
117 Self { x: v.x, y: v.y }
118 }
119}
120
121impl Vec2 {
124 pub const X: Self = Self { x: 1.0, y: 0.0 };
126
127 pub const Y: Self = Self { x: 0.0, y: 1.0 };
129
130 pub const RIGHT: Self = Self { x: 1.0, y: 0.0 };
132
133 pub const LEFT: Self = Self { x: -1.0, y: 0.0 };
135
136 pub const UP: Self = Self { x: 0.0, y: -1.0 };
138
139 pub const DOWN: Self = Self { x: 0.0, y: 1.0 };
141
142 pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
143 pub const INFINITY: Self = Self::splat(f32::INFINITY);
144 pub const NAN: Self = Self::splat(f32::NAN);
145
146 #[inline(always)]
147 pub const fn new(x: f32, y: f32) -> Self {
148 Self { x, y }
149 }
150
151 #[inline(always)]
153 pub const fn splat(v: f32) -> Self {
154 Self { x: v, y: v }
155 }
156
157 #[inline(always)]
160 pub fn to_pos2(self) -> crate::Pos2 {
161 crate::Pos2 {
162 x: self.x,
163 y: self.y,
164 }
165 }
166
167 #[must_use]
169 #[inline(always)]
170 pub fn normalized(self) -> Self {
171 let len = self.length();
172 if len <= 0.0 {
173 self
174 } else {
175 self / len
176 }
177 }
178
179 #[inline(always)]
182 pub fn rot90(self) -> Self {
183 vec2(self.y, -self.x)
184 }
185
186 #[inline(always)]
187 pub fn length(self) -> f32 {
188 self.x.hypot(self.y)
189 }
190
191 #[inline(always)]
192 pub fn length_sq(self) -> f32 {
193 self.x * self.x + self.y * self.y
194 }
195
196 #[inline(always)]
213 pub fn angle(self) -> f32 {
214 self.y.atan2(self.x)
215 }
216
217 #[inline(always)]
229 pub fn angled(angle: f32) -> Self {
230 let (sin, cos) = angle.sin_cos();
231 vec2(cos, sin)
232 }
233
234 #[must_use]
235 #[inline(always)]
236 pub fn floor(self) -> Self {
237 vec2(self.x.floor(), self.y.floor())
238 }
239
240 #[must_use]
241 #[inline(always)]
242 pub fn round(self) -> Self {
243 vec2(self.x.round(), self.y.round())
244 }
245
246 #[must_use]
247 #[inline(always)]
248 pub fn ceil(self) -> Self {
249 vec2(self.x.ceil(), self.y.ceil())
250 }
251
252 #[must_use]
253 #[inline]
254 pub fn abs(self) -> Self {
255 vec2(self.x.abs(), self.y.abs())
256 }
257
258 #[inline(always)]
260 pub fn is_finite(self) -> bool {
261 self.x.is_finite() && self.y.is_finite()
262 }
263
264 #[inline(always)]
266 pub fn any_nan(self) -> bool {
267 self.x.is_nan() || self.y.is_nan()
268 }
269
270 #[must_use]
271 #[inline]
272 pub fn min(self, other: Self) -> Self {
273 vec2(self.x.min(other.x), self.y.min(other.y))
274 }
275
276 #[must_use]
277 #[inline]
278 pub fn max(self, other: Self) -> Self {
279 vec2(self.x.max(other.x), self.y.max(other.y))
280 }
281
282 #[inline]
284 pub fn dot(self, other: Self) -> f32 {
285 self.x * other.x + self.y * other.y
286 }
287
288 #[must_use]
290 #[inline(always)]
291 pub fn min_elem(self) -> f32 {
292 self.x.min(self.y)
293 }
294
295 #[inline(always)]
297 #[must_use]
298 pub fn max_elem(self) -> f32 {
299 self.x.max(self.y)
300 }
301
302 #[inline]
304 #[must_use]
305 pub fn yx(self) -> Self {
306 Self {
307 x: self.y,
308 y: self.x,
309 }
310 }
311
312 #[must_use]
313 #[inline]
314 pub fn clamp(self, min: Self, max: Self) -> Self {
315 Self {
316 x: self.x.clamp(min.x, max.x),
317 y: self.y.clamp(min.y, max.y),
318 }
319 }
320}
321
322impl std::ops::Index<usize> for Vec2 {
323 type Output = f32;
324
325 #[inline(always)]
326 fn index(&self, index: usize) -> &f32 {
327 match index {
328 0 => &self.x,
329 1 => &self.y,
330 _ => panic!("Vec2 index out of bounds: {index}"),
331 }
332 }
333}
334
335impl std::ops::IndexMut<usize> for Vec2 {
336 #[inline(always)]
337 fn index_mut(&mut self, index: usize) -> &mut f32 {
338 match index {
339 0 => &mut self.x,
340 1 => &mut self.y,
341 _ => panic!("Vec2 index out of bounds: {index}"),
342 }
343 }
344}
345
346impl Eq for Vec2 {}
347
348impl Neg for Vec2 {
349 type Output = Self;
350
351 #[inline(always)]
352 fn neg(self) -> Self {
353 vec2(-self.x, -self.y)
354 }
355}
356
357impl AddAssign for Vec2 {
358 #[inline(always)]
359 fn add_assign(&mut self, rhs: Self) {
360 *self = Self {
361 x: self.x + rhs.x,
362 y: self.y + rhs.y,
363 };
364 }
365}
366
367impl SubAssign for Vec2 {
368 #[inline(always)]
369 fn sub_assign(&mut self, rhs: Self) {
370 *self = Self {
371 x: self.x - rhs.x,
372 y: self.y - rhs.y,
373 };
374 }
375}
376
377impl Add for Vec2 {
378 type Output = Self;
379
380 #[inline(always)]
381 fn add(self, rhs: Self) -> Self {
382 Self {
383 x: self.x + rhs.x,
384 y: self.y + rhs.y,
385 }
386 }
387}
388
389impl Sub for Vec2 {
390 type Output = Self;
391
392 #[inline(always)]
393 fn sub(self, rhs: Self) -> Self {
394 Self {
395 x: self.x - rhs.x,
396 y: self.y - rhs.y,
397 }
398 }
399}
400
401impl Mul<Self> for Vec2 {
403 type Output = Self;
404
405 #[inline(always)]
406 fn mul(self, vec: Self) -> Self {
407 Self {
408 x: self.x * vec.x,
409 y: self.y * vec.y,
410 }
411 }
412}
413
414impl Div<Self> for Vec2 {
416 type Output = Self;
417
418 #[inline(always)]
419 fn div(self, rhs: Self) -> Self {
420 Self {
421 x: self.x / rhs.x,
422 y: self.y / rhs.y,
423 }
424 }
425}
426
427impl MulAssign<f32> for Vec2 {
428 #[inline(always)]
429 fn mul_assign(&mut self, rhs: f32) {
430 self.x *= rhs;
431 self.y *= rhs;
432 }
433}
434
435impl DivAssign<f32> for Vec2 {
436 #[inline(always)]
437 fn div_assign(&mut self, rhs: f32) {
438 self.x /= rhs;
439 self.y /= rhs;
440 }
441}
442
443impl Mul<f32> for Vec2 {
444 type Output = Self;
445
446 #[inline(always)]
447 fn mul(self, factor: f32) -> Self {
448 Self {
449 x: self.x * factor,
450 y: self.y * factor,
451 }
452 }
453}
454
455impl Mul<Vec2> for f32 {
456 type Output = Vec2;
457
458 #[inline(always)]
459 fn mul(self, vec: Vec2) -> Vec2 {
460 Vec2 {
461 x: self * vec.x,
462 y: self * vec.y,
463 }
464 }
465}
466
467impl Div<f32> for Vec2 {
468 type Output = Self;
469
470 #[inline(always)]
471 fn div(self, factor: f32) -> Self {
472 Self {
473 x: self.x / factor,
474 y: self.y / factor,
475 }
476 }
477}
478
479impl fmt::Debug for Vec2 {
480 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
481 if let Some(precision) = f.precision() {
482 write!(f, "[{1:.0$} {2:.0$}]", precision, self.x, self.y)
483 } else {
484 write!(f, "[{:.1} {:.1}]", self.x, self.y)
485 }
486 }
487}
488
489impl fmt::Display for Vec2 {
490 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
491 f.write_str("[")?;
492 self.x.fmt(f)?;
493 f.write_str(" ")?;
494 self.y.fmt(f)?;
495 f.write_str("]")?;
496 Ok(())
497 }
498}
499
500#[test]
501fn test_vec2() {
502 macro_rules! almost_eq {
503 ($left: expr, $right: expr) => {
504 let left = $left;
505 let right = $right;
506 assert!((left - right).abs() < 1e-6, "{} != {}", left, right);
507 };
508 }
509 use std::f32::consts::TAU;
510
511 assert_eq!(Vec2::ZERO.angle(), 0.0);
512 assert_eq!(Vec2::angled(0.0).angle(), 0.0);
513 assert_eq!(Vec2::angled(1.0).angle(), 1.0);
514 assert_eq!(Vec2::X.angle(), 0.0);
515 assert_eq!(Vec2::Y.angle(), 0.25 * TAU);
516
517 assert_eq!(Vec2::RIGHT.angle(), 0.0);
518 assert_eq!(Vec2::DOWN.angle(), 0.25 * TAU);
519 almost_eq!(Vec2::LEFT.angle(), 0.50 * TAU);
520 assert_eq!(Vec2::UP.angle(), -0.25 * TAU);
521
522 let mut assignment = vec2(1.0, 2.0);
523 assignment += vec2(3.0, 4.0);
524 assert_eq!(assignment, vec2(4.0, 6.0));
525
526 let mut assignment = vec2(4.0, 6.0);
527 assignment -= vec2(1.0, 2.0);
528 assert_eq!(assignment, vec2(3.0, 4.0));
529
530 let mut assignment = vec2(1.0, 2.0);
531 assignment *= 2.0;
532 assert_eq!(assignment, vec2(2.0, 4.0));
533
534 let mut assignment = vec2(2.0, 4.0);
535 assignment /= 2.0;
536 assert_eq!(assignment, vec2(1.0, 2.0));
537}