1use core::iter::Sum;
2use core::ops::*;
3#[cfg(feature = "f64")]
4use glam::{DMat2, DVec2};
5use glam::{Mat2, Vec2};
6
7#[cfg(feature = "bevy_reflect")]
8use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize, std_traits::ReflectDefault};
9
10#[cfg(feature = "f64")]
11use crate::{DMat23, DMat32};
12#[cfg(feature = "f32")]
13use crate::{Mat23, Mat32};
14use crate::{MatConversionError, SquareMatExt, ops::FloatAbs};
15
16pub trait Mat2Ext {
18 type SymmetricMat2;
20
21 fn mul_symmetric_mat2(&self, rhs: &Self::SymmetricMat2) -> Self;
23
24 fn add_symmetric_mat2(&self, rhs: &Self::SymmetricMat2) -> Self;
26
27 fn sub_symmetric_mat2(&self, rhs: &Self::SymmetricMat2) -> Self;
29}
30
31#[cfg(feature = "f32")]
32impl Mat2Ext for Mat2 {
33 type SymmetricMat2 = SymmetricMat2;
34
35 #[inline]
36 fn mul_symmetric_mat2(&self, rhs: &SymmetricMat2) -> Mat2 {
37 self.mul(rhs)
38 }
39
40 #[inline]
41 fn add_symmetric_mat2(&self, rhs: &SymmetricMat2) -> Mat2 {
42 self.add(rhs)
43 }
44
45 #[inline]
46 fn sub_symmetric_mat2(&self, rhs: &SymmetricMat2) -> Mat2 {
47 self.sub(rhs)
48 }
49}
50
51#[cfg(feature = "f64")]
52impl Mat2Ext for DMat2 {
53 type SymmetricMat2 = SymmetricDMat2;
54
55 #[inline]
56 fn mul_symmetric_mat2(&self, rhs: &SymmetricDMat2) -> DMat2 {
57 self.mul(rhs)
58 }
59
60 #[inline]
61 fn add_symmetric_mat2(&self, rhs: &SymmetricDMat2) -> DMat2 {
62 self.add(rhs)
63 }
64
65 #[inline]
66 fn sub_symmetric_mat2(&self, rhs: &SymmetricDMat2) -> DMat2 {
67 self.sub(rhs)
68 }
69}
70
71macro_rules! symmetric_mat2s {
72 ($($n:ident => $nonsymmetricn:ident, $m23t:ident, $m32t:ident, $vt:ident, $t:ident),+) => {
73 $(
74 #[derive(Clone, Copy, PartialEq)]
90 #[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
91 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92 #[cfg_attr(
93 all(feature = "bevy_reflect", feature = "serde"),
94 reflect(Debug, Default, PartialEq, Serialize, Deserialize)
95 )]
96 pub struct $n {
97 pub m00: $t,
99 pub m01: $t,
101 pub m11: $t,
103 }
104
105 impl $n {
106 pub const ZERO: Self = Self::new(0.0, 0.0, 0.0);
108
109 pub const IDENTITY: Self = Self::new(1.0, 0.0, 1.0);
112
113 pub const NAN: Self = Self::new($t::NAN, $t::NAN, $t::NAN);
115
116 #[inline(always)]
121 #[must_use]
122 pub const fn new(
123 m00: $t,
124 m01: $t,
125 m11: $t,
126 ) -> Self {
127 Self { m00, m01, m11 }
128 }
129
130 #[inline(always)]
135 #[must_use]
136 pub const fn from_cols_unchecked(x_axis: $vt, y_axis: $vt) -> Self {
137 Self {
138 m00: x_axis.x,
139 m01: x_axis.y,
140 m11: y_axis.y,
141 }
142 }
143
144 #[inline]
149 #[must_use]
150 pub const fn from_cols_array_unchecked(m: &[$t; 4]) -> Self {
151 Self::new(m[0], m[1], m[3])
152 }
153
154 #[inline]
156 #[must_use]
157 pub const fn to_cols_array(&self) -> [$t; 4] {
158 [self.m00, self.m01, self.m01, self.m11]
159 }
160
161 #[inline]
166 #[must_use]
167 pub const fn from_cols_array_2d_unchecked(m: &[[$t; 2]; 2]) -> Self {
168 Self::from_cols_unchecked(
169 $vt::from_array(m[0]),
170 $vt::from_array(m[1]),
171 )
172 }
173
174 #[inline]
176 #[must_use]
177 pub const fn to_cols_array_2d(&self) -> [[$t; 2]; 2] {
178 [[self.m00, self.m01], [self.m01, self.m11]]
179 }
180
181 #[inline]
190 #[must_use]
191 pub const fn from_cols_slice(slice: &[$t]) -> Self {
192 Self::new(slice[0], slice[1], slice[3])
193 }
194
195 #[inline]
197 #[must_use]
198 #[doc(alias = "scale")]
199 pub const fn from_diagonal(diagonal: $vt) -> Self {
200 Self::new(diagonal.x, 0.0, diagonal.y)
201 }
202
203 #[inline]
209 pub fn try_from_mat2(mat: $nonsymmetricn) -> Result<Self, MatConversionError> {
210 if mat.is_symmetric() {
211 Ok(Self::from_mat2_unchecked(mat))
212 } else {
213 Err(MatConversionError::Asymmetric)
214 }
215 }
216
217 #[inline]
222 #[must_use]
223 pub fn from_mat2_unchecked(mat: $nonsymmetricn) -> Self {
224 Self::new(
225 mat.x_axis.x,
226 mat.x_axis.y,
227 mat.y_axis.y,
228 )
229 }
230
231 #[inline]
233 #[must_use]
234 pub const fn to_mat2(&self) -> $nonsymmetricn {
235 $nonsymmetricn::from_cols_array(&self.to_cols_array())
236 }
237
238 #[inline(always)]
240 #[must_use]
241 pub fn from_outer_product(v: $vt) -> Self {
242 Self::new(v.x * v.x, v.x * v.y, v.y * v.y)
243 }
244
245 #[inline]
251 #[must_use]
252 pub const fn col(&self, index: usize) -> $vt {
253 match index {
254 0 => $vt::new(self.m00, self.m01),
255 1 => $vt::new(self.m01, self.m11),
256 _ => panic!("index out of bounds"),
257 }
258 }
259
260 #[inline]
266 #[must_use]
267 pub const fn row(&self, index: usize) -> $vt {
268 match index {
269 0 => $vt::new(self.m00, self.m01),
270 1 => $vt::new(self.m01, self.m11),
271 _ => panic!("index out of bounds"),
272 }
273 }
274
275 #[inline]
277 #[must_use]
278 pub fn diagonal(&self) -> $vt {
279 $vt::new(self.m00, self.m11)
280 }
281
282 #[inline]
285 #[must_use]
286 pub fn is_finite(&self) -> bool {
287 self.m00.is_finite() && self.m01.is_finite() && self.m11.is_finite()
288 }
289
290 #[inline]
292 #[must_use]
293 pub fn is_nan(&self) -> bool {
294 self.m00.is_nan() || self.m01.is_nan() || self.m11.is_nan()
295 }
296
297 #[inline]
299 #[must_use]
300 pub fn determinant(&self) -> $t {
301 let [a, b, c] = [self.m00, self.m11, self.m01];
306 a * b - c * c
307 }
308
309 #[inline]
313 #[must_use]
314 pub fn inverse(&self) -> Self {
315 let inv_det = 1.0 / self.determinant();
316 Self {
317 m00: self.m11 * inv_det,
318 m01: -self.m01 * inv_det,
319 m11: self.m00 * inv_det,
320 }
321 }
322
323 #[inline]
325 #[must_use]
326 pub fn inverse_or_zero(&self) -> Self {
327 let det = self.determinant();
328 if det == 0.0 {
329 Self::ZERO
330 } else {
331 let inv_det = 1.0 / det;
332 Self {
333 m00: self.m11 * inv_det,
334 m01: -self.m01 * inv_det,
335 m11: self.m00 * inv_det,
336 }
337 }
338 }
339
340 #[inline]
342 #[must_use]
343 pub fn abs(&self) -> Self {
344 Self::new(
345 FloatAbs::abs(self.m00),
346 FloatAbs::abs(self.m01),
347 FloatAbs::abs(self.m11),
348 )
349 }
350
351 #[inline]
353 #[must_use]
354 pub fn mul_vec2(&self, rhs: $vt) -> $vt {
355 let mut res = self.col(0).mul(rhs.x);
356 res = res.add(self.col(1).mul(rhs.y));
357 res
358 }
359
360 #[inline]
362 #[must_use]
363 pub fn mul_mat2(&self, rhs: &$nonsymmetricn) -> $nonsymmetricn {
364 self.mul(rhs)
365 }
366
367 #[inline]
369 #[must_use]
370 pub fn mul_mat23(&self, rhs: &$m23t) -> $m23t {
371 self.mul(rhs)
372 }
373
374 #[inline]
378 #[must_use]
379 pub fn complete_mat23_sandwich(a: &$m23t, b: &$m23t) -> Self {
380 Self::new(
381 a.row(0).dot(b.row(0)),
382 a.row(1).dot(b.row(0)),
383 a.row(1).dot(b.row(1)),
384 )
385 }
386
387 #[inline]
391 #[must_use]
392 pub fn complete_mat32_sandwich(a: &$m32t, b: &$m32t) -> Self {
393 Self::new(
394 a.col(0).dot(b.col(0)),
395 a.col(1).dot(b.col(0)),
396 a.col(1).dot(b.col(1)),
397 )
398 }
399
400 #[inline]
402 #[must_use]
403 pub fn add_mat2(&self, rhs: &$nonsymmetricn) -> $nonsymmetricn {
404 self.add(rhs)
405 }
406
407 #[inline]
409 #[must_use]
410 pub fn sub_mat2(&self, rhs: &$nonsymmetricn) -> $nonsymmetricn {
411 self.sub(rhs)
412 }
413
414 #[inline]
416 #[must_use]
417 pub fn mul_symmetric_mat2(&self, rhs: &Self) -> $nonsymmetricn {
418 self.mul(rhs)
419 }
420
421 #[inline]
423 #[must_use]
424 pub fn add_symmetric_mat2(&self, rhs: &Self) -> Self {
425 self.add(rhs)
426 }
427
428 #[inline]
430 #[must_use]
431 pub fn sub_symmetric_mat2(&self, rhs: &Self) -> Self {
432 self.sub(rhs)
433 }
434
435 #[inline]
437 #[must_use]
438 pub fn mul_scalar(&self, rhs: $t) -> Self {
439 Self::new(
440 self.m00 * rhs,
441 self.m01 * rhs,
442 self.m11 * rhs,
443 )
444 }
445
446 #[inline]
448 #[must_use]
449 pub fn div_scalar(&self, rhs: $t) -> Self {
450 Self::new(
451 self.m00 / rhs,
452 self.m01 / rhs,
453 self.m11 / rhs,
454 )
455 }
456 }
457
458 impl Default for $n {
459 #[inline(always)]
460 fn default() -> Self {
461 Self::IDENTITY
462 }
463 }
464
465 impl TryFrom<$nonsymmetricn> for $n {
466 type Error = MatConversionError;
467
468 #[inline]
469 fn try_from(mat: $nonsymmetricn) -> Result<Self, Self::Error> {
470 Self::try_from_mat2(mat)
471 }
472 }
473
474 impl Add for $n {
475 type Output = Self;
476 #[inline]
477 fn add(self, rhs: Self) -> Self::Output {
478 Self::new(
479 self.m00 + rhs.m00,
480 self.m01 + rhs.m01,
481 self.m11 + rhs.m11,
482 )
483 }
484 }
485
486 impl Add<&Self> for $n {
487 type Output = Self;
488 #[inline]
489 fn add(self, rhs: &Self) -> Self::Output {
490 self.add(*rhs)
491 }
492 }
493
494 impl Add<Self> for &$n {
495 type Output = $n;
496 #[inline]
497 fn add(self, rhs: Self) -> Self::Output {
498 (*self).add(rhs)
499 }
500 }
501
502 impl Add<&Self> for &$n {
503 type Output = $n;
504 #[inline]
505 fn add(self, rhs: &Self) -> Self::Output {
506 (*self).add(*rhs)
507 }
508 }
509
510 impl AddAssign for $n {
511 #[inline]
512 fn add_assign(&mut self, rhs: Self) {
513 *self = self.add(rhs);
514 }
515 }
516
517 impl AddAssign<&Self> for $n {
518 #[inline]
519 fn add_assign(&mut self, rhs: &Self) {
520 self.add_assign(*rhs);
521 }
522 }
523
524 impl Add<$nonsymmetricn> for $n {
525 type Output = $nonsymmetricn;
526 #[inline]
527 fn add(self, rhs: $nonsymmetricn) -> Self::Output {
528 $nonsymmetricn::from_cols(
529 self.col(0).add(rhs.x_axis),
530 self.col(1).add(rhs.y_axis),
531 )
532 }
533 }
534
535 impl Add<&$nonsymmetricn> for $n {
536 type Output = $nonsymmetricn;
537 #[inline]
538 fn add(self, rhs: &$nonsymmetricn) -> Self::Output {
539 self.add(*rhs)
540 }
541 }
542
543 impl Add<$nonsymmetricn> for &$n {
544 type Output = $nonsymmetricn;
545 #[inline]
546 fn add(self, rhs: $nonsymmetricn) -> Self::Output {
547 (*self).add(rhs)
548 }
549 }
550
551 impl Add<&$nonsymmetricn> for &$n {
552 type Output = $nonsymmetricn;
553 #[inline]
554 fn add(self, rhs: &$nonsymmetricn) -> Self::Output {
555 (*self).add(*rhs)
556 }
557 }
558
559 impl Add<$n> for $nonsymmetricn {
560 type Output = $nonsymmetricn;
561 #[inline]
562 fn add(self, rhs: $n) -> Self::Output {
563 rhs.add(&self)
564 }
565 }
566
567 impl Add<&$n> for $nonsymmetricn {
568 type Output = $nonsymmetricn;
569 #[inline]
570 fn add(self, rhs: &$n) -> Self::Output {
571 self.add(*rhs)
572 }
573 }
574
575 impl Add<&$n> for &$nonsymmetricn {
576 type Output = $nonsymmetricn;
577 #[inline]
578 fn add(self, rhs: &$n) -> Self::Output {
579 (*self).add(*rhs)
580 }
581 }
582
583 impl AddAssign<$n> for $nonsymmetricn {
584 #[inline]
585 fn add_assign(&mut self, rhs: $n) {
586 *self = self.add(rhs);
587 }
588 }
589
590 impl AddAssign<&$n> for $nonsymmetricn {
591 #[inline]
592 fn add_assign(&mut self, rhs: &$n) {
593 *self = self.add(*rhs);
594 }
595 }
596
597 impl Sub for $n {
598 type Output = Self;
599 #[inline]
600 fn sub(self, rhs: Self) -> Self::Output {
601 Self::new(
602 self.m00 - rhs.m00,
603 self.m01 - rhs.m01,
604 self.m11 - rhs.m11,
605 )
606 }
607 }
608
609 impl Sub<&Self> for $n {
610 type Output = Self;
611 #[inline]
612 fn sub(self, rhs: &Self) -> Self::Output {
613 self.sub(*rhs)
614 }
615 }
616
617 impl Sub<Self> for &$n {
618 type Output = $n;
619 #[inline]
620 fn sub(self, rhs: Self) -> Self::Output {
621 (*self).sub(rhs)
622 }
623 }
624
625 impl Sub<&Self> for &$n {
626 type Output = $n;
627 #[inline]
628 fn sub(self, rhs: &Self) -> Self::Output {
629 (*self).sub(*rhs)
630 }
631 }
632
633 impl SubAssign for $n {
634 #[inline]
635 fn sub_assign(&mut self, rhs: Self) {
636 *self = self.sub(rhs);
637 }
638 }
639
640 impl SubAssign<&Self> for $n {
641 #[inline]
642 fn sub_assign(&mut self, rhs: &Self) {
643 self.sub_assign(*rhs);
644 }
645 }
646
647 impl Sub<$nonsymmetricn> for $n {
648 type Output = $nonsymmetricn;
649 #[inline]
650 fn sub(self, rhs: $nonsymmetricn) -> Self::Output {
651 $nonsymmetricn::from_cols(
652 self.col(0).sub(rhs.x_axis),
653 self.col(1).sub(rhs.y_axis),
654 )
655 }
656 }
657
658 impl Sub<&$nonsymmetricn> for $n {
659 type Output = $nonsymmetricn;
660 #[inline]
661 fn sub(self, rhs: &$nonsymmetricn) -> Self::Output {
662 self.sub(*rhs)
663 }
664 }
665
666 impl Sub<$nonsymmetricn> for &$n {
667 type Output = $nonsymmetricn;
668 #[inline]
669 fn sub(self, rhs: $nonsymmetricn) -> Self::Output {
670 (*self).sub(rhs)
671 }
672 }
673
674 impl Sub<&$nonsymmetricn> for &$n {
675 type Output = $nonsymmetricn;
676 #[inline]
677 fn sub(self, rhs: &$nonsymmetricn) -> Self::Output {
678 (*self).sub(*rhs)
679 }
680 }
681
682 impl Sub<$n> for $nonsymmetricn {
683 type Output = $nonsymmetricn;
684 #[inline]
685 fn sub(self, rhs: $n) -> Self::Output {
686 rhs.sub(&self)
687 }
688 }
689
690 impl Sub<&$n> for $nonsymmetricn {
691 type Output = $nonsymmetricn;
692 #[inline]
693 fn sub(self, rhs: &$n) -> Self::Output {
694 self.sub(*rhs)
695 }
696 }
697
698 impl Sub<&$n> for &$nonsymmetricn {
699 type Output = $nonsymmetricn;
700 #[inline]
701 fn sub(self, rhs: &$n) -> Self::Output {
702 (*self).sub(*rhs)
703 }
704 }
705
706 impl SubAssign<$n> for $nonsymmetricn {
707 #[inline]
708 fn sub_assign(&mut self, rhs: $n) {
709 *self = self.sub(rhs);
710 }
711 }
712
713 impl SubAssign<&$n> for $nonsymmetricn {
714 #[inline]
715 fn sub_assign(&mut self, rhs: &$n) {
716 *self = self.sub(*rhs);
717 }
718 }
719
720 impl Neg for $n {
721 type Output = Self;
722 #[inline]
723 fn neg(self) -> Self::Output {
724 Self::new(
725 -self.m00, -self.m01, -self.m11,
726 )
727 }
728 }
729
730 impl Neg for &$n {
731 type Output = $n;
732 #[inline]
733 fn neg(self) -> Self::Output {
734 (*self).neg()
735 }
736 }
737
738 impl Mul for $n {
739 type Output = $nonsymmetricn;
740 #[inline]
741 fn mul(self, rhs: Self) -> Self::Output {
742 $nonsymmetricn::from_cols(self.mul(rhs.col(0)), self.mul(rhs.col(1)))
743 }
744 }
745
746 impl Mul<&Self> for $n {
747 type Output = $nonsymmetricn;
748 #[inline]
749 fn mul(self, rhs: &Self) -> Self::Output {
750 self.mul(*rhs)
751 }
752 }
753
754 impl Mul<Self> for &$n {
755 type Output = $nonsymmetricn;
756 #[inline]
757 fn mul(self, rhs: Self) -> Self::Output {
758 (*self).mul(rhs)
759 }
760 }
761
762 impl Mul<&Self> for &$n {
763 type Output = $nonsymmetricn;
764 #[inline]
765 fn mul(self, rhs: &Self) -> Self::Output {
766 (*self).mul(*rhs)
767 }
768 }
769
770 impl Mul<$n> for $nonsymmetricn {
771 type Output = Self;
772 #[inline]
773 fn mul(self, rhs: $n) -> Self::Output {
774 Self::from_cols_array(&[
775 self.x_axis.x * rhs.m00 + self.y_axis.x * rhs.m01,
776 self.x_axis.y * rhs.m00 + self.y_axis.y * rhs.m01,
777 self.x_axis.x * rhs.m01 + self.y_axis.x * rhs.m11,
778 self.x_axis.y * rhs.m01 + self.y_axis.y * rhs.m11,
779 ])
780 }
781 }
782
783 impl Mul<&$n> for $nonsymmetricn {
784 type Output = Self;
785 #[inline]
786 fn mul(self, rhs: &$n) -> Self::Output {
787 self.mul(*rhs)
788 }
789 }
790
791 impl Mul<$n> for &$nonsymmetricn {
792 type Output = $nonsymmetricn;
793 #[inline]
794 fn mul(self, rhs: $n) -> Self::Output {
795 (*self).mul(rhs)
796 }
797 }
798
799 impl Mul<&$n> for &$nonsymmetricn {
800 type Output = $nonsymmetricn;
801 #[inline]
802 fn mul(self, rhs: &$n) -> Self::Output {
803 (*self).mul(*rhs)
804 }
805 }
806
807 impl MulAssign<$n> for $nonsymmetricn {
808 #[inline]
809 fn mul_assign(&mut self, rhs: $n) {
810 *self = self.mul(rhs);
811 }
812 }
813
814 impl MulAssign<&$n> for $nonsymmetricn {
815 #[inline]
816 fn mul_assign(&mut self, rhs: &$n) {
817 *self = self.mul(*rhs);
818 }
819 }
820
821 impl Mul<$nonsymmetricn> for $n {
822 type Output = $nonsymmetricn;
823 #[inline]
824 fn mul(self, rhs: $nonsymmetricn) -> Self::Output {
825 $nonsymmetricn::from_cols(
826 self.mul(rhs.x_axis),
827 self.mul(rhs.y_axis),
828 )
829 }
830 }
831
832 impl Mul<&$nonsymmetricn> for $n {
833 type Output = $nonsymmetricn;
834 #[inline]
835 fn mul(self, rhs: &$nonsymmetricn) -> Self::Output {
836 self.mul(*rhs)
837 }
838 }
839
840 impl Mul<$nonsymmetricn> for &$n {
841 type Output = $nonsymmetricn;
842 #[inline]
843 fn mul(self, rhs: $nonsymmetricn) -> Self::Output {
844 (*self).mul(rhs)
845 }
846 }
847
848 impl Mul<&$nonsymmetricn> for &$n {
849 type Output = $nonsymmetricn;
850 #[inline]
851 fn mul(self, rhs: &$nonsymmetricn) -> Self::Output {
852 (*self).mul(*rhs)
853 }
854 }
855
856 impl Mul<$m23t> for $n {
857 type Output = $m23t;
858 #[inline]
859 fn mul(self, rhs: $m23t) -> Self::Output {
860 $m23t::from_cols(
861 $vt::new(
862 self.row(0).dot(rhs.x_axis),
863 self.row(1).dot(rhs.x_axis),
864 ),
865 $vt::new(
866 self.row(0).dot(rhs.y_axis),
867 self.row(1).dot(rhs.y_axis),
868 ),
869 $vt::new(
870 self.row(0).dot(rhs.z_axis),
871 self.row(1).dot(rhs.z_axis),
872 ),
873 )
874 }
875 }
876
877 impl Mul<&$m23t> for $n {
878 type Output = $m23t;
879 #[inline]
880 fn mul(self, rhs: &$m23t) -> Self::Output {
881 self.mul(*rhs)
882 }
883 }
884
885 impl Mul<$m23t> for &$n {
886 type Output = $m23t;
887 #[inline]
888 fn mul(self, rhs: $m23t) -> Self::Output {
889 (*self).mul(rhs)
890 }
891 }
892
893 impl Mul<&$m23t> for &$n {
894 type Output = $m23t;
895 #[inline]
896 fn mul(self, rhs: &$m23t) -> Self::Output {
897 (*self).mul(*rhs)
898 }
899 }
900
901 impl Mul<$vt> for $n {
902 type Output = $vt;
903 #[inline]
904 fn mul(self, rhs: $vt) -> Self::Output {
905 self.mul_vec2(rhs)
906 }
907 }
908
909 impl Mul<&$vt> for $n {
910 type Output = $vt;
911 #[inline]
912 fn mul(self, rhs: &$vt) -> Self::Output {
913 self.mul(*rhs)
914 }
915 }
916
917 impl Mul<$vt> for &$n {
918 type Output = $vt;
919 #[inline]
920 fn mul(self, rhs: $vt) -> Self::Output {
921 (*self).mul(rhs)
922 }
923 }
924
925 impl Mul<&$vt> for &$n {
926 type Output = $vt;
927 #[inline]
928 fn mul(self, rhs: &$vt) -> Self::Output {
929 (*self).mul(*rhs)
930 }
931 }
932
933 impl Mul<$n> for $t {
934 type Output = $n;
935 #[inline]
936 fn mul(self, rhs: $n) -> Self::Output {
937 rhs.mul_scalar(self)
938 }
939 }
940
941 impl Mul<&$n> for $t {
942 type Output = $n;
943 #[inline]
944 fn mul(self, rhs: &$n) -> Self::Output {
945 self.mul(*rhs)
946 }
947 }
948
949 impl Mul<$n> for &$t {
950 type Output = $n;
951 #[inline]
952 fn mul(self, rhs: $n) -> Self::Output {
953 (*self).mul(rhs)
954 }
955 }
956
957 impl Mul<&$n> for &$t {
958 type Output = $n;
959 #[inline]
960 fn mul(self, rhs: &$n) -> Self::Output {
961 (*self).mul(*rhs)
962 }
963 }
964
965 impl Mul<$t> for $n {
966 type Output = Self;
967 #[inline]
968 fn mul(self, rhs: $t) -> Self::Output {
969 self.mul_scalar(rhs)
970 }
971 }
972
973 impl Mul<&$t> for $n {
974 type Output = Self;
975 #[inline]
976 fn mul(self, rhs: &$t) -> Self::Output {
977 self.mul(*rhs)
978 }
979 }
980
981 impl Mul<$t> for &$n {
982 type Output = $n;
983 #[inline]
984 fn mul(self, rhs: $t) -> Self::Output {
985 (*self).mul(rhs)
986 }
987 }
988
989 impl Mul<&$t> for &$n {
990 type Output = $n;
991 #[inline]
992 fn mul(self, rhs: &$t) -> Self::Output {
993 (*self).mul(*rhs)
994 }
995 }
996
997 impl MulAssign<$t> for $n {
998 #[inline]
999 fn mul_assign(&mut self, rhs: $t) {
1000 *self = self.mul(rhs);
1001 }
1002 }
1003
1004 impl MulAssign<&$t> for $n {
1005 #[inline]
1006 fn mul_assign(&mut self, rhs: &$t) {
1007 self.mul_assign(*rhs);
1008 }
1009 }
1010
1011 impl Div<$n> for $t {
1012 type Output = $n;
1013 #[inline]
1014 fn div(self, rhs: $n) -> Self::Output {
1015 rhs.div_scalar(self)
1016 }
1017 }
1018
1019 impl Div<&$n> for $t {
1020 type Output = $n;
1021 #[inline]
1022 fn div(self, rhs: &$n) -> Self::Output {
1023 self.div(*rhs)
1024 }
1025 }
1026
1027 impl Div<$n> for &$t {
1028 type Output = $n;
1029 #[inline]
1030 fn div(self, rhs: $n) -> Self::Output {
1031 (*self).div(rhs)
1032 }
1033 }
1034
1035 impl Div<&$n> for &$t {
1036 type Output = $n;
1037 #[inline]
1038 fn div(self, rhs: &$n) -> Self::Output {
1039 (*self).div(*rhs)
1040 }
1041 }
1042
1043 impl Div<$t> for $n {
1044 type Output = Self;
1045 #[inline]
1046 fn div(self, rhs: $t) -> Self::Output {
1047 self.div_scalar(rhs)
1048 }
1049 }
1050
1051 impl Div<&$t> for $n {
1052 type Output = Self;
1053 #[inline]
1054 fn div(self, rhs: &$t) -> Self::Output {
1055 self.div(*rhs)
1056 }
1057 }
1058
1059 impl Div<$t> for &$n {
1060 type Output = $n;
1061 #[inline]
1062 fn div(self, rhs: $t) -> Self::Output {
1063 (*self).div(rhs)
1064 }
1065 }
1066
1067 impl Div<&$t> for &$n {
1068 type Output = $n;
1069 #[inline]
1070 fn div(self, rhs: &$t) -> Self::Output {
1071 (*self).div(*rhs)
1072 }
1073 }
1074
1075 impl DivAssign<$t> for $n {
1076 #[inline]
1077 fn div_assign(&mut self, rhs: $t) {
1078 *self = self.div(rhs);
1079 }
1080 }
1081
1082 impl DivAssign<&$t> for $n {
1083 #[inline]
1084 fn div_assign(&mut self, rhs: &$t) {
1085 self.div_assign(*rhs);
1086 }
1087 }
1088
1089 impl From<$n> for $nonsymmetricn {
1090 #[inline]
1091 fn from(mat: $n) -> Self {
1092 mat.to_mat2()
1093 }
1094 }
1095
1096 impl Sum<$n> for $n {
1097 fn sum<I: Iterator<Item = $n>>(iter: I) -> Self {
1098 iter.fold(Self::ZERO, Self::add)
1099 }
1100 }
1101
1102 impl<'a> Sum<&'a $n> for $n {
1103 fn sum<I: Iterator<Item = &'a $n>>(iter: I) -> Self {
1104 iter.fold(Self::ZERO, |a, &b| a.add(b))
1105 }
1106 }
1107
1108 #[cfg(feature = "approx")]
1109 impl approx::AbsDiffEq for $n {
1110 type Epsilon = $t;
1111
1112 #[inline]
1113 fn default_epsilon() -> Self::Epsilon {
1114 $t::default_epsilon()
1115 }
1116
1117 #[inline]
1118 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
1119 self.m00.abs_diff_eq(&other.m00, epsilon)
1120 && self.m01.abs_diff_eq(&other.m01, epsilon)
1121 && self.m11.abs_diff_eq(&other.m11, epsilon)
1122 }
1123 }
1124
1125 #[cfg(feature = "approx")]
1126 impl approx::RelativeEq for $n {
1127 #[inline]
1128 fn default_max_relative() -> Self::Epsilon {
1129 $t::default_max_relative()
1130 }
1131
1132 #[inline]
1133 fn relative_eq(
1134 &self,
1135 other: &Self,
1136 epsilon: Self::Epsilon,
1137 max_relative: Self::Epsilon,
1138 ) -> bool {
1139 self.m00.relative_eq(&other.m00, epsilon, max_relative)
1140 && self.m01.relative_eq(&other.m01, epsilon, max_relative)
1141 && self.m11.relative_eq(&other.m11, epsilon, max_relative)
1142 }
1143 }
1144
1145 #[cfg(feature = "approx")]
1146 impl approx::UlpsEq for $n {
1147 #[inline]
1148 fn default_max_ulps() -> u32 {
1149 $t::default_max_ulps()
1150 }
1151
1152 #[inline]
1153 fn ulps_eq(
1154 &self,
1155 other: &Self,
1156 epsilon: Self::Epsilon,
1157 max_ulps: u32,
1158 ) -> bool {
1159 self.m00.ulps_eq(&other.m00, epsilon, max_ulps)
1160 && self.m01.ulps_eq(&other.m01, epsilon, max_ulps)
1161 && self.m11.ulps_eq(&other.m11, epsilon, max_ulps)
1162 }
1163 }
1164
1165 impl core::fmt::Debug for $n {
1166 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1167 f.debug_struct(stringify!($n))
1168 .field("m00", &self.m00)
1169 .field("m01", &self.m01)
1170 .field("m11", &self.m11)
1171 .finish()
1172 }
1173 }
1174
1175 impl core::fmt::Display for $n {
1176 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1177 if let Some(p) = f.precision() {
1178 write!(
1179 f,
1180 "[[{:.*}, {:.*}], [{:.*}, {:.*}]]",
1181 p, self.m00, p, self.m01, p, self.m01, p, self.m11
1182 )
1183 } else {
1184 write!(
1185 f,
1186 "[[{}, {}], [{}, {}]]",
1187 self.m00, self.m01, self.m01, self.m11
1188 )
1189 }
1190 }
1191 }
1192 )+
1193 }
1194}
1195
1196#[cfg(feature = "f32")]
1197symmetric_mat2s!(SymmetricMat2 => Mat2, Mat23, Mat32, Vec2, f32);
1198
1199#[cfg(feature = "f64")]
1200symmetric_mat2s!(SymmetricDMat2 => DMat2, DMat23, DMat32, DVec2, f64);
1201
1202#[cfg(all(feature = "f32", feature = "f64"))]
1203impl SymmetricMat2 {
1204 #[inline]
1206 #[must_use]
1207 pub fn as_symmetric_dmat2(&self) -> SymmetricDMat2 {
1208 SymmetricDMat2 {
1209 m00: self.m00 as f64,
1210 m01: self.m01 as f64,
1211 m11: self.m11 as f64,
1212 }
1213 }
1214}
1215
1216#[cfg(all(feature = "f32", feature = "f64"))]
1217impl SymmetricDMat2 {
1218 #[inline]
1220 #[must_use]
1221 pub fn as_symmetric_mat2(&self) -> SymmetricMat2 {
1222 SymmetricMat2 {
1223 m00: self.m00 as f32,
1224 m01: self.m01 as f32,
1225 m11: self.m11 as f32,
1226 }
1227 }
1228}