glam/f32/
affine2.rs

1// Generated from affine.rs.tera template. Edit the template, not the generated file.
2
3use crate::{Mat2, Mat3, Mat3A, Vec2, Vec3A};
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 Affine2 {
10    pub matrix2: Mat2,
11    pub translation: Vec2,
12}
13
14impl Affine2 {
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: Mat2::ZERO,
21        translation: Vec2::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: Mat2::IDENTITY,
29        translation: Vec2::ZERO,
30    };
31
32    /// All NAN:s.
33    pub const NAN: Self = Self {
34        matrix2: Mat2::NAN,
35        translation: Vec2::NAN,
36    };
37
38    /// Creates an affine transform from three column vectors.
39    #[inline(always)]
40    #[must_use]
41    pub const fn from_cols(x_axis: Vec2, y_axis: Vec2, z_axis: Vec2) -> Self {
42        Self {
43            matrix2: Mat2::from_cols(x_axis, y_axis),
44            translation: z_axis,
45        }
46    }
47
48    /// Creates an affine transform from a `[f32; 6]` array stored in column major order.
49    #[inline]
50    #[must_use]
51    pub fn from_cols_array(m: &[f32; 6]) -> Self {
52        Self {
53            matrix2: Mat2::from_cols_array(&[m[0], m[1], m[2], m[3]]),
54            translation: Vec2::from_array([m[4], m[5]]),
55        }
56    }
57
58    /// Creates a `[f32; 6]` array storing data in column major order.
59    #[inline]
60    #[must_use]
61    pub fn to_cols_array(&self) -> [f32; 6] {
62        let x = &self.matrix2.x_axis;
63        let y = &self.matrix2.y_axis;
64        let z = &self.translation;
65        [x.x, x.y, y.x, y.y, z.x, z.y]
66    }
67
68    /// Creates an affine transform from a `[[f32; 2]; 3]`
69    /// 2D array stored in column major order.
70    /// If your data is in row major order you will need to `transpose` the returned
71    /// matrix.
72    #[inline]
73    #[must_use]
74    pub fn from_cols_array_2d(m: &[[f32; 2]; 3]) -> Self {
75        Self {
76            matrix2: Mat2::from_cols(m[0].into(), m[1].into()),
77            translation: m[2].into(),
78        }
79    }
80
81    /// Creates a `[[f32; 2]; 3]` 2D array storing data in
82    /// column major order.
83    /// If you require data in row major order `transpose` the matrix first.
84    #[inline]
85    #[must_use]
86    pub fn to_cols_array_2d(&self) -> [[f32; 2]; 3] {
87        [
88            self.matrix2.x_axis.into(),
89            self.matrix2.y_axis.into(),
90            self.translation.into(),
91        ]
92    }
93
94    /// Creates an affine transform from the first 6 values in `slice`.
95    ///
96    /// # Panics
97    ///
98    /// Panics if `slice` is less than 6 elements long.
99    #[inline]
100    #[must_use]
101    pub fn from_cols_slice(slice: &[f32]) -> Self {
102        Self {
103            matrix2: Mat2::from_cols_slice(&slice[0..4]),
104            translation: Vec2::from_slice(&slice[4..6]),
105        }
106    }
107
108    /// Writes the columns of `self` to the first 6 elements in `slice`.
109    ///
110    /// # Panics
111    ///
112    /// Panics if `slice` is less than 6 elements long.
113    #[inline]
114    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
115        self.matrix2.write_cols_to_slice(&mut slice[0..4]);
116        self.translation.write_to_slice(&mut slice[4..6]);
117    }
118
119    /// Creates an affine transform that changes scale.
120    /// Note that if any scale is zero the transform will be non-invertible.
121    #[inline]
122    #[must_use]
123    pub fn from_scale(scale: Vec2) -> Self {
124        Self {
125            matrix2: Mat2::from_diagonal(scale),
126            translation: Vec2::ZERO,
127        }
128    }
129
130    /// Creates an affine transform from the given rotation `angle`.
131    #[inline]
132    #[must_use]
133    pub fn from_angle(angle: f32) -> Self {
134        Self {
135            matrix2: Mat2::from_angle(angle),
136            translation: Vec2::ZERO,
137        }
138    }
139
140    /// Creates an affine transformation from the given 2D `translation`.
141    #[inline]
142    #[must_use]
143    pub fn from_translation(translation: Vec2) -> Self {
144        Self {
145            matrix2: Mat2::IDENTITY,
146            translation,
147        }
148    }
149
150    /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation)
151    #[inline]
152    #[must_use]
153    pub fn from_mat2(matrix2: Mat2) -> Self {
154        Self {
155            matrix2,
156            translation: Vec2::ZERO,
157        }
158    }
159
160    /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) and a
161    /// translation vector.
162    ///
163    /// Equivalent to
164    /// `Affine2::from_translation(translation) * Affine2::from_mat2(mat2)`
165    #[inline]
166    #[must_use]
167    pub fn from_mat2_translation(matrix2: Mat2, translation: Vec2) -> Self {
168        Self {
169            matrix2,
170            translation,
171        }
172    }
173
174    /// Creates an affine transform from the given 2D `scale`, rotation `angle` (in radians) and
175    /// `translation`.
176    ///
177    /// Equivalent to `Affine2::from_translation(translation) *
178    /// Affine2::from_angle(angle) * Affine2::from_scale(scale)`
179    #[inline]
180    #[must_use]
181    pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
182        let rotation = Mat2::from_angle(angle);
183        Self {
184            matrix2: Mat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
185            translation,
186        }
187    }
188
189    /// Creates an affine transform from the given 2D rotation `angle` (in radians) and
190    /// `translation`.
191    ///
192    /// Equivalent to `Affine2::from_translation(translation) * Affine2::from_angle(angle)`
193    #[inline]
194    #[must_use]
195    pub fn from_angle_translation(angle: f32, translation: Vec2) -> Self {
196        Self {
197            matrix2: Mat2::from_angle(angle),
198            translation,
199        }
200    }
201
202    /// The given `Mat3` must be an affine transform,
203    #[inline]
204    #[must_use]
205    pub fn from_mat3(m: Mat3) -> Self {
206        use crate::swizzles::Vec3Swizzles;
207        Self {
208            matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
209            translation: m.z_axis.xy(),
210        }
211    }
212
213    /// The given [`Mat3A`] must be an affine transform,
214    #[inline]
215    #[must_use]
216    pub fn from_mat3a(m: Mat3A) -> Self {
217        use crate::swizzles::Vec3Swizzles;
218        Self {
219            matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
220            translation: m.z_axis.xy(),
221        }
222    }
223
224    /// Extracts `scale`, `angle` and `translation` from `self`.
225    ///
226    /// The transform is expected to be non-degenerate and without shearing, or the output
227    /// will be invalid.
228    ///
229    /// # Panics
230    ///
231    /// Will panic if the determinant `self.matrix2` is zero or if the resulting scale
232    /// vector contains any zero elements when `glam_assert` is enabled.
233    #[inline]
234    #[must_use]
235    pub fn to_scale_angle_translation(self) -> (Vec2, f32, Vec2) {
236        use crate::f32::math;
237        let det = self.matrix2.determinant();
238        glam_assert!(det != 0.0);
239
240        let scale = Vec2::new(
241            self.matrix2.x_axis.length() * math::signum(det),
242            self.matrix2.y_axis.length(),
243        );
244
245        glam_assert!(scale.cmpne(Vec2::ZERO).all());
246
247        let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
248
249        (scale, angle, self.translation)
250    }
251
252    /// Transforms the given 2D point, applying shear, scale, rotation and translation.
253    #[inline]
254    #[must_use]
255    pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
256        self.matrix2 * rhs + self.translation
257    }
258
259    /// Transforms the given 2D vector, applying shear, scale and rotation (but NOT
260    /// translation).
261    ///
262    /// To also apply translation, use [`Self::transform_point2()`] instead.
263    #[inline]
264    pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
265        self.matrix2 * rhs
266    }
267
268    /// Returns `true` if, and only if, all elements are finite.
269    ///
270    /// If any element is either `NaN`, positive or negative infinity, this will return
271    /// `false`.
272    #[inline]
273    #[must_use]
274    pub fn is_finite(&self) -> bool {
275        self.matrix2.is_finite() && self.translation.is_finite()
276    }
277
278    /// Returns `true` if any elements are `NaN`.
279    #[inline]
280    #[must_use]
281    pub fn is_nan(&self) -> bool {
282        self.matrix2.is_nan() || self.translation.is_nan()
283    }
284
285    /// Returns true if the absolute difference of all elements between `self` and `rhs`
286    /// is less than or equal to `max_abs_diff`.
287    ///
288    /// This can be used to compare if two 3x4 matrices contain similar elements. It works
289    /// best when comparing with a known value. The `max_abs_diff` that should be used used
290    /// depends on the values being compared against.
291    ///
292    /// For more see
293    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
294    #[inline]
295    #[must_use]
296    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
297        self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
298            && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
299    }
300
301    /// Return the inverse of this transform.
302    ///
303    /// Note that if the transform is not invertible the result will be invalid.
304    #[inline]
305    #[must_use]
306    pub fn inverse(&self) -> Self {
307        let matrix2 = self.matrix2.inverse();
308        // transform negative translation by the matrix inverse:
309        let translation = -(matrix2 * self.translation);
310
311        Self {
312            matrix2,
313            translation,
314        }
315    }
316}
317
318impl Default for Affine2 {
319    #[inline(always)]
320    fn default() -> Self {
321        Self::IDENTITY
322    }
323}
324
325impl Deref for Affine2 {
326    type Target = crate::deref::Cols3<Vec2>;
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 Affine2 {
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 Affine2 {
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 Affine2 {
348    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
349        fmt.debug_struct(stringify!(Affine2))
350            .field("matrix2", &self.matrix2)
351            .field("translation", &self.translation)
352            .finish()
353    }
354}
355
356impl core::fmt::Display for Affine2 {
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 Affine2 {
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 Affine2 {
384    type Output = Affine2;
385
386    #[inline]
387    fn mul(self, rhs: Affine2) -> Self::Output {
388        Self {
389            matrix2: self.matrix2 * rhs.matrix2,
390            translation: self.matrix2 * rhs.translation + self.translation,
391        }
392    }
393}
394
395impl MulAssign for Affine2 {
396    #[inline]
397    fn mul_assign(&mut self, rhs: Affine2) {
398        *self = self.mul(rhs);
399    }
400}
401
402impl From<Affine2> for Mat3 {
403    #[inline]
404    fn from(m: Affine2) -> Mat3 {
405        Self::from_cols(
406            m.matrix2.x_axis.extend(0.0),
407            m.matrix2.y_axis.extend(0.0),
408            m.translation.extend(1.0),
409        )
410    }
411}
412
413impl Mul<Mat3> for Affine2 {
414    type Output = Mat3;
415
416    #[inline]
417    fn mul(self, rhs: Mat3) -> Self::Output {
418        Mat3::from(self) * rhs
419    }
420}
421
422impl Mul<Affine2> for Mat3 {
423    type Output = Mat3;
424
425    #[inline]
426    fn mul(self, rhs: Affine2) -> Self::Output {
427        self * Mat3::from(rhs)
428    }
429}
430
431impl From<Affine2> for Mat3A {
432    #[inline]
433    fn from(m: Affine2) -> Mat3A {
434        Self::from_cols(
435            Vec3A::from((m.matrix2.x_axis, 0.0)),
436            Vec3A::from((m.matrix2.y_axis, 0.0)),
437            Vec3A::from((m.translation, 1.0)),
438        )
439    }
440}
441
442impl Mul<Mat3A> for Affine2 {
443    type Output = Mat3A;
444
445    #[inline]
446    fn mul(self, rhs: Mat3A) -> Self::Output {
447        Mat3A::from(self) * rhs
448    }
449}
450
451impl Mul<Affine2> for Mat3A {
452    type Output = Mat3A;
453
454    #[inline]
455    fn mul(self, rhs: Affine2) -> Self::Output {
456        self * Mat3A::from(rhs)
457    }
458}