glam/f64/
daffine2.rs

1// Generated from affine.rs.tera template. Edit the template, not the generated file.
2
3use crate::{DMat2, DMat3, DVec2};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6/// A 2D affine transform, which can represent translation, rotation, scaling and shear.
7#[derive(Copy, Clone)]
8#[cfg_attr(
9    all(feature = "bytemuck", not(target_arch = "spirv")),
10    derive(bytemuck::Pod, bytemuck::Zeroable)
11)]
12#[repr(C)]
13pub struct DAffine2 {
14    pub matrix2: DMat2,
15    pub translation: DVec2,
16}
17
18impl DAffine2 {
19    /// The degenerate zero transform.
20    ///
21    /// This transforms any finite vector and point to zero.
22    /// The zero transform is non-invertible.
23    pub const ZERO: Self = Self {
24        matrix2: DMat2::ZERO,
25        translation: DVec2::ZERO,
26    };
27
28    /// The identity transform.
29    ///
30    /// Multiplying a vector with this returns the same vector.
31    pub const IDENTITY: Self = Self {
32        matrix2: DMat2::IDENTITY,
33        translation: DVec2::ZERO,
34    };
35
36    /// All NAN:s.
37    pub const NAN: Self = Self {
38        matrix2: DMat2::NAN,
39        translation: DVec2::NAN,
40    };
41
42    /// Creates an affine transform from three column vectors.
43    #[inline(always)]
44    #[must_use]
45    pub const fn from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self {
46        Self {
47            matrix2: DMat2::from_cols(x_axis, y_axis),
48            translation: z_axis,
49        }
50    }
51
52    /// Creates an affine transform from a `[f64; 6]` array stored in column major order.
53    #[inline]
54    #[must_use]
55    pub fn from_cols_array(m: &[f64; 6]) -> Self {
56        Self {
57            matrix2: DMat2::from_cols_array(&[m[0], m[1], m[2], m[3]]),
58            translation: DVec2::from_array([m[4], m[5]]),
59        }
60    }
61
62    /// Creates a `[f64; 6]` array storing data in column major order.
63    #[inline]
64    #[must_use]
65    pub fn to_cols_array(&self) -> [f64; 6] {
66        let x = &self.matrix2.x_axis;
67        let y = &self.matrix2.y_axis;
68        let z = &self.translation;
69        [x.x, x.y, y.x, y.y, z.x, z.y]
70    }
71
72    /// Creates an affine transform from a `[[f64; 2]; 3]`
73    /// 2D array stored in column major order.
74    /// If your data is in row major order you will need to `transpose` the returned
75    /// matrix.
76    #[inline]
77    #[must_use]
78    pub fn from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self {
79        Self {
80            matrix2: DMat2::from_cols(m[0].into(), m[1].into()),
81            translation: m[2].into(),
82        }
83    }
84
85    /// Creates a `[[f64; 2]; 3]` 2D array storing data in
86    /// column major order.
87    /// If you require data in row major order `transpose` the matrix first.
88    #[inline]
89    #[must_use]
90    pub fn to_cols_array_2d(&self) -> [[f64; 2]; 3] {
91        [
92            self.matrix2.x_axis.into(),
93            self.matrix2.y_axis.into(),
94            self.translation.into(),
95        ]
96    }
97
98    /// Creates an affine transform from the first 6 values in `slice`.
99    ///
100    /// # Panics
101    ///
102    /// Panics if `slice` is less than 6 elements long.
103    #[inline]
104    #[must_use]
105    pub fn from_cols_slice(slice: &[f64]) -> Self {
106        Self {
107            matrix2: DMat2::from_cols_slice(&slice[0..4]),
108            translation: DVec2::from_slice(&slice[4..6]),
109        }
110    }
111
112    /// Writes the columns of `self` to the first 6 elements in `slice`.
113    ///
114    /// # Panics
115    ///
116    /// Panics if `slice` is less than 6 elements long.
117    #[inline]
118    pub fn write_cols_to_slice(self, slice: &mut [f64]) {
119        self.matrix2.write_cols_to_slice(&mut slice[0..4]);
120        self.translation.write_to_slice(&mut slice[4..6]);
121    }
122
123    /// Creates an affine transform that changes scale.
124    /// Note that if any scale is zero the transform will be non-invertible.
125    #[inline]
126    #[must_use]
127    pub fn from_scale(scale: DVec2) -> Self {
128        Self {
129            matrix2: DMat2::from_diagonal(scale),
130            translation: DVec2::ZERO,
131        }
132    }
133
134    /// Creates an affine transform from the given rotation `angle`.
135    #[inline]
136    #[must_use]
137    pub fn from_angle(angle: f64) -> Self {
138        Self {
139            matrix2: DMat2::from_angle(angle),
140            translation: DVec2::ZERO,
141        }
142    }
143
144    /// Creates an affine transformation from the given 2D `translation`.
145    #[inline]
146    #[must_use]
147    pub fn from_translation(translation: DVec2) -> Self {
148        Self {
149            matrix2: DMat2::IDENTITY,
150            translation,
151        }
152    }
153
154    /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation)
155    #[inline]
156    #[must_use]
157    pub fn from_mat2(matrix2: DMat2) -> Self {
158        Self {
159            matrix2,
160            translation: DVec2::ZERO,
161        }
162    }
163
164    /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) and a
165    /// translation vector.
166    ///
167    /// Equivalent to
168    /// `DAffine2::from_translation(translation) * DAffine2::from_mat2(mat2)`
169    #[inline]
170    #[must_use]
171    pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self {
172        Self {
173            matrix2,
174            translation,
175        }
176    }
177
178    /// Creates an affine transform from the given 2D `scale`, rotation `angle` (in radians) and
179    /// `translation`.
180    ///
181    /// Equivalent to `DAffine2::from_translation(translation) *
182    /// DAffine2::from_angle(angle) * DAffine2::from_scale(scale)`
183    #[inline]
184    #[must_use]
185    pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
186        let rotation = DMat2::from_angle(angle);
187        Self {
188            matrix2: DMat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
189            translation,
190        }
191    }
192
193    /// Creates an affine transform from the given 2D rotation `angle` (in radians) and
194    /// `translation`.
195    ///
196    /// Equivalent to `DAffine2::from_translation(translation) * DAffine2::from_angle(angle)`
197    #[inline]
198    #[must_use]
199    pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self {
200        Self {
201            matrix2: DMat2::from_angle(angle),
202            translation,
203        }
204    }
205
206    /// The given `DMat3` must be an affine transform,
207    #[inline]
208    #[must_use]
209    pub fn from_mat3(m: DMat3) -> Self {
210        use crate::swizzles::Vec3Swizzles;
211        Self {
212            matrix2: DMat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
213            translation: m.z_axis.xy(),
214        }
215    }
216
217    /// Extracts `scale`, `angle` and `translation` from `self`.
218    ///
219    /// The transform is expected to be non-degenerate and without shearing, or the output
220    /// will be invalid.
221    ///
222    /// # Panics
223    ///
224    /// Will panic if the determinant `self.matrix2` is zero or if the resulting scale
225    /// vector contains any zero elements when `glam_assert` is enabled.
226    #[inline]
227    #[must_use]
228    pub fn to_scale_angle_translation(self) -> (DVec2, f64, DVec2) {
229        use crate::f64::math;
230        let det = self.matrix2.determinant();
231        glam_assert!(det != 0.0);
232
233        let scale = DVec2::new(
234            self.matrix2.x_axis.length() * math::signum(det),
235            self.matrix2.y_axis.length(),
236        );
237
238        glam_assert!(scale.cmpne(DVec2::ZERO).all());
239
240        let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
241
242        (scale, angle, self.translation)
243    }
244
245    /// Transforms the given 2D point, applying shear, scale, rotation and translation.
246    #[inline]
247    #[must_use]
248    pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
249        self.matrix2 * rhs + self.translation
250    }
251
252    /// Transforms the given 2D vector, applying shear, scale and rotation (but NOT
253    /// translation).
254    ///
255    /// To also apply translation, use [`Self::transform_point2()`] instead.
256    #[inline]
257    pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
258        self.matrix2 * rhs
259    }
260
261    /// Returns `true` if, and only if, all elements are finite.
262    ///
263    /// If any element is either `NaN`, positive or negative infinity, this will return
264    /// `false`.
265    #[inline]
266    #[must_use]
267    pub fn is_finite(&self) -> bool {
268        self.matrix2.is_finite() && self.translation.is_finite()
269    }
270
271    /// Returns `true` if any elements are `NaN`.
272    #[inline]
273    #[must_use]
274    pub fn is_nan(&self) -> bool {
275        self.matrix2.is_nan() || self.translation.is_nan()
276    }
277
278    /// Returns true if the absolute difference of all elements between `self` and `rhs`
279    /// is less than or equal to `max_abs_diff`.
280    ///
281    /// This can be used to compare if two 3x4 matrices contain similar elements. It works
282    /// best when comparing with a known value. The `max_abs_diff` that should be used used
283    /// depends on the values being compared against.
284    ///
285    /// For more see
286    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
287    #[inline]
288    #[must_use]
289    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
290        self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
291            && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
292    }
293
294    /// Return the inverse of this transform.
295    ///
296    /// Note that if the transform is not invertible the result will be invalid.
297    #[inline]
298    #[must_use]
299    pub fn inverse(&self) -> Self {
300        let matrix2 = self.matrix2.inverse();
301        // transform negative translation by the matrix inverse:
302        let translation = -(matrix2 * self.translation);
303
304        Self {
305            matrix2,
306            translation,
307        }
308    }
309
310    /// Casts all elements of `self` to `f32`.
311    #[inline]
312    #[must_use]
313    pub fn as_affine2(&self) -> crate::Affine2 {
314        crate::Affine2::from_mat2_translation(self.matrix2.as_mat2(), self.translation.as_vec2())
315    }
316}
317
318impl Default for DAffine2 {
319    #[inline(always)]
320    fn default() -> Self {
321        Self::IDENTITY
322    }
323}
324
325impl Deref for DAffine2 {
326    type Target = crate::deref::Cols3<DVec2>;
327    #[inline(always)]
328    fn deref(&self) -> &Self::Target {
329        unsafe { &*(self as *const Self as *const Self::Target) }
330    }
331}
332
333impl DerefMut for DAffine2 {
334    #[inline(always)]
335    fn deref_mut(&mut self) -> &mut Self::Target {
336        unsafe { &mut *(self as *mut Self as *mut Self::Target) }
337    }
338}
339
340impl PartialEq for DAffine2 {
341    #[inline]
342    fn eq(&self, rhs: &Self) -> bool {
343        self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
344    }
345}
346
347impl core::fmt::Debug for DAffine2 {
348    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
349        fmt.debug_struct(stringify!(DAffine2))
350            .field("matrix2", &self.matrix2)
351            .field("translation", &self.translation)
352            .finish()
353    }
354}
355
356impl core::fmt::Display for DAffine2 {
357    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
358        if let Some(p) = f.precision() {
359            write!(
360                f,
361                "[{:.*}, {:.*}, {:.*}]",
362                p, self.matrix2.x_axis, p, self.matrix2.y_axis, p, self.translation
363            )
364        } else {
365            write!(
366                f,
367                "[{}, {}, {}]",
368                self.matrix2.x_axis, self.matrix2.y_axis, self.translation
369            )
370        }
371    }
372}
373
374impl<'a> core::iter::Product<&'a Self> for DAffine2 {
375    fn product<I>(iter: I) -> Self
376    where
377        I: Iterator<Item = &'a Self>,
378    {
379        iter.fold(Self::IDENTITY, |a, &b| a * b)
380    }
381}
382
383impl Mul for DAffine2 {
384    type Output = Self;
385
386    #[inline]
387    fn mul(self, rhs: Self) -> Self {
388        Self {
389            matrix2: self.matrix2 * rhs.matrix2,
390            translation: self.matrix2 * rhs.translation + self.translation,
391        }
392    }
393}
394
395impl Mul<&Self> for DAffine2 {
396    type Output = Self;
397    #[inline]
398    fn mul(self, rhs: &Self) -> Self {
399        self.mul(*rhs)
400    }
401}
402
403impl Mul<&DAffine2> for &DAffine2 {
404    type Output = DAffine2;
405    #[inline]
406    fn mul(self, rhs: &DAffine2) -> DAffine2 {
407        (*self).mul(*rhs)
408    }
409}
410
411impl Mul<DAffine2> for &DAffine2 {
412    type Output = DAffine2;
413    #[inline]
414    fn mul(self, rhs: DAffine2) -> DAffine2 {
415        (*self).mul(rhs)
416    }
417}
418
419impl MulAssign for DAffine2 {
420    #[inline]
421    fn mul_assign(&mut self, rhs: Self) {
422        *self = self.mul(rhs);
423    }
424}
425
426impl MulAssign<&Self> for DAffine2 {
427    #[inline]
428    fn mul_assign(&mut self, rhs: &Self) {
429        self.mul_assign(*rhs);
430    }
431}
432
433impl From<DAffine2> for DMat3 {
434    #[inline]
435    fn from(m: DAffine2) -> Self {
436        Self::from_cols(
437            m.matrix2.x_axis.extend(0.0),
438            m.matrix2.y_axis.extend(0.0),
439            m.translation.extend(1.0),
440        )
441    }
442}
443
444impl Mul<DMat3> for DAffine2 {
445    type Output = DMat3;
446
447    #[inline]
448    fn mul(self, rhs: DMat3) -> Self::Output {
449        DMat3::from(self) * rhs
450    }
451}
452
453impl Mul<&DMat3> for DAffine2 {
454    type Output = DMat3;
455    #[inline]
456    fn mul(self, rhs: &DMat3) -> DMat3 {
457        self.mul(*rhs)
458    }
459}
460
461impl Mul<&DMat3> for &DAffine2 {
462    type Output = DMat3;
463    #[inline]
464    fn mul(self, rhs: &DMat3) -> DMat3 {
465        (*self).mul(*rhs)
466    }
467}
468
469impl Mul<DMat3> for &DAffine2 {
470    type Output = DMat3;
471    #[inline]
472    fn mul(self, rhs: DMat3) -> DMat3 {
473        (*self).mul(rhs)
474    }
475}
476
477impl Mul<DAffine2> for DMat3 {
478    type Output = Self;
479
480    #[inline]
481    fn mul(self, rhs: DAffine2) -> Self {
482        self * Self::from(rhs)
483    }
484}
485
486impl Mul<&DAffine2> for DMat3 {
487    type Output = Self;
488    #[inline]
489    fn mul(self, rhs: &DAffine2) -> Self {
490        self.mul(*rhs)
491    }
492}
493
494impl Mul<&DAffine2> for &DMat3 {
495    type Output = DMat3;
496    #[inline]
497    fn mul(self, rhs: &DAffine2) -> DMat3 {
498        (*self).mul(*rhs)
499    }
500}
501
502impl Mul<DAffine2> for &DMat3 {
503    type Output = DMat3;
504    #[inline]
505    fn mul(self, rhs: DAffine2) -> DMat3 {
506        (*self).mul(rhs)
507    }
508}
509
510impl MulAssign<DAffine2> for DMat3 {
511    #[inline]
512    fn mul_assign(&mut self, rhs: DAffine2) {
513        *self = self.mul(rhs);
514    }
515}
516
517impl MulAssign<&DAffine2> for DMat3 {
518    #[inline]
519    fn mul_assign(&mut self, rhs: &DAffine2) {
520        self.mul_assign(*rhs);
521    }
522}