Skip to main content

glam/f64/
dmat2.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use crate::{DMat3, DVec2, Mat2, f64::math, swizzles::*};
4use core::fmt;
5use core::iter::{Product, Sum};
6use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8#[cfg(feature = "zerocopy-08")]
9use zerocopy_derive_08::*;
10
11/// Creates a 2x2 matrix from two column vectors.
12#[inline(always)]
13#[must_use]
14pub const fn dmat2(x_axis: DVec2, y_axis: DVec2) -> DMat2 {
15    DMat2::from_cols(x_axis, y_axis)
16}
17
18/// A 2x2 column major matrix.
19#[derive(Clone, Copy)]
20#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
21#[cfg_attr(
22    feature = "zerocopy-08",
23    derive(FromBytes, Immutable, IntoBytes, KnownLayout)
24)]
25#[cfg_attr(feature = "cuda", repr(align(16)))]
26#[repr(C)]
27pub struct DMat2 {
28    pub x_axis: DVec2,
29    pub y_axis: DVec2,
30}
31
32impl DMat2 {
33    /// A 2x2 matrix with all elements set to `0.0`.
34    pub const ZERO: Self = Self::from_cols(DVec2::ZERO, DVec2::ZERO);
35
36    /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
37    pub const IDENTITY: Self = Self::from_cols(DVec2::X, DVec2::Y);
38
39    /// All NAN:s.
40    pub const NAN: Self = Self::from_cols(DVec2::NAN, DVec2::NAN);
41
42    #[allow(clippy::too_many_arguments)]
43    #[inline(always)]
44    #[must_use]
45    const fn new(m00: f64, m01: f64, m10: f64, m11: f64) -> Self {
46        Self {
47            x_axis: DVec2::new(m00, m01),
48            y_axis: DVec2::new(m10, m11),
49        }
50    }
51
52    /// Creates a 2x2 matrix from two column vectors.
53    ///
54    /// See also [`Self::from_rows`] when the data is in row major order.
55    #[inline(always)]
56    #[must_use]
57    pub const fn from_cols(x_axis: DVec2, y_axis: DVec2) -> Self {
58        Self { x_axis, y_axis }
59    }
60
61    /// Creates a 2x2 matrix from two row vectors.
62    ///
63    /// Matrices are stored in column major order, so the given rows are permuted into
64    /// the matrix layout. Use [`Self::from_cols`] instead when the data is already in
65    /// column major order.
66    #[inline(always)]
67    #[must_use]
68    pub const fn from_rows(row0: DVec2, row1: DVec2) -> Self {
69        let [m00, m01] = row0.to_array();
70        let [m10, m11] = row1.to_array();
71        Self::new(m00, m10, m01, m11)
72    }
73
74    /// Creates a 2x2 matrix from a `[f64; 4]` array stored in column major order.
75    ///
76    /// If the data is in row major order use [`Self::from_rows_array`] instead.
77    #[inline]
78    #[must_use]
79    pub const fn from_cols_array(m: &[f64; 4]) -> Self {
80        Self::new(m[0], m[1], m[2], m[3])
81    }
82
83    /// Creates a `[f64; 4]` array storing data in column major order.
84    ///
85    /// If you require the data in row major order use [`Self::to_rows_array`] instead.
86    #[inline]
87    #[must_use]
88    pub const fn to_cols_array(&self) -> [f64; 4] {
89        [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
90    }
91
92    /// Creates a 2x2 matrix from a `[[f64; 2]; 2]` 2D array stored in column major order.
93    ///
94    /// If the data is in row major order `transpose` the returned matrix.
95    #[inline]
96    #[must_use]
97    pub const fn from_cols_array_2d(m: &[[f64; 2]; 2]) -> Self {
98        Self::from_cols(DVec2::from_array(m[0]), DVec2::from_array(m[1]))
99    }
100
101    /// Creates a `[[f64; 2]; 2]` 2D array storing data in column major order.
102    ///
103    /// If you require row major order `transpose` the matrix first.
104    #[inline]
105    #[must_use]
106    pub const fn to_cols_array_2d(&self) -> [[f64; 2]; 2] {
107        [self.x_axis.to_array(), self.y_axis.to_array()]
108    }
109
110    /// Creates a 2x2 matrix from a `[f64; 4]` array stored in row major order.
111    ///
112    /// Matrices are stored in column major order, so the array is permuted into the
113    /// matrix layout. Use [`Self::from_cols_array`] instead when the data is already in
114    /// column major order.
115    #[inline]
116    #[must_use]
117    pub const fn from_rows_array(m: &[f64; 4]) -> Self {
118        Self::new(m[0], m[2], m[1], m[3])
119    }
120
121    /// Creates a `[f64; 4]` array storing data in row major order.
122    ///
123    /// Matrices are stored in column major order, so the array is permuted out of the
124    /// column major storage. Use [`Self::to_cols_array`] instead when you want data in
125    /// column major order.
126    #[inline]
127    #[must_use]
128    pub const fn to_rows_array(&self) -> [f64; 4] {
129        let m = self.to_cols_array();
130        [m[0], m[2], m[1], m[3]]
131    }
132
133    /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
134    #[doc(alias = "scale")]
135    #[inline]
136    #[must_use]
137    pub const fn from_diagonal(diagonal: DVec2) -> Self {
138        Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
139    }
140
141    /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
142    /// `angle` (in radians).
143    #[inline]
144    #[must_use]
145    pub fn from_scale_angle(scale: DVec2, angle: f64) -> Self {
146        let (sin, cos) = math::sin_cos(angle);
147        Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
148    }
149
150    /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
151    #[inline]
152    #[must_use]
153    pub fn from_angle(angle: f64) -> Self {
154        let (sin, cos) = math::sin_cos(angle);
155        Self::new(cos, sin, -sin, cos)
156    }
157
158    /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
159    #[inline]
160    #[must_use]
161    pub fn from_mat3(m: DMat3) -> Self {
162        Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
163    }
164
165    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
166    /// and `j`th row.
167    ///
168    /// # Panics
169    ///
170    /// Panics if `i` or `j` is greater than 2.
171    #[inline]
172    #[must_use]
173    #[track_caller]
174    pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self {
175        match (i, j) {
176            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
177            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
178            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
179            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
180            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
181            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
182            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
183            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
184            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
185            _ => panic!("index out of bounds"),
186        }
187    }
188
189    /// Creates a 2x2 matrix from the first 4 values in `slice`.
190    ///
191    /// See also [`Self::from_rows_slice`] when the slice is in row major order.
192    ///
193    /// # Panics
194    ///
195    /// Panics if `slice` is less than 4 elements long.
196    #[inline]
197    #[must_use]
198    #[track_caller]
199    pub const fn from_cols_slice(slice: &[f64]) -> Self {
200        Self::new(slice[0], slice[1], slice[2], slice[3])
201    }
202
203    /// Writes the columns of `self` to the first 4 elements in `slice`.
204    ///
205    /// # Panics
206    ///
207    /// Panics if `slice` is less than 4 elements long.
208    #[inline]
209    #[track_caller]
210    pub fn write_cols_to_slice(&self, slice: &mut [f64]) {
211        slice[0] = self.x_axis.x;
212        slice[1] = self.x_axis.y;
213        slice[2] = self.y_axis.x;
214        slice[3] = self.y_axis.y;
215    }
216
217    /// Creates a 2x2 matrix from the first 4 values in `slice`, stored in row
218    /// major order.
219    ///
220    /// Matrices are stored in column major order, so the slice is permuted into the
221    /// matrix layout. Use [`Self::from_cols_slice`] instead when the slice is already in
222    /// column major order.
223    ///
224    /// # Panics
225    ///
226    /// Panics if `slice` is less than 4 elements long.
227    #[inline]
228    #[must_use]
229    #[track_caller]
230    pub const fn from_rows_slice(slice: &[f64]) -> Self {
231        Self::new(slice[0], slice[2], slice[1], slice[3])
232    }
233
234    /// Returns the matrix column for the given `index`.
235    ///
236    /// # Panics
237    ///
238    /// Panics if `index` is greater than 1.
239    #[inline]
240    #[must_use]
241    #[track_caller]
242    pub fn col(&self, index: usize) -> DVec2 {
243        match index {
244            0 => self.x_axis,
245            1 => self.y_axis,
246            _ => panic!("index out of bounds"),
247        }
248    }
249
250    /// Returns a mutable reference to the matrix column for the given `index`.
251    ///
252    /// # Panics
253    ///
254    /// Panics if `index` is greater than 1.
255    #[inline]
256    #[track_caller]
257    pub fn col_mut(&mut self, index: usize) -> &mut DVec2 {
258        match index {
259            0 => &mut self.x_axis,
260            1 => &mut self.y_axis,
261            _ => panic!("index out of bounds"),
262        }
263    }
264
265    /// Returns the matrix row for the given `index`.
266    ///
267    /// See also [`Self::set_row`] when you need to change the row.
268    ///
269    /// # Panics
270    ///
271    /// Panics if `index` is greater than 1.
272    #[inline]
273    #[must_use]
274    #[track_caller]
275    pub fn row(&self, index: usize) -> DVec2 {
276        match index {
277            0 => DVec2::new(self.x_axis.x, self.y_axis.x),
278            1 => DVec2::new(self.x_axis.y, self.y_axis.y),
279            _ => panic!("index out of bounds"),
280        }
281    }
282
283    /// Sets the matrix row for the given `index`.
284    ///
285    /// Matrices are stored in column major order, so the row is spread across all
286    /// 2 columns and writing it touches every column. Use [`Self::col_mut`]
287    /// instead when you can work with columns. See also [`Self::row`].
288    ///
289    /// # Panics
290    ///
291    /// Panics if `index` is greater than 1.
292    #[inline]
293    #[track_caller]
294    pub fn set_row(&mut self, index: usize, row: DVec2) {
295        match index {
296            0 => {
297                self.x_axis.x = row.x;
298                self.y_axis.x = row.y;
299            }
300            1 => {
301                self.x_axis.y = row.x;
302                self.y_axis.y = row.y;
303            }
304            _ => panic!("index out of bounds"),
305        }
306    }
307
308    /// Returns `true` if, and only if, all elements are finite.
309    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
310    #[inline]
311    #[must_use]
312    pub fn is_finite(&self) -> bool {
313        self.x_axis.is_finite() && self.y_axis.is_finite()
314    }
315
316    /// Returns `true` if any elements are `NaN`.
317    #[inline]
318    #[must_use]
319    pub fn is_nan(&self) -> bool {
320        self.x_axis.is_nan() || self.y_axis.is_nan()
321    }
322
323    /// Returns the transpose of `self`.
324    #[inline]
325    #[must_use]
326    pub fn transpose(&self) -> Self {
327        Self {
328            x_axis: DVec2::new(self.x_axis.x, self.y_axis.x),
329            y_axis: DVec2::new(self.x_axis.y, self.y_axis.y),
330        }
331    }
332
333    /// Returns the diagonal of `self`.
334    #[inline]
335    #[must_use]
336    pub fn diagonal(&self) -> DVec2 {
337        DVec2::new(self.x_axis.x, self.y_axis.y)
338    }
339
340    /// Returns the determinant of `self`.
341    #[inline]
342    #[must_use]
343    pub fn determinant(&self) -> f64 {
344        self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
345    }
346
347    /// If `CHECKED` is true then if the determinant is zero this function will return a tuple
348    /// containing a zero matrix and false. If the determinant is non zero a tuple containing the
349    /// inverted matrix and true is returned.
350    ///
351    /// If `CHECKED` is false then the determinant is not checked and if it is zero the resulting
352    /// inverted matrix will be invalid. Will panic if the resulting inverted matrix is not finite
353    /// when `glam_assert` is enabled.
354    ///
355    /// A tuple containing the inverted matrix and a bool is used instead of an option here as
356    /// regular Rust enums put the discriminant first which can result in a lot of padding if the
357    /// matrix is aligned.
358    #[inline(always)]
359    #[must_use]
360    #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
361    fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
362        let inv_det = 1.0 / self.determinant();
363        let m = Self::new(
364            self.y_axis.y * inv_det,
365            self.x_axis.y * -inv_det,
366            self.y_axis.x * -inv_det,
367            self.x_axis.x * inv_det,
368        );
369        if CHECKED {
370            if !m.is_finite() {
371                return (Self::ZERO, false);
372            }
373        } else {
374            glam_assert!(m.is_finite());
375        }
376        (m, true)
377    }
378
379    /// Returns the inverse of `self`.
380    ///
381    /// If the matrix is not invertible the returned matrix will be invalid. The
382    /// returned matrix will also be invalid if the inverse is not finite, which can
383    /// happen when `self` contains very large or very small values. Use
384    /// [`Self::try_inverse`] or [`Self::inverse_or_zero`] to detect these cases.
385    ///
386    /// # Panics
387    ///
388    /// Will panic if the resulting inverted matrix is not finite when `glam_assert`
389    /// is enabled.
390    #[inline]
391    #[must_use]
392    #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
393    pub fn inverse(&self) -> Self {
394        self.inverse_checked::<false>().0
395    }
396
397    /// Returns the inverse of `self` or `None` if the matrix is not invertible, or if
398    /// the inverse is not finite.
399    #[inline]
400    #[must_use]
401    pub fn try_inverse(&self) -> Option<Self> {
402        let (m, is_valid) = self.inverse_checked::<true>();
403        if is_valid { Some(m) } else { None }
404    }
405
406    /// Returns the inverse of `self` or `DMat2::ZERO` if the matrix is not
407    /// invertible, or if the inverse is not finite.
408    #[inline]
409    #[must_use]
410    pub fn inverse_or_zero(&self) -> Self {
411        self.inverse_checked::<true>().0
412    }
413
414    /// Transforms a 2D vector.
415    #[inline]
416    #[must_use]
417    pub fn mul_vec2(&self, rhs: DVec2) -> DVec2 {
418        #[allow(clippy::suspicious_operation_groupings)]
419        DVec2::new(
420            (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
421            (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
422        )
423    }
424
425    /// Transforms a 2D vector by the transpose of `self`.
426    #[inline]
427    #[must_use]
428    pub fn transpose_mul_vec2(&self, rhs: DVec2) -> DVec2 {
429        DVec2::new(self.x_axis.dot(rhs), self.y_axis.dot(rhs))
430    }
431
432    /// Transforms a 2D vector by the transpose of `self`.
433    #[inline]
434    #[must_use]
435    #[deprecated(
436        since = "0.34.2",
437        note = "Use `transpose_mul_vec2` instead, whose word order matches its order of operations and is consistent with `transpose().mul_vec2`."
438    )]
439    pub fn mul_transpose_vec2(&self, rhs: DVec2) -> DVec2 {
440        self.transpose_mul_vec2(rhs)
441    }
442
443    /// Multiplies two 2x2 matrices.
444    #[inline]
445    #[must_use]
446    pub fn mul_mat2(&self, rhs: &Self) -> Self {
447        self.mul(rhs)
448    }
449
450    /// Adds two 2x2 matrices.
451    #[inline]
452    #[must_use]
453    pub fn add_mat2(&self, rhs: &Self) -> Self {
454        self.add(rhs)
455    }
456
457    /// Subtracts two 2x2 matrices.
458    #[inline]
459    #[must_use]
460    pub fn sub_mat2(&self, rhs: &Self) -> Self {
461        self.sub(rhs)
462    }
463
464    /// Multiplies a 2x2 matrix by a scalar.
465    #[inline]
466    #[must_use]
467    pub fn mul_scalar(&self, rhs: f64) -> Self {
468        Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
469    }
470
471    /// Multiply `self` by a scaling vector `scale`.
472    /// This is faster than creating a whole diagonal scaling matrix and then multiplying that.
473    /// This operation is commutative.
474    #[inline]
475    #[must_use]
476    pub fn mul_diagonal_scale(&self, scale: DVec2) -> Self {
477        Self::from_cols(self.x_axis * scale.x, self.y_axis * scale.y)
478    }
479
480    /// Divides a 2x2 matrix by a scalar.
481    #[inline]
482    #[must_use]
483    pub fn div_scalar(&self, rhs: f64) -> Self {
484        let rhs = DVec2::splat(rhs);
485        Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs))
486    }
487
488    /// Returns a matrix containing the reciprocal `1.0/n` of each element of `self`.
489    #[inline]
490    #[must_use]
491    pub fn recip(&self) -> Self {
492        Self::from_cols(self.x_axis.recip(), self.y_axis.recip())
493    }
494
495    /// Returns true if the absolute difference of all elements between `self` and `rhs`
496    /// is less than or equal to `max_abs_diff`.
497    ///
498    /// This can be used to compare if two matrices contain similar elements. It works best
499    /// when comparing with a known value. The `max_abs_diff` that should be used used
500    /// depends on the values being compared against.
501    ///
502    /// For more see
503    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
504    #[inline]
505    #[must_use]
506    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
507        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
508            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
509    }
510
511    /// Takes the absolute value of each element in `self`
512    #[inline]
513    #[must_use]
514    pub fn abs(&self) -> Self {
515        Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
516    }
517
518    #[cfg(feature = "f64")]
519    #[inline]
520    #[must_use]
521    pub fn as_mat2(&self) -> Mat2 {
522        Mat2::from_cols(self.x_axis.as_vec2(), self.y_axis.as_vec2())
523    }
524}
525
526impl Default for DMat2 {
527    #[inline]
528    fn default() -> Self {
529        Self::IDENTITY
530    }
531}
532
533impl Add for DMat2 {
534    type Output = Self;
535    #[inline]
536    fn add(self, rhs: Self) -> Self {
537        Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
538    }
539}
540
541impl Add<&Self> for DMat2 {
542    type Output = Self;
543    #[inline]
544    fn add(self, rhs: &Self) -> Self {
545        self.add(*rhs)
546    }
547}
548
549impl Add<&DMat2> for &DMat2 {
550    type Output = DMat2;
551    #[inline]
552    fn add(self, rhs: &DMat2) -> DMat2 {
553        (*self).add(*rhs)
554    }
555}
556
557impl Add<DMat2> for &DMat2 {
558    type Output = DMat2;
559    #[inline]
560    fn add(self, rhs: DMat2) -> DMat2 {
561        (*self).add(rhs)
562    }
563}
564
565impl AddAssign for DMat2 {
566    #[inline]
567    fn add_assign(&mut self, rhs: Self) {
568        *self = self.add(rhs);
569    }
570}
571
572impl AddAssign<&Self> for DMat2 {
573    #[inline]
574    fn add_assign(&mut self, rhs: &Self) {
575        self.add_assign(*rhs);
576    }
577}
578
579impl Sub for DMat2 {
580    type Output = Self;
581    #[inline]
582    fn sub(self, rhs: Self) -> Self {
583        Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
584    }
585}
586
587impl Sub<&Self> for DMat2 {
588    type Output = Self;
589    #[inline]
590    fn sub(self, rhs: &Self) -> Self {
591        self.sub(*rhs)
592    }
593}
594
595impl Sub<&DMat2> for &DMat2 {
596    type Output = DMat2;
597    #[inline]
598    fn sub(self, rhs: &DMat2) -> DMat2 {
599        (*self).sub(*rhs)
600    }
601}
602
603impl Sub<DMat2> for &DMat2 {
604    type Output = DMat2;
605    #[inline]
606    fn sub(self, rhs: DMat2) -> DMat2 {
607        (*self).sub(rhs)
608    }
609}
610
611impl SubAssign for DMat2 {
612    #[inline]
613    fn sub_assign(&mut self, rhs: Self) {
614        *self = self.sub(rhs);
615    }
616}
617
618impl SubAssign<&Self> for DMat2 {
619    #[inline]
620    fn sub_assign(&mut self, rhs: &Self) {
621        self.sub_assign(*rhs);
622    }
623}
624
625impl Neg for DMat2 {
626    type Output = Self;
627    #[inline]
628    fn neg(self) -> Self::Output {
629        Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
630    }
631}
632
633impl Neg for &DMat2 {
634    type Output = DMat2;
635    #[inline]
636    fn neg(self) -> DMat2 {
637        (*self).neg()
638    }
639}
640
641impl Mul for DMat2 {
642    type Output = Self;
643    #[inline]
644    fn mul(self, rhs: Self) -> Self {
645        Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
646    }
647}
648
649impl Mul<&Self> for DMat2 {
650    type Output = Self;
651    #[inline]
652    fn mul(self, rhs: &Self) -> Self {
653        self.mul(*rhs)
654    }
655}
656
657impl Mul<&DMat2> for &DMat2 {
658    type Output = DMat2;
659    #[inline]
660    fn mul(self, rhs: &DMat2) -> DMat2 {
661        (*self).mul(*rhs)
662    }
663}
664
665impl Mul<DMat2> for &DMat2 {
666    type Output = DMat2;
667    #[inline]
668    fn mul(self, rhs: DMat2) -> DMat2 {
669        (*self).mul(rhs)
670    }
671}
672
673impl MulAssign for DMat2 {
674    #[inline]
675    fn mul_assign(&mut self, rhs: Self) {
676        *self = self.mul(rhs);
677    }
678}
679
680impl MulAssign<&Self> for DMat2 {
681    #[inline]
682    fn mul_assign(&mut self, rhs: &Self) {
683        self.mul_assign(*rhs);
684    }
685}
686
687impl Mul<DVec2> for DMat2 {
688    type Output = DVec2;
689    #[inline]
690    fn mul(self, rhs: DVec2) -> Self::Output {
691        self.mul_vec2(rhs)
692    }
693}
694
695impl Mul<&DVec2> for DMat2 {
696    type Output = DVec2;
697    #[inline]
698    fn mul(self, rhs: &DVec2) -> DVec2 {
699        self.mul(*rhs)
700    }
701}
702
703impl Mul<&DVec2> for &DMat2 {
704    type Output = DVec2;
705    #[inline]
706    fn mul(self, rhs: &DVec2) -> DVec2 {
707        (*self).mul(*rhs)
708    }
709}
710
711impl Mul<DVec2> for &DMat2 {
712    type Output = DVec2;
713    #[inline]
714    fn mul(self, rhs: DVec2) -> DVec2 {
715        (*self).mul(rhs)
716    }
717}
718
719impl Mul<DMat2> for f64 {
720    type Output = DMat2;
721    #[inline]
722    fn mul(self, rhs: DMat2) -> Self::Output {
723        rhs.mul_scalar(self)
724    }
725}
726
727impl Mul<&DMat2> for f64 {
728    type Output = DMat2;
729    #[inline]
730    fn mul(self, rhs: &DMat2) -> DMat2 {
731        self.mul(*rhs)
732    }
733}
734
735impl Mul<&DMat2> for &f64 {
736    type Output = DMat2;
737    #[inline]
738    fn mul(self, rhs: &DMat2) -> DMat2 {
739        (*self).mul(*rhs)
740    }
741}
742
743impl Mul<DMat2> for &f64 {
744    type Output = DMat2;
745    #[inline]
746    fn mul(self, rhs: DMat2) -> DMat2 {
747        (*self).mul(rhs)
748    }
749}
750
751impl Mul<f64> for DMat2 {
752    type Output = Self;
753    #[inline]
754    fn mul(self, rhs: f64) -> Self {
755        self.mul_scalar(rhs)
756    }
757}
758
759impl Mul<&f64> for DMat2 {
760    type Output = Self;
761    #[inline]
762    fn mul(self, rhs: &f64) -> Self {
763        self.mul(*rhs)
764    }
765}
766
767impl Mul<&f64> for &DMat2 {
768    type Output = DMat2;
769    #[inline]
770    fn mul(self, rhs: &f64) -> DMat2 {
771        (*self).mul(*rhs)
772    }
773}
774
775impl Mul<f64> for &DMat2 {
776    type Output = DMat2;
777    #[inline]
778    fn mul(self, rhs: f64) -> DMat2 {
779        (*self).mul(rhs)
780    }
781}
782
783impl MulAssign<f64> for DMat2 {
784    #[inline]
785    fn mul_assign(&mut self, rhs: f64) {
786        *self = self.mul(rhs);
787    }
788}
789
790impl MulAssign<&f64> for DMat2 {
791    #[inline]
792    fn mul_assign(&mut self, rhs: &f64) {
793        self.mul_assign(*rhs);
794    }
795}
796
797impl Div<DMat2> for f64 {
798    type Output = DMat2;
799    #[inline]
800    fn div(self, rhs: DMat2) -> Self::Output {
801        DMat2::from_cols(self.div(rhs.x_axis), self.div(rhs.y_axis))
802    }
803}
804
805impl Div<&DMat2> for f64 {
806    type Output = DMat2;
807    #[inline]
808    fn div(self, rhs: &DMat2) -> DMat2 {
809        self.div(*rhs)
810    }
811}
812
813impl Div<&DMat2> for &f64 {
814    type Output = DMat2;
815    #[inline]
816    fn div(self, rhs: &DMat2) -> DMat2 {
817        (*self).div(*rhs)
818    }
819}
820
821impl Div<DMat2> for &f64 {
822    type Output = DMat2;
823    #[inline]
824    fn div(self, rhs: DMat2) -> DMat2 {
825        (*self).div(rhs)
826    }
827}
828
829impl Div<f64> for DMat2 {
830    type Output = Self;
831    #[inline]
832    fn div(self, rhs: f64) -> Self {
833        self.div_scalar(rhs)
834    }
835}
836
837impl Div<&f64> for DMat2 {
838    type Output = Self;
839    #[inline]
840    fn div(self, rhs: &f64) -> Self {
841        self.div(*rhs)
842    }
843}
844
845impl Div<&f64> for &DMat2 {
846    type Output = DMat2;
847    #[inline]
848    fn div(self, rhs: &f64) -> DMat2 {
849        (*self).div(*rhs)
850    }
851}
852
853impl Div<f64> for &DMat2 {
854    type Output = DMat2;
855    #[inline]
856    fn div(self, rhs: f64) -> DMat2 {
857        (*self).div(rhs)
858    }
859}
860
861impl DivAssign<f64> for DMat2 {
862    #[inline]
863    fn div_assign(&mut self, rhs: f64) {
864        *self = self.div(rhs);
865    }
866}
867
868impl DivAssign<&f64> for DMat2 {
869    #[inline]
870    fn div_assign(&mut self, rhs: &f64) {
871        self.div_assign(*rhs);
872    }
873}
874
875impl Sum<Self> for DMat2 {
876    fn sum<I>(iter: I) -> Self
877    where
878        I: Iterator<Item = Self>,
879    {
880        iter.fold(Self::ZERO, Self::add)
881    }
882}
883
884impl<'a> Sum<&'a Self> for DMat2 {
885    fn sum<I>(iter: I) -> Self
886    where
887        I: Iterator<Item = &'a Self>,
888    {
889        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
890    }
891}
892
893impl Product for DMat2 {
894    fn product<I>(iter: I) -> Self
895    where
896        I: Iterator<Item = Self>,
897    {
898        iter.fold(Self::IDENTITY, Self::mul)
899    }
900}
901
902impl<'a> Product<&'a Self> for DMat2 {
903    fn product<I>(iter: I) -> Self
904    where
905        I: Iterator<Item = &'a Self>,
906    {
907        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
908    }
909}
910
911impl PartialEq for DMat2 {
912    #[inline]
913    fn eq(&self, rhs: &Self) -> bool {
914        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
915    }
916}
917
918impl AsRef<[f64; 4]> for DMat2 {
919    #[inline]
920    fn as_ref(&self) -> &[f64; 4] {
921        unsafe { &*(self as *const Self as *const [f64; 4]) }
922    }
923}
924
925impl AsMut<[f64; 4]> for DMat2 {
926    #[inline]
927    fn as_mut(&mut self) -> &mut [f64; 4] {
928        unsafe { &mut *(self as *mut Self as *mut [f64; 4]) }
929    }
930}
931
932impl fmt::Debug for DMat2 {
933    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
934        fmt.debug_struct(stringify!(DMat2))
935            .field("x_axis", &self.x_axis)
936            .field("y_axis", &self.y_axis)
937            .finish()
938    }
939}
940
941impl fmt::Display for DMat2 {
942    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
943        if let Some(p) = f.precision() {
944            write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
945        } else {
946            write!(f, "[{}, {}]", self.x_axis, self.y_axis)
947        }
948    }
949}