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