1use std::{
2 f64::{self, consts::PI},
3 fmt,
4 ops::{Add, Div, Mul, Sub},
5};
6
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9use crate::utils::round_precision;
10
11macro_rules! as_serde_tuple {
13 ($(#[$smeta:meta])*
14 $svis:vis struct $sname:ident {
15 $($fvis:vis $fname:ident : $ftype:ty,)*
16 }) => {
17 $(#[$smeta])*
18 $svis struct $sname {
19 $($fvis $fname : $ftype,)*
20 }
21
22 impl<'de> Deserialize<'de> for $sname {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where D: Deserializer<'de>
25 {
26 #[derive(Deserialize, Serialize)]
27 pub struct Array($(pub $ftype,)*);
28
29 Deserialize::deserialize(deserializer)
30 .map(|Array($($fname,)*)| Self { $($fname,)* })
31 }
32 }
33
34 impl Serialize for $sname {
35 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
36 where
37 S: Serializer,
38 {
39 #[derive(Deserialize, Serialize)]
40 pub struct Array($(pub $ftype,)*);
41
42 (Array($(self.$fname.clone(),)*)).serialize(serializer)
43 }
44 }
45 }
46}
47
48as_serde_tuple! {
49 #[allow(missing_docs)]
50 #[derive(Default, Debug, PartialEq, Clone, Copy)]
52 pub struct Vector2 {
53 pub x: f64,
54 pub y: f64,
55
56 }
57}
58
59impl Vector2 {
60 pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
62
63 pub const MIN: Self = Self {
65 x: f64::MIN,
66 y: f64::MIN,
67 };
68
69 pub const MAX: Self = Self {
71 x: f64::MAX,
72 y: f64::MAX,
73 };
74
75 #[must_use]
77 pub fn new(x: f64, y: f64) -> Self {
78 Self { x, y }
79 }
80
81 #[must_use]
83 pub fn splat(value: f64) -> Self {
84 Self { x: value, y: value }
85 }
86
87 #[must_use]
89 #[deprecated]
90 pub fn min() -> Self {
91 Self {
92 x: f64::MIN,
93 y: f64::MIN,
94 }
95 }
96
97 #[must_use]
99 #[deprecated]
100 pub fn max() -> Self {
101 Self {
102 x: f64::MAX,
103 y: f64::MAX,
104 }
105 }
106
107 #[must_use]
109 pub fn distance_to(&self, to: Self) -> f64 {
110 ((self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y)).sqrt()
111 }
112
113 #[must_use]
115 pub fn angle(&self) -> f64 {
116 (-self.x).atan2(-self.y) + PI
117 }
118
119 #[must_use]
121 pub fn angle_degrees(&self) -> f64 {
122 self.angle().to_degrees()
123 }
124
125 #[must_use]
127 pub fn add_x(&self, value: f64) -> Self {
128 let mut vector = *self;
129 vector.x += value;
130 vector
131 }
132
133 #[must_use]
135 pub fn add_y(&self, value: f64) -> Self {
136 let mut vector = *self;
137 vector.y += value;
138 vector
139 }
140
141 #[must_use]
143 pub fn with_x(&self, value: f64) -> Self {
144 let mut vector = *self;
145 vector.x = value;
146 vector
147 }
148
149 #[must_use]
151 pub fn with_y(&self, value: f64) -> Self {
152 let mut vector = *self;
153 vector.y = value;
154 vector
155 }
156}
157
158impl Add for Vector2 {
159 type Output = Vector2;
160
161 fn add(self, rhs: Vector2) -> Vector2 {
162 Vector2 {
163 x: self.x + rhs.x,
164 y: self.y + rhs.y,
165 }
166 }
167}
168
169impl Sub for Vector2 {
170 type Output = Vector2;
171
172 fn sub(self, rhs: Vector2) -> Vector2 {
173 Vector2 {
174 x: self.x - rhs.x,
175 y: self.y - rhs.y,
176 }
177 }
178}
179
180impl Mul for Vector2 {
181 type Output = Vector2;
182
183 fn mul(self, rhs: Vector2) -> Vector2 {
184 Vector2 {
185 x: self.x * rhs.x,
186 y: self.y * rhs.y,
187 }
188 }
189}
190
191impl Div for Vector2 {
192 type Output = Vector2;
193
194 fn div(self, rhs: Vector2) -> Vector2 {
195 Vector2 {
196 x: self.x / rhs.x,
197 y: self.y / rhs.y,
198 }
199 }
200}
201
202impl fmt::Display for Vector2 {
203 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
204 write!(
205 formatter,
206 "{{x: {}, y: {}}}",
207 round_precision(self.x),
208 round_precision(self.y)
209 )
210 }
211}
212
213#[cfg(feature = "glam")]
214impl From<glam::Vec2> for Vector2 {
215 fn from(value: glam::Vec2) -> Self {
216 Self {
217 x: value.x as f64,
218 y: value.y as f64,
219 }
220 }
221}
222
223#[cfg(feature = "glam")]
224impl From<Vector2> for glam::Vec2 {
225 fn from(value: Vector2) -> Self {
226 Self {
227 x: value.x as f32,
228 y: value.y as f32,
229 }
230 }
231}
232
233#[cfg(feature = "glam")]
234impl From<glam::DVec2> for Vector2 {
235 fn from(value: glam::DVec2) -> Self {
236 Self {
237 x: value.x,
238 y: value.y,
239 }
240 }
241}
242
243#[cfg(feature = "glam")]
244impl From<Vector2> for glam::DVec2 {
245 fn from(value: Vector2) -> Self {
246 Self {
247 x: value.x,
248 y: value.y,
249 }
250 }
251}
252
253#[cfg(feature = "nalgebra")]
254impl From<nalgebra::Point2<f32>> for Vector2 {
255 fn from(value: nalgebra::Point2<f32>) -> Self {
256 Self {
257 x: value.x as f64,
258 y: value.y as f64,
259 }
260 }
261}
262
263#[cfg(feature = "nalgebra")]
264impl From<Vector2> for nalgebra::Point2<f32> {
265 fn from(value: Vector2) -> Self {
266 Self::new(value.x as f32, value.y as f32)
267 }
268}
269
270#[cfg(feature = "nalgebra")]
271impl From<nalgebra::Point2<f64>> for Vector2 {
272 fn from(value: nalgebra::Point2<f64>) -> Self {
273 Self {
274 x: value.x,
275 y: value.y,
276 }
277 }
278}
279
280#[cfg(feature = "nalgebra")]
281impl From<Vector2> for nalgebra::Point2<f64> {
282 fn from(value: Vector2) -> Self {
283 Self::new(value.x, value.y)
284 }
285}
286
287as_serde_tuple! {
288 #[allow(missing_docs)]
289 #[derive(Default, Debug, PartialEq, Clone, Copy)]
291 pub struct Vector3 {
292 pub x: f64,
293 pub y: f64,
294 pub z: f64,
295 }
296}
297
298impl Vector3 {
299 pub const ZERO: Self = Self {
301 x: 0.0,
302 y: 0.0,
303 z: 0.0,
304 };
305
306 pub const MIN: Self = Self {
308 x: f64::MIN,
309 y: f64::MIN,
310 z: f64::MIN,
311 };
312
313 pub const MAX: Self = Self {
315 x: f64::MAX,
316 y: f64::MAX,
317 z: f64::MAX,
318 };
319
320 #[must_use]
322 pub fn new(x: f64, y: f64, z: f64) -> Self {
323 Self { x, y, z }
324 }
325
326 #[must_use]
328 pub fn splat(value: f64) -> Self {
329 Self {
330 x: value,
331 y: value,
332 z: value,
333 }
334 }
335
336 #[must_use]
338 #[deprecated]
339 pub fn min() -> Self {
340 Self {
341 x: f64::MIN,
342 y: f64::MIN,
343 z: f64::MIN,
344 }
345 }
346
347 #[must_use]
349 #[deprecated]
350 pub fn max() -> Self {
351 Self {
352 x: f64::MAX,
353 y: f64::MAX,
354 z: f64::MAX,
355 }
356 }
357
358 #[must_use]
360 pub fn distance_to(&self, to: Self) -> f64 {
361 ((self.x - to.x) * (self.x - to.x)
362 + (self.y - to.y) * (self.y - to.y)
363 + (self.z - to.z) * (self.z - to.z))
364 .sqrt()
365 }
366
367 #[must_use]
369 pub fn xy(&self) -> Vector2 {
370 Vector2::new(self.x, self.y)
371 }
372
373 #[must_use]
375 pub fn xz(&self) -> Vector2 {
376 Vector2::new(self.x, self.z)
377 }
378
379 #[must_use]
381 pub fn yz(&self) -> Vector2 {
382 Vector2::new(self.y, self.z)
383 }
384
385 #[must_use]
387 pub fn add_x(&self, value: f64) -> Self {
388 let mut vector = *self;
389 vector.x += value;
390 vector
391 }
392
393 #[must_use]
395 pub fn add_y(&self, value: f64) -> Self {
396 let mut vector = *self;
397 vector.y += value;
398 vector
399 }
400
401 #[must_use]
403 pub fn add_z(&self, value: f64) -> Self {
404 let mut vector = *self;
405 vector.z += value;
406 vector
407 }
408
409 #[must_use]
411 pub fn with_x(&self, value: f64) -> Self {
412 let mut vector = *self;
413 vector.x = value;
414 vector
415 }
416
417 #[must_use]
419 pub fn with_y(&self, value: f64) -> Self {
420 let mut vector = *self;
421 vector.y = value;
422 vector
423 }
424
425 #[must_use]
427 pub fn with_z(&self, value: f64) -> Self {
428 let mut vector = *self;
429 vector.z = value;
430 vector
431 }
432}
433
434impl Add for Vector3 {
435 type Output = Vector3;
436
437 fn add(self, rhs: Vector3) -> Vector3 {
438 Vector3 {
439 x: self.x + rhs.x,
440 y: self.y + rhs.y,
441 z: self.z + rhs.z,
442 }
443 }
444}
445
446impl Sub for Vector3 {
447 type Output = Vector3;
448
449 fn sub(self, rhs: Vector3) -> Vector3 {
450 Vector3 {
451 x: self.x - rhs.x,
452 y: self.y - rhs.y,
453 z: self.z - rhs.z,
454 }
455 }
456}
457
458impl Mul for Vector3 {
459 type Output = Vector3;
460
461 fn mul(self, rhs: Vector3) -> Vector3 {
462 Vector3 {
463 x: self.x * rhs.x,
464 y: self.y * rhs.y,
465 z: self.z * rhs.z,
466 }
467 }
468}
469
470impl Div for Vector3 {
471 type Output = Vector3;
472
473 fn div(self, rhs: Vector3) -> Vector3 {
474 Vector3 {
475 x: self.x / rhs.x,
476 y: self.y / rhs.y,
477 z: self.z / rhs.z,
478 }
479 }
480}
481
482impl fmt::Display for Vector3 {
483 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
484 write!(
485 formatter,
486 "{{x: {}, y: {}, z: {}}}",
487 round_precision(self.x),
488 round_precision(self.y),
489 round_precision(self.z)
490 )
491 }
492}
493
494#[cfg(feature = "glam")]
495impl From<glam::Vec3> for Vector3 {
496 fn from(value: glam::Vec3) -> Self {
497 Self {
498 x: value.x as f64,
499 y: value.y as f64,
500 z: value.z as f64,
501 }
502 }
503}
504
505#[cfg(feature = "glam")]
506impl From<Vector3> for glam::Vec3 {
507 fn from(value: Vector3) -> Self {
508 Self {
509 x: value.x as f32,
510 y: value.y as f32,
511 z: value.z as f32,
512 }
513 }
514}
515
516#[cfg(feature = "glam")]
517impl From<glam::DVec3> for Vector3 {
518 fn from(value: glam::DVec3) -> Self {
519 Self {
520 x: value.x,
521 y: value.y,
522 z: value.z,
523 }
524 }
525}
526
527#[cfg(feature = "glam")]
528impl From<Vector3> for glam::DVec3 {
529 fn from(value: Vector3) -> Self {
530 Self {
531 x: value.x,
532 y: value.y,
533 z: value.z,
534 }
535 }
536}
537
538#[cfg(feature = "nalgebra")]
539impl From<nalgebra::Point3<f32>> for Vector3 {
540 fn from(value: nalgebra::Point3<f32>) -> Self {
541 Self {
542 x: value.x as f64,
543 y: value.y as f64,
544 z: value.z as f64,
545 }
546 }
547}
548
549#[cfg(feature = "nalgebra")]
550impl From<Vector3> for nalgebra::Point3<f32> {
551 fn from(value: Vector3) -> Self {
552 Self::new(value.x as f32, value.y as f32, value.z as f32)
553 }
554}
555
556#[cfg(feature = "nalgebra")]
557impl From<nalgebra::Point3<f64>> for Vector3 {
558 fn from(value: nalgebra::Point3<f64>) -> Self {
559 Self {
560 x: value.x,
561 y: value.y,
562 z: value.z,
563 }
564 }
565}
566
567#[cfg(feature = "nalgebra")]
568impl From<Vector3> for nalgebra::Point3<f64> {
569 fn from(value: Vector3) -> Self {
570 Self::new(value.x, value.y, value.z)
571 }
572}
573
574#[cfg(test)]
575mod tests {
576 use super::*;
577
578 #[test]
579 fn test_vector3_min() {
580 let vector = Vector3::MIN;
581 assert!(vector.x == f64::MIN);
582 assert!(vector.y == f64::MIN);
583 assert!(vector.z == f64::MIN);
584 }
585
586 #[test]
587 fn test_vector3_max() {
588 let vector = Vector3::MAX;
589 assert!(vector.x == f64::MAX);
590 assert!(vector.y == f64::MAX);
591 assert!(vector.z == f64::MAX);
592 }
593
594 #[test]
595 fn test_vector3_xy_xz_yz() {
596 let vector = Vector3::new(1.0, 2.0, 3.0);
597 assert!(vector.xy() == Vector2::new(1.0, 2.0));
598 assert!(vector.xz() == Vector2::new(1.0, 3.0));
599 assert!(vector.yz() == Vector2::new(2.0, 3.0));
600 }
601
602 #[test]
603 fn test_vector3_add_xyz() {
604 let vector = Vector3::default();
605
606 let vector = vector.add_x(1.0);
607 assert!(vector.x == 1.0);
608 assert!(vector.y == 0.0);
609 assert!(vector.z == 0.0);
610
611 let vector = vector.add_y(-1.0);
612 assert!(vector.x == 1.0);
613 assert!(vector.y == -1.0);
614 assert!(vector.z == 0.0);
615
616 let vector = vector.add_z(3.0);
617 assert!(vector.x == 1.0);
618 assert!(vector.y == -1.0);
619 assert!(vector.z == 3.0);
620 }
621
622 #[test]
623 fn test_vector2_min() {
624 let vector = Vector2::MIN;
625 assert!(vector.x == f64::MIN);
626 assert!(vector.y == f64::MIN);
627 }
628
629 #[test]
630 fn test_vector2_max() {
631 let vector = Vector2::MAX;
632 assert!(vector.x == f64::MAX);
633 assert!(vector.y == f64::MAX);
634 }
635
636 #[test]
637 fn test_vector2_add_xyz() {
638 let vector = Vector2::default();
639
640 let vector = vector.add_x(1.0);
641 assert!(vector.x == 1.0);
642 assert!(vector.y == 0.0);
643
644 let vector = vector.add_y(-1.0);
645 assert!(vector.x == 1.0);
646 assert!(vector.y == -1.0);
647 }
648
649 #[test]
650 fn test_vector2_distance_to() {
651 let vector_a = Vector2::new(20.0, 40.0);
652 let vector_b = Vector2::new(20.0, 20.0);
653 assert!(vector_a.distance_to(vector_b) == 20.0);
654 }
655
656 #[test]
657 fn test_vector2_angle() {
658 let vector = Vector2::new(20.0, 0.0);
659 assert!(vector.angle() == f64::consts::PI / 2.0);
660 }
661
662 #[test]
663 fn test_vector2_angle_degree() {
664 let vector = Vector2::new(20.0, 20.0);
665 assert!(vector.angle_degrees() == 45.0);
666 }
667
668 #[cfg(feature = "glam")]
669 #[test]
670 fn test_glam_from_into() {
671 let v = Vector3::new(23.1, 5.0, 0.0);
672
673 let b: glam::DVec3 = v.into();
674 assert_eq!(b, glam::DVec3::new(23.1, 5.0, 0.0));
675
676 let c = Vector3::from(b);
677 assert_eq!(c, v);
678
679 let d: glam::Vec3 = c.into();
680 assert_eq!(d, glam::Vec3::new(23.1, 5.0, 0.0));
681
682 let v = Vector2::new(23.1, 5.0);
683
684 let b: glam::DVec2 = v.into();
685 assert_eq!(b, glam::DVec2::new(23.1, 5.0));
686
687 let c = Vector2::from(b);
688 assert_eq!(c, v);
689
690 let d: glam::Vec2 = c.into();
691 assert_eq!(d, glam::Vec2::new(23.1, 5.0));
692 }
693
694 #[cfg(feature = "nalgebra")]
695 #[test]
696 fn test_nalgebra_from_into() {
697 let v = Vector3::new(23.1, 5.0, 0.0);
698
699 let b: nalgebra::Point3<f64> = v.into();
700 assert_eq!(b, nalgebra::Point3::new(23.1, 5.0, 0.0));
701
702 let c = Vector3::from(b);
703 assert_eq!(c, v);
704
705 let d: nalgebra::Point3<f32> = c.into();
706 assert_eq!(d, nalgebra::Point3::new(23.1, 5.0, 0.0));
707
708 let v = Vector2::new(23.1, 5.0);
709
710 let b: nalgebra::Point2<f64> = v.into();
711 assert_eq!(b, nalgebra::Point2::new(23.1, 5.0));
712
713 let c = Vector2::from(b);
714 assert_eq!(c, v);
715
716 let d: nalgebra::Point2<f32> = c.into();
717 assert_eq!(d, nalgebra::Point2::new(23.1, 5.0));
718 }
719}