1use crate::{f64::math, BVec2, DVec3, IVec2, UVec2, Vec2};
4
5#[cfg(not(target_arch = "spirv"))]
6use core::fmt;
7use core::iter::{Product, Sum};
8use core::{f32, ops::*};
9
10#[inline(always)]
12#[must_use]
13pub const fn dvec2(x: f64, y: f64) -> DVec2 {
14 DVec2::new(x, y)
15}
16
17#[derive(Clone, Copy, PartialEq)]
19#[cfg_attr(feature = "cuda", repr(align(16)))]
20#[cfg_attr(not(target_arch = "spirv"), repr(C))]
21#[cfg_attr(target_arch = "spirv", repr(simd))]
22pub struct DVec2 {
23 pub x: f64,
24 pub y: f64,
25}
26
27impl DVec2 {
28 pub const ZERO: Self = Self::splat(0.0);
30
31 pub const ONE: Self = Self::splat(1.0);
33
34 pub const NEG_ONE: Self = Self::splat(-1.0);
36
37 pub const MIN: Self = Self::splat(f64::MIN);
39
40 pub const MAX: Self = Self::splat(f64::MAX);
42
43 pub const NAN: Self = Self::splat(f64::NAN);
45
46 pub const INFINITY: Self = Self::splat(f64::INFINITY);
48
49 pub const NEG_INFINITY: Self = Self::splat(f64::NEG_INFINITY);
51
52 pub const X: Self = Self::new(1.0, 0.0);
54
55 pub const Y: Self = Self::new(0.0, 1.0);
57
58 pub const NEG_X: Self = Self::new(-1.0, 0.0);
60
61 pub const NEG_Y: Self = Self::new(0.0, -1.0);
63
64 pub const AXES: [Self; 2] = [Self::X, Self::Y];
66
67 #[inline(always)]
69 #[must_use]
70 pub const fn new(x: f64, y: f64) -> Self {
71 Self { x, y }
72 }
73
74 #[inline]
76 #[must_use]
77 pub const fn splat(v: f64) -> Self {
78 Self { x: v, y: v }
79 }
80
81 #[inline]
87 #[must_use]
88 pub fn select(mask: BVec2, if_true: Self, if_false: Self) -> Self {
89 Self {
90 x: if mask.test(0) { if_true.x } else { if_false.x },
91 y: if mask.test(1) { if_true.y } else { if_false.y },
92 }
93 }
94
95 #[inline]
97 #[must_use]
98 pub const fn from_array(a: [f64; 2]) -> Self {
99 Self::new(a[0], a[1])
100 }
101
102 #[inline]
104 #[must_use]
105 pub const fn to_array(&self) -> [f64; 2] {
106 [self.x, self.y]
107 }
108
109 #[inline]
115 #[must_use]
116 pub const fn from_slice(slice: &[f64]) -> Self {
117 Self::new(slice[0], slice[1])
118 }
119
120 #[inline]
126 pub fn write_to_slice(self, slice: &mut [f64]) {
127 slice[0] = self.x;
128 slice[1] = self.y;
129 }
130
131 #[inline]
133 #[must_use]
134 pub const fn extend(self, z: f64) -> DVec3 {
135 DVec3::new(self.x, self.y, z)
136 }
137
138 #[inline]
140 #[must_use]
141 pub fn dot(self, rhs: Self) -> f64 {
142 (self.x * rhs.x) + (self.y * rhs.y)
143 }
144
145 #[inline]
147 #[must_use]
148 pub fn dot_into_vec(self, rhs: Self) -> Self {
149 Self::splat(self.dot(rhs))
150 }
151
152 #[inline]
156 #[must_use]
157 pub fn min(self, rhs: Self) -> Self {
158 Self {
159 x: self.x.min(rhs.x),
160 y: self.y.min(rhs.y),
161 }
162 }
163
164 #[inline]
168 #[must_use]
169 pub fn max(self, rhs: Self) -> Self {
170 Self {
171 x: self.x.max(rhs.x),
172 y: self.y.max(rhs.y),
173 }
174 }
175
176 #[inline]
184 #[must_use]
185 pub fn clamp(self, min: Self, max: Self) -> Self {
186 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
187 self.max(min).min(max)
188 }
189
190 #[inline]
194 #[must_use]
195 pub fn min_element(self) -> f64 {
196 self.x.min(self.y)
197 }
198
199 #[inline]
203 #[must_use]
204 pub fn max_element(self) -> f64 {
205 self.x.max(self.y)
206 }
207
208 #[inline]
214 #[must_use]
215 pub fn cmpeq(self, rhs: Self) -> BVec2 {
216 BVec2::new(self.x.eq(&rhs.x), self.y.eq(&rhs.y))
217 }
218
219 #[inline]
225 #[must_use]
226 pub fn cmpne(self, rhs: Self) -> BVec2 {
227 BVec2::new(self.x.ne(&rhs.x), self.y.ne(&rhs.y))
228 }
229
230 #[inline]
236 #[must_use]
237 pub fn cmpge(self, rhs: Self) -> BVec2 {
238 BVec2::new(self.x.ge(&rhs.x), self.y.ge(&rhs.y))
239 }
240
241 #[inline]
247 #[must_use]
248 pub fn cmpgt(self, rhs: Self) -> BVec2 {
249 BVec2::new(self.x.gt(&rhs.x), self.y.gt(&rhs.y))
250 }
251
252 #[inline]
258 #[must_use]
259 pub fn cmple(self, rhs: Self) -> BVec2 {
260 BVec2::new(self.x.le(&rhs.x), self.y.le(&rhs.y))
261 }
262
263 #[inline]
269 #[must_use]
270 pub fn cmplt(self, rhs: Self) -> BVec2 {
271 BVec2::new(self.x.lt(&rhs.x), self.y.lt(&rhs.y))
272 }
273
274 #[inline]
276 #[must_use]
277 pub fn abs(self) -> Self {
278 Self {
279 x: math::abs(self.x),
280 y: math::abs(self.y),
281 }
282 }
283
284 #[inline]
290 #[must_use]
291 pub fn signum(self) -> Self {
292 Self {
293 x: math::signum(self.x),
294 y: math::signum(self.y),
295 }
296 }
297
298 #[inline]
300 #[must_use]
301 pub fn copysign(self, rhs: Self) -> Self {
302 Self {
303 x: math::copysign(self.x, rhs.x),
304 y: math::copysign(self.y, rhs.y),
305 }
306 }
307
308 #[inline]
313 #[must_use]
314 pub fn is_negative_bitmask(self) -> u32 {
315 (self.x.is_sign_negative() as u32) | (self.y.is_sign_negative() as u32) << 1
316 }
317
318 #[inline]
321 #[must_use]
322 pub fn is_finite(self) -> bool {
323 self.x.is_finite() && self.y.is_finite()
324 }
325
326 #[inline]
328 #[must_use]
329 pub fn is_nan(self) -> bool {
330 self.x.is_nan() || self.y.is_nan()
331 }
332
333 #[inline]
337 #[must_use]
338 pub fn is_nan_mask(self) -> BVec2 {
339 BVec2::new(self.x.is_nan(), self.y.is_nan())
340 }
341
342 #[doc(alias = "magnitude")]
344 #[inline]
345 #[must_use]
346 pub fn length(self) -> f64 {
347 math::sqrt(self.dot(self))
348 }
349
350 #[doc(alias = "magnitude2")]
354 #[inline]
355 #[must_use]
356 pub fn length_squared(self) -> f64 {
357 self.dot(self)
358 }
359
360 #[inline]
364 #[must_use]
365 pub fn length_recip(self) -> f64 {
366 self.length().recip()
367 }
368
369 #[inline]
371 #[must_use]
372 pub fn distance(self, rhs: Self) -> f64 {
373 (self - rhs).length()
374 }
375
376 #[inline]
378 #[must_use]
379 pub fn distance_squared(self, rhs: Self) -> f64 {
380 (self - rhs).length_squared()
381 }
382
383 #[inline]
385 #[must_use]
386 pub fn div_euclid(self, rhs: Self) -> Self {
387 Self::new(
388 math::div_euclid(self.x, rhs.x),
389 math::div_euclid(self.y, rhs.y),
390 )
391 }
392
393 #[inline]
397 #[must_use]
398 pub fn rem_euclid(self, rhs: Self) -> Self {
399 Self::new(
400 math::rem_euclid(self.x, rhs.x),
401 math::rem_euclid(self.y, rhs.y),
402 )
403 }
404
405 #[inline]
415 #[must_use]
416 pub fn normalize(self) -> Self {
417 #[allow(clippy::let_and_return)]
418 let normalized = self.mul(self.length_recip());
419 glam_assert!(normalized.is_finite());
420 normalized
421 }
422
423 #[inline]
430 #[must_use]
431 pub fn try_normalize(self) -> Option<Self> {
432 let rcp = self.length_recip();
433 if rcp.is_finite() && rcp > 0.0 {
434 Some(self * rcp)
435 } else {
436 None
437 }
438 }
439
440 #[inline]
447 #[must_use]
448 pub fn normalize_or_zero(self) -> Self {
449 let rcp = self.length_recip();
450 if rcp.is_finite() && rcp > 0.0 {
451 self * rcp
452 } else {
453 Self::ZERO
454 }
455 }
456
457 #[inline]
461 #[must_use]
462 pub fn is_normalized(self) -> bool {
463 math::abs(self.length_squared() - 1.0) <= 1e-4
465 }
466
467 #[inline]
475 #[must_use]
476 pub fn project_onto(self, rhs: Self) -> Self {
477 let other_len_sq_rcp = rhs.dot(rhs).recip();
478 glam_assert!(other_len_sq_rcp.is_finite());
479 rhs * self.dot(rhs) * other_len_sq_rcp
480 }
481
482 #[inline]
493 #[must_use]
494 pub fn reject_from(self, rhs: Self) -> Self {
495 self - self.project_onto(rhs)
496 }
497
498 #[inline]
506 #[must_use]
507 pub fn project_onto_normalized(self, rhs: Self) -> Self {
508 glam_assert!(rhs.is_normalized());
509 rhs * self.dot(rhs)
510 }
511
512 #[inline]
523 #[must_use]
524 pub fn reject_from_normalized(self, rhs: Self) -> Self {
525 self - self.project_onto_normalized(rhs)
526 }
527
528 #[inline]
531 #[must_use]
532 pub fn round(self) -> Self {
533 Self {
534 x: math::round(self.x),
535 y: math::round(self.y),
536 }
537 }
538
539 #[inline]
542 #[must_use]
543 pub fn floor(self) -> Self {
544 Self {
545 x: math::floor(self.x),
546 y: math::floor(self.y),
547 }
548 }
549
550 #[inline]
553 #[must_use]
554 pub fn ceil(self) -> Self {
555 Self {
556 x: math::ceil(self.x),
557 y: math::ceil(self.y),
558 }
559 }
560
561 #[inline]
564 #[must_use]
565 pub fn trunc(self) -> Self {
566 Self {
567 x: math::trunc(self.x),
568 y: math::trunc(self.y),
569 }
570 }
571
572 #[inline]
577 #[must_use]
578 pub fn fract(self) -> Self {
579 self - self.floor()
580 }
581
582 #[inline]
585 #[must_use]
586 pub fn exp(self) -> Self {
587 Self::new(math::exp(self.x), math::exp(self.y))
588 }
589
590 #[inline]
592 #[must_use]
593 pub fn powf(self, n: f64) -> Self {
594 Self::new(math::powf(self.x, n), math::powf(self.y, n))
595 }
596
597 #[inline]
599 #[must_use]
600 pub fn recip(self) -> Self {
601 Self {
602 x: 1.0 / self.x,
603 y: 1.0 / self.y,
604 }
605 }
606
607 #[doc(alias = "mix")]
613 #[inline]
614 #[must_use]
615 pub fn lerp(self, rhs: Self, s: f64) -> Self {
616 self + ((rhs - self) * s)
617 }
618
619 #[inline]
629 #[must_use]
630 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
631 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
632 }
633
634 #[inline]
640 #[must_use]
641 pub fn clamp_length(self, min: f64, max: f64) -> Self {
642 glam_assert!(min <= max);
643 let length_sq = self.length_squared();
644 if length_sq < min * min {
645 min * (self / math::sqrt(length_sq))
646 } else if length_sq > max * max {
647 max * (self / math::sqrt(length_sq))
648 } else {
649 self
650 }
651 }
652
653 #[inline]
655 #[must_use]
656 pub fn clamp_length_max(self, max: f64) -> Self {
657 let length_sq = self.length_squared();
658 if length_sq > max * max {
659 max * (self / math::sqrt(length_sq))
660 } else {
661 self
662 }
663 }
664
665 #[inline]
667 #[must_use]
668 pub fn clamp_length_min(self, min: f64) -> Self {
669 let length_sq = self.length_squared();
670 if length_sq < min * min {
671 min * (self / math::sqrt(length_sq))
672 } else {
673 self
674 }
675 }
676
677 #[inline]
685 #[must_use]
686 pub fn mul_add(self, a: Self, b: Self) -> Self {
687 Self::new(
688 math::mul_add(self.x, a.x, b.x),
689 math::mul_add(self.y, a.y, b.y),
690 )
691 }
692
693 #[inline]
698 #[must_use]
699 pub fn from_angle(angle: f64) -> Self {
700 let (sin, cos) = math::sin_cos(angle);
701 Self { x: cos, y: sin }
702 }
703
704 #[inline]
708 #[must_use]
709 pub fn to_angle(self) -> f64 {
710 math::atan2(self.y, self.x)
711 }
712
713 #[inline]
717 #[must_use]
718 pub fn angle_between(self, rhs: Self) -> f64 {
719 let angle = math::acos_approx(
720 self.dot(rhs) / math::sqrt(self.length_squared() * rhs.length_squared()),
721 );
722
723 angle * math::signum(self.perp_dot(rhs))
724 }
725
726 #[inline]
728 #[must_use]
729 pub fn perp(self) -> Self {
730 Self {
731 x: -self.y,
732 y: self.x,
733 }
734 }
735
736 #[doc(alias = "wedge")]
739 #[doc(alias = "cross")]
740 #[doc(alias = "determinant")]
741 #[inline]
742 #[must_use]
743 pub fn perp_dot(self, rhs: Self) -> f64 {
744 (self.x * rhs.y) - (self.y * rhs.x)
745 }
746
747 #[inline]
751 #[must_use]
752 pub fn rotate(self, rhs: Self) -> Self {
753 Self {
754 x: self.x * rhs.x - self.y * rhs.y,
755 y: self.y * rhs.x + self.x * rhs.y,
756 }
757 }
758
759 #[inline]
761 #[must_use]
762 pub fn as_vec2(&self) -> crate::Vec2 {
763 crate::Vec2::new(self.x as f32, self.y as f32)
764 }
765
766 #[inline]
768 #[must_use]
769 pub fn as_i16vec2(&self) -> crate::I16Vec2 {
770 crate::I16Vec2::new(self.x as i16, self.y as i16)
771 }
772
773 #[inline]
775 #[must_use]
776 pub fn as_u16vec2(&self) -> crate::U16Vec2 {
777 crate::U16Vec2::new(self.x as u16, self.y as u16)
778 }
779
780 #[inline]
782 #[must_use]
783 pub fn as_ivec2(&self) -> crate::IVec2 {
784 crate::IVec2::new(self.x as i32, self.y as i32)
785 }
786
787 #[inline]
789 #[must_use]
790 pub fn as_uvec2(&self) -> crate::UVec2 {
791 crate::UVec2::new(self.x as u32, self.y as u32)
792 }
793
794 #[inline]
796 #[must_use]
797 pub fn as_i64vec2(&self) -> crate::I64Vec2 {
798 crate::I64Vec2::new(self.x as i64, self.y as i64)
799 }
800
801 #[inline]
803 #[must_use]
804 pub fn as_u64vec2(&self) -> crate::U64Vec2 {
805 crate::U64Vec2::new(self.x as u64, self.y as u64)
806 }
807}
808
809impl Default for DVec2 {
810 #[inline(always)]
811 fn default() -> Self {
812 Self::ZERO
813 }
814}
815
816impl Div<DVec2> for DVec2 {
817 type Output = Self;
818 #[inline]
819 fn div(self, rhs: Self) -> Self {
820 Self {
821 x: self.x.div(rhs.x),
822 y: self.y.div(rhs.y),
823 }
824 }
825}
826
827impl DivAssign<DVec2> for DVec2 {
828 #[inline]
829 fn div_assign(&mut self, rhs: Self) {
830 self.x.div_assign(rhs.x);
831 self.y.div_assign(rhs.y);
832 }
833}
834
835impl Div<f64> for DVec2 {
836 type Output = Self;
837 #[inline]
838 fn div(self, rhs: f64) -> Self {
839 Self {
840 x: self.x.div(rhs),
841 y: self.y.div(rhs),
842 }
843 }
844}
845
846impl DivAssign<f64> for DVec2 {
847 #[inline]
848 fn div_assign(&mut self, rhs: f64) {
849 self.x.div_assign(rhs);
850 self.y.div_assign(rhs);
851 }
852}
853
854impl Div<DVec2> for f64 {
855 type Output = DVec2;
856 #[inline]
857 fn div(self, rhs: DVec2) -> DVec2 {
858 DVec2 {
859 x: self.div(rhs.x),
860 y: self.div(rhs.y),
861 }
862 }
863}
864
865impl Mul<DVec2> for DVec2 {
866 type Output = Self;
867 #[inline]
868 fn mul(self, rhs: Self) -> Self {
869 Self {
870 x: self.x.mul(rhs.x),
871 y: self.y.mul(rhs.y),
872 }
873 }
874}
875
876impl MulAssign<DVec2> for DVec2 {
877 #[inline]
878 fn mul_assign(&mut self, rhs: Self) {
879 self.x.mul_assign(rhs.x);
880 self.y.mul_assign(rhs.y);
881 }
882}
883
884impl Mul<f64> for DVec2 {
885 type Output = Self;
886 #[inline]
887 fn mul(self, rhs: f64) -> Self {
888 Self {
889 x: self.x.mul(rhs),
890 y: self.y.mul(rhs),
891 }
892 }
893}
894
895impl MulAssign<f64> for DVec2 {
896 #[inline]
897 fn mul_assign(&mut self, rhs: f64) {
898 self.x.mul_assign(rhs);
899 self.y.mul_assign(rhs);
900 }
901}
902
903impl Mul<DVec2> for f64 {
904 type Output = DVec2;
905 #[inline]
906 fn mul(self, rhs: DVec2) -> DVec2 {
907 DVec2 {
908 x: self.mul(rhs.x),
909 y: self.mul(rhs.y),
910 }
911 }
912}
913
914impl Add<DVec2> for DVec2 {
915 type Output = Self;
916 #[inline]
917 fn add(self, rhs: Self) -> Self {
918 Self {
919 x: self.x.add(rhs.x),
920 y: self.y.add(rhs.y),
921 }
922 }
923}
924
925impl AddAssign<DVec2> for DVec2 {
926 #[inline]
927 fn add_assign(&mut self, rhs: Self) {
928 self.x.add_assign(rhs.x);
929 self.y.add_assign(rhs.y);
930 }
931}
932
933impl Add<f64> for DVec2 {
934 type Output = Self;
935 #[inline]
936 fn add(self, rhs: f64) -> Self {
937 Self {
938 x: self.x.add(rhs),
939 y: self.y.add(rhs),
940 }
941 }
942}
943
944impl AddAssign<f64> for DVec2 {
945 #[inline]
946 fn add_assign(&mut self, rhs: f64) {
947 self.x.add_assign(rhs);
948 self.y.add_assign(rhs);
949 }
950}
951
952impl Add<DVec2> for f64 {
953 type Output = DVec2;
954 #[inline]
955 fn add(self, rhs: DVec2) -> DVec2 {
956 DVec2 {
957 x: self.add(rhs.x),
958 y: self.add(rhs.y),
959 }
960 }
961}
962
963impl Sub<DVec2> for DVec2 {
964 type Output = Self;
965 #[inline]
966 fn sub(self, rhs: Self) -> Self {
967 Self {
968 x: self.x.sub(rhs.x),
969 y: self.y.sub(rhs.y),
970 }
971 }
972}
973
974impl SubAssign<DVec2> for DVec2 {
975 #[inline]
976 fn sub_assign(&mut self, rhs: DVec2) {
977 self.x.sub_assign(rhs.x);
978 self.y.sub_assign(rhs.y);
979 }
980}
981
982impl Sub<f64> for DVec2 {
983 type Output = Self;
984 #[inline]
985 fn sub(self, rhs: f64) -> Self {
986 Self {
987 x: self.x.sub(rhs),
988 y: self.y.sub(rhs),
989 }
990 }
991}
992
993impl SubAssign<f64> for DVec2 {
994 #[inline]
995 fn sub_assign(&mut self, rhs: f64) {
996 self.x.sub_assign(rhs);
997 self.y.sub_assign(rhs);
998 }
999}
1000
1001impl Sub<DVec2> for f64 {
1002 type Output = DVec2;
1003 #[inline]
1004 fn sub(self, rhs: DVec2) -> DVec2 {
1005 DVec2 {
1006 x: self.sub(rhs.x),
1007 y: self.sub(rhs.y),
1008 }
1009 }
1010}
1011
1012impl Rem<DVec2> for DVec2 {
1013 type Output = Self;
1014 #[inline]
1015 fn rem(self, rhs: Self) -> Self {
1016 Self {
1017 x: self.x.rem(rhs.x),
1018 y: self.y.rem(rhs.y),
1019 }
1020 }
1021}
1022
1023impl RemAssign<DVec2> for DVec2 {
1024 #[inline]
1025 fn rem_assign(&mut self, rhs: Self) {
1026 self.x.rem_assign(rhs.x);
1027 self.y.rem_assign(rhs.y);
1028 }
1029}
1030
1031impl Rem<f64> for DVec2 {
1032 type Output = Self;
1033 #[inline]
1034 fn rem(self, rhs: f64) -> Self {
1035 Self {
1036 x: self.x.rem(rhs),
1037 y: self.y.rem(rhs),
1038 }
1039 }
1040}
1041
1042impl RemAssign<f64> for DVec2 {
1043 #[inline]
1044 fn rem_assign(&mut self, rhs: f64) {
1045 self.x.rem_assign(rhs);
1046 self.y.rem_assign(rhs);
1047 }
1048}
1049
1050impl Rem<DVec2> for f64 {
1051 type Output = DVec2;
1052 #[inline]
1053 fn rem(self, rhs: DVec2) -> DVec2 {
1054 DVec2 {
1055 x: self.rem(rhs.x),
1056 y: self.rem(rhs.y),
1057 }
1058 }
1059}
1060
1061#[cfg(not(target_arch = "spirv"))]
1062impl AsRef<[f64; 2]> for DVec2 {
1063 #[inline]
1064 fn as_ref(&self) -> &[f64; 2] {
1065 unsafe { &*(self as *const DVec2 as *const [f64; 2]) }
1066 }
1067}
1068
1069#[cfg(not(target_arch = "spirv"))]
1070impl AsMut<[f64; 2]> for DVec2 {
1071 #[inline]
1072 fn as_mut(&mut self) -> &mut [f64; 2] {
1073 unsafe { &mut *(self as *mut DVec2 as *mut [f64; 2]) }
1074 }
1075}
1076
1077impl Sum for DVec2 {
1078 #[inline]
1079 fn sum<I>(iter: I) -> Self
1080 where
1081 I: Iterator<Item = Self>,
1082 {
1083 iter.fold(Self::ZERO, Self::add)
1084 }
1085}
1086
1087impl<'a> Sum<&'a Self> for DVec2 {
1088 #[inline]
1089 fn sum<I>(iter: I) -> Self
1090 where
1091 I: Iterator<Item = &'a Self>,
1092 {
1093 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1094 }
1095}
1096
1097impl Product for DVec2 {
1098 #[inline]
1099 fn product<I>(iter: I) -> Self
1100 where
1101 I: Iterator<Item = Self>,
1102 {
1103 iter.fold(Self::ONE, Self::mul)
1104 }
1105}
1106
1107impl<'a> Product<&'a Self> for DVec2 {
1108 #[inline]
1109 fn product<I>(iter: I) -> Self
1110 where
1111 I: Iterator<Item = &'a Self>,
1112 {
1113 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1114 }
1115}
1116
1117impl Neg for DVec2 {
1118 type Output = Self;
1119 #[inline]
1120 fn neg(self) -> Self {
1121 Self {
1122 x: self.x.neg(),
1123 y: self.y.neg(),
1124 }
1125 }
1126}
1127
1128impl Index<usize> for DVec2 {
1129 type Output = f64;
1130 #[inline]
1131 fn index(&self, index: usize) -> &Self::Output {
1132 match index {
1133 0 => &self.x,
1134 1 => &self.y,
1135 _ => panic!("index out of bounds"),
1136 }
1137 }
1138}
1139
1140impl IndexMut<usize> for DVec2 {
1141 #[inline]
1142 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1143 match index {
1144 0 => &mut self.x,
1145 1 => &mut self.y,
1146 _ => panic!("index out of bounds"),
1147 }
1148 }
1149}
1150
1151#[cfg(not(target_arch = "spirv"))]
1152impl fmt::Display for DVec2 {
1153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1154 write!(f, "[{}, {}]", self.x, self.y)
1155 }
1156}
1157
1158#[cfg(not(target_arch = "spirv"))]
1159impl fmt::Debug for DVec2 {
1160 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1161 fmt.debug_tuple(stringify!(DVec2))
1162 .field(&self.x)
1163 .field(&self.y)
1164 .finish()
1165 }
1166}
1167
1168impl From<[f64; 2]> for DVec2 {
1169 #[inline]
1170 fn from(a: [f64; 2]) -> Self {
1171 Self::new(a[0], a[1])
1172 }
1173}
1174
1175impl From<DVec2> for [f64; 2] {
1176 #[inline]
1177 fn from(v: DVec2) -> Self {
1178 [v.x, v.y]
1179 }
1180}
1181
1182impl From<(f64, f64)> for DVec2 {
1183 #[inline]
1184 fn from(t: (f64, f64)) -> Self {
1185 Self::new(t.0, t.1)
1186 }
1187}
1188
1189impl From<DVec2> for (f64, f64) {
1190 #[inline]
1191 fn from(v: DVec2) -> Self {
1192 (v.x, v.y)
1193 }
1194}
1195
1196impl From<Vec2> for DVec2 {
1197 #[inline]
1198 fn from(v: Vec2) -> Self {
1199 Self::new(f64::from(v.x), f64::from(v.y))
1200 }
1201}
1202
1203impl From<IVec2> for DVec2 {
1204 #[inline]
1205 fn from(v: IVec2) -> Self {
1206 Self::new(f64::from(v.x), f64::from(v.y))
1207 }
1208}
1209
1210impl From<UVec2> for DVec2 {
1211 #[inline]
1212 fn from(v: UVec2) -> Self {
1213 Self::new(f64::from(v.x), f64::from(v.y))
1214 }
1215}