1 // Generated from affine.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{DMat2, DMat3, DVec2};
4 use 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)]
9 pub struct DAffine2 {
10     pub matrix2: DMat2,
11     pub translation: DVec2,
12 }
13 
14 impl 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     #[must_use]
from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self41     pub const fn from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self {
42         Self {
43             matrix2: DMat2::from_cols(x_axis, y_axis),
44             translation: z_axis,
45         }
46     }
47 
48     /// Creates an affine transform from a `[f64; 6]` array stored in column major order.
49     #[inline]
50     #[must_use]
from_cols_array(m: &[f64; 6]) -> Self51     pub fn from_cols_array(m: &[f64; 6]) -> Self {
52         Self {
53             matrix2: DMat2::from_cols_slice(&m[0..4]),
54             translation: DVec2::from_slice(&m[4..6]),
55         }
56     }
57 
58     /// Creates a `[f64; 6]` array storing data in column major order.
59     #[inline]
60     #[must_use]
to_cols_array(&self) -> [f64; 6]61     pub fn to_cols_array(&self) -> [f64; 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 `[[f64; 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]
from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self74     pub fn from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self {
75         Self {
76             matrix2: DMat2::from_cols(m[0].into(), m[1].into()),
77             translation: m[2].into(),
78         }
79     }
80 
81     /// Creates a `[[f64; 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]
to_cols_array_2d(&self) -> [[f64; 2]; 3]86     pub fn to_cols_array_2d(&self) -> [[f64; 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]
from_cols_slice(slice: &[f64]) -> Self101     pub fn from_cols_slice(slice: &[f64]) -> Self {
102         Self {
103             matrix2: DMat2::from_cols_slice(&slice[0..4]),
104             translation: DVec2::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]
write_cols_to_slice(self, slice: &mut [f64])114     pub fn write_cols_to_slice(self, slice: &mut [f64]) {
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]
from_scale(scale: DVec2) -> Self123     pub fn from_scale(scale: DVec2) -> Self {
124         Self {
125             matrix2: DMat2::from_diagonal(scale),
126             translation: DVec2::ZERO,
127         }
128     }
129 
130     /// Creates an affine transform from the given rotation `angle`.
131     #[inline]
132     #[must_use]
from_angle(angle: f64) -> Self133     pub fn from_angle(angle: f64) -> Self {
134         Self {
135             matrix2: DMat2::from_angle(angle),
136             translation: DVec2::ZERO,
137         }
138     }
139 
140     /// Creates an affine transformation from the given 2D `translation`.
141     #[inline]
142     #[must_use]
from_translation(translation: DVec2) -> Self143     pub fn from_translation(translation: DVec2) -> Self {
144         Self {
145             matrix2: DMat2::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]
from_mat2(matrix2: DMat2) -> Self153     pub fn from_mat2(matrix2: DMat2) -> Self {
154         Self {
155             matrix2,
156             translation: DVec2::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     /// `DAffine2::from_translation(translation) * DAffine2::from_mat2(mat2)`
165     #[inline]
166     #[must_use]
from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self167     pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> 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 `DAffine2::from_translation(translation) *
178     /// DAffine2::from_angle(angle) * DAffine2::from_scale(scale)`
179     #[inline]
180     #[must_use]
from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self181     pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
182         let rotation = DMat2::from_angle(angle);
183         Self {
184             matrix2: DMat2::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 `DAffine2::from_translation(translation) * DAffine2::from_angle(angle)`
193     #[inline]
194     #[must_use]
from_angle_translation(angle: f64, translation: DVec2) -> Self195     pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self {
196         Self {
197             matrix2: DMat2::from_angle(angle),
198             translation,
199         }
200     }
201 
202     /// The given `DMat3` must be an affine transform,
203     #[inline]
204     #[must_use]
from_mat3(m: DMat3) -> Self205     pub fn from_mat3(m: DMat3) -> Self {
206         use crate::swizzles::Vec3Swizzles;
207         Self {
208             matrix2: DMat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
209             translation: m.z_axis.xy(),
210         }
211     }
212 
213     /// Extracts `scale`, `angle` and `translation` from `self`.
214     ///
215     /// The transform is expected to be non-degenerate and without shearing, or the output
216     /// will be invalid.
217     ///
218     /// # Panics
219     ///
220     /// Will panic if the determinant `self.matrix2` is zero or if the resulting scale
221     /// vector contains any zero elements when `glam_assert` is enabled.
222     #[inline]
223     #[must_use]
to_scale_angle_translation(self) -> (DVec2, f64, DVec2)224     pub fn to_scale_angle_translation(self) -> (DVec2, f64, DVec2) {
225         use crate::f64::math;
226         let det = self.matrix2.determinant();
227         glam_assert!(det != 0.0);
228 
229         let scale = DVec2::new(
230             self.matrix2.x_axis.length() * math::signum(det),
231             self.matrix2.y_axis.length(),
232         );
233 
234         glam_assert!(scale.cmpne(DVec2::ZERO).all());
235 
236         let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
237 
238         (scale, angle, self.translation)
239     }
240 
241     /// Transforms the given 2D point, applying shear, scale, rotation and translation.
242     #[inline]
243     #[must_use]
transform_point2(&self, rhs: DVec2) -> DVec2244     pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
245         self.matrix2 * rhs + self.translation
246     }
247 
248     /// Transforms the given 2D vector, applying shear, scale and rotation (but NOT
249     /// translation).
250     ///
251     /// To also apply translation, use [`Self::transform_point2()`] instead.
252     #[inline]
transform_vector2(&self, rhs: DVec2) -> DVec2253     pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
254         self.matrix2 * rhs
255     }
256 
257     /// Returns `true` if, and only if, all elements are finite.
258     ///
259     /// If any element is either `NaN`, positive or negative infinity, this will return
260     /// `false`.
261     #[inline]
262     #[must_use]
is_finite(&self) -> bool263     pub fn is_finite(&self) -> bool {
264         self.matrix2.is_finite() && self.translation.is_finite()
265     }
266 
267     /// Returns `true` if any elements are `NaN`.
268     #[inline]
269     #[must_use]
is_nan(&self) -> bool270     pub fn is_nan(&self) -> bool {
271         self.matrix2.is_nan() || self.translation.is_nan()
272     }
273 
274     /// Returns true if the absolute difference of all elements between `self` and `rhs`
275     /// is less than or equal to `max_abs_diff`.
276     ///
277     /// This can be used to compare if two 3x4 matrices contain similar elements. It works
278     /// best when comparing with a known value. The `max_abs_diff` that should be used used
279     /// depends on the values being compared against.
280     ///
281     /// For more see
282     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
283     #[inline]
284     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool285     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
286         self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
287             && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
288     }
289 
290     /// Return the inverse of this transform.
291     ///
292     /// Note that if the transform is not invertible the result will be invalid.
293     #[inline]
294     #[must_use]
inverse(&self) -> Self295     pub fn inverse(&self) -> Self {
296         let matrix2 = self.matrix2.inverse();
297         // transform negative translation by the matrix inverse:
298         let translation = -(matrix2 * self.translation);
299 
300         Self {
301             matrix2,
302             translation,
303         }
304     }
305 }
306 
307 impl Default for DAffine2 {
308     #[inline(always)]
default() -> Self309     fn default() -> Self {
310         Self::IDENTITY
311     }
312 }
313 
314 impl Deref for DAffine2 {
315     type Target = crate::deref::Cols3<DVec2>;
316     #[inline(always)]
deref(&self) -> &Self::Target317     fn deref(&self) -> &Self::Target {
318         unsafe { &*(self as *const Self as *const Self::Target) }
319     }
320 }
321 
322 impl DerefMut for DAffine2 {
323     #[inline(always)]
deref_mut(&mut self) -> &mut Self::Target324     fn deref_mut(&mut self) -> &mut Self::Target {
325         unsafe { &mut *(self as *mut Self as *mut Self::Target) }
326     }
327 }
328 
329 impl PartialEq for DAffine2 {
330     #[inline]
eq(&self, rhs: &Self) -> bool331     fn eq(&self, rhs: &Self) -> bool {
332         self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
333     }
334 }
335 
336 #[cfg(not(target_arch = "spirv"))]
337 impl core::fmt::Debug for DAffine2 {
fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result338     fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
339         fmt.debug_struct(stringify!(DAffine2))
340             .field("matrix2", &self.matrix2)
341             .field("translation", &self.translation)
342             .finish()
343     }
344 }
345 
346 #[cfg(not(target_arch = "spirv"))]
347 impl core::fmt::Display for DAffine2 {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result348     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
349         write!(
350             f,
351             "[{}, {}, {}]",
352             self.matrix2.x_axis, self.matrix2.y_axis, self.translation
353         )
354     }
355 }
356 
357 impl<'a> core::iter::Product<&'a Self> for DAffine2 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,358     fn product<I>(iter: I) -> Self
359     where
360         I: Iterator<Item = &'a Self>,
361     {
362         iter.fold(Self::IDENTITY, |a, &b| a * b)
363     }
364 }
365 
366 impl Mul for DAffine2 {
367     type Output = DAffine2;
368 
369     #[inline]
mul(self, rhs: DAffine2) -> Self::Output370     fn mul(self, rhs: DAffine2) -> Self::Output {
371         Self {
372             matrix2: self.matrix2 * rhs.matrix2,
373             translation: self.matrix2 * rhs.translation + self.translation,
374         }
375     }
376 }
377 
378 impl MulAssign for DAffine2 {
379     #[inline]
mul_assign(&mut self, rhs: DAffine2)380     fn mul_assign(&mut self, rhs: DAffine2) {
381         *self = self.mul(rhs);
382     }
383 }
384 
385 impl From<DAffine2> for DMat3 {
386     #[inline]
from(m: DAffine2) -> DMat3387     fn from(m: DAffine2) -> DMat3 {
388         Self::from_cols(
389             m.matrix2.x_axis.extend(0.0),
390             m.matrix2.y_axis.extend(0.0),
391             m.translation.extend(1.0),
392         )
393     }
394 }
395 
396 impl Mul<DMat3> for DAffine2 {
397     type Output = DMat3;
398 
399     #[inline]
mul(self, rhs: DMat3) -> Self::Output400     fn mul(self, rhs: DMat3) -> Self::Output {
401         DMat3::from(self) * rhs
402     }
403 }
404 
405 impl Mul<DAffine2> for DMat3 {
406     type Output = DMat3;
407 
408     #[inline]
mul(self, rhs: DAffine2) -> Self::Output409     fn mul(self, rhs: DAffine2) -> Self::Output {
410         self * DMat3::from(rhs)
411     }
412 }
413