1use crate::{DMat2, DMat3, DVec2};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[derive(Copy, Clone)]
8#[repr(C)]
9pub struct DAffine2 {
10 pub matrix2: DMat2,
11 pub translation: DVec2,
12}
13
14impl DAffine2 {
15 pub const ZERO: Self = Self {
20 matrix2: DMat2::ZERO,
21 translation: DVec2::ZERO,
22 };
23
24 pub const IDENTITY: Self = Self {
28 matrix2: DMat2::IDENTITY,
29 translation: DVec2::ZERO,
30 };
31
32 pub const NAN: Self = Self {
34 matrix2: DMat2::NAN,
35 translation: DVec2::NAN,
36 };
37
38 #[inline(always)]
40 #[must_use]
41 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 #[inline]
50 #[must_use]
51 pub fn from_cols_array(m: &[f64; 6]) -> Self {
52 Self {
53 matrix2: DMat2::from_cols_array(&[m[0], m[1], m[2], m[3]]),
54 translation: DVec2::from_array([m[4], m[5]]),
55 }
56 }
57
58 #[inline]
60 #[must_use]
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 #[inline]
73 #[must_use]
74 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 #[inline]
85 #[must_use]
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 #[inline]
100 #[must_use]
101 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 #[inline]
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 #[inline]
122 #[must_use]
123 pub fn from_scale(scale: DVec2) -> Self {
124 Self {
125 matrix2: DMat2::from_diagonal(scale),
126 translation: DVec2::ZERO,
127 }
128 }
129
130 #[inline]
132 #[must_use]
133 pub fn from_angle(angle: f64) -> Self {
134 Self {
135 matrix2: DMat2::from_angle(angle),
136 translation: DVec2::ZERO,
137 }
138 }
139
140 #[inline]
142 #[must_use]
143 pub fn from_translation(translation: DVec2) -> Self {
144 Self {
145 matrix2: DMat2::IDENTITY,
146 translation,
147 }
148 }
149
150 #[inline]
152 #[must_use]
153 pub fn from_mat2(matrix2: DMat2) -> Self {
154 Self {
155 matrix2,
156 translation: DVec2::ZERO,
157 }
158 }
159
160 #[inline]
166 #[must_use]
167 pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self {
168 Self {
169 matrix2,
170 translation,
171 }
172 }
173
174 #[inline]
180 #[must_use]
181 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 #[inline]
194 #[must_use]
195 pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self {
196 Self {
197 matrix2: DMat2::from_angle(angle),
198 translation,
199 }
200 }
201
202 #[inline]
204 #[must_use]
205 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 #[inline]
223 #[must_use]
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 #[inline]
243 #[must_use]
244 pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
245 self.matrix2 * rhs + self.translation
246 }
247
248 #[inline]
253 pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
254 self.matrix2 * rhs
255 }
256
257 #[inline]
262 #[must_use]
263 pub fn is_finite(&self) -> bool {
264 self.matrix2.is_finite() && self.translation.is_finite()
265 }
266
267 #[inline]
269 #[must_use]
270 pub fn is_nan(&self) -> bool {
271 self.matrix2.is_nan() || self.translation.is_nan()
272 }
273
274 #[inline]
284 #[must_use]
285 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 #[inline]
294 #[must_use]
295 pub fn inverse(&self) -> Self {
296 let matrix2 = self.matrix2.inverse();
297 let translation = -(matrix2 * self.translation);
299
300 Self {
301 matrix2,
302 translation,
303 }
304 }
305}
306
307impl Default for DAffine2 {
308 #[inline(always)]
309 fn default() -> Self {
310 Self::IDENTITY
311 }
312}
313
314impl Deref for DAffine2 {
315 type Target = crate::deref::Cols3<DVec2>;
316 #[inline(always)]
317 fn deref(&self) -> &Self::Target {
318 unsafe { &*(self as *const Self as *const Self::Target) }
319 }
320}
321
322impl DerefMut for DAffine2 {
323 #[inline(always)]
324 fn deref_mut(&mut self) -> &mut Self::Target {
325 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
326 }
327}
328
329impl PartialEq for DAffine2 {
330 #[inline]
331 fn eq(&self, rhs: &Self) -> bool {
332 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
333 }
334}
335
336impl core::fmt::Debug for DAffine2 {
337 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
338 fmt.debug_struct(stringify!(DAffine2))
339 .field("matrix2", &self.matrix2)
340 .field("translation", &self.translation)
341 .finish()
342 }
343}
344
345impl core::fmt::Display for DAffine2 {
346 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
347 if let Some(p) = f.precision() {
348 write!(
349 f,
350 "[{:.*}, {:.*}, {:.*}]",
351 p, self.matrix2.x_axis, p, self.matrix2.y_axis, p, self.translation
352 )
353 } else {
354 write!(
355 f,
356 "[{}, {}, {}]",
357 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
358 )
359 }
360 }
361}
362
363impl<'a> core::iter::Product<&'a Self> for DAffine2 {
364 fn product<I>(iter: I) -> Self
365 where
366 I: Iterator<Item = &'a Self>,
367 {
368 iter.fold(Self::IDENTITY, |a, &b| a * b)
369 }
370}
371
372impl Mul for DAffine2 {
373 type Output = DAffine2;
374
375 #[inline]
376 fn mul(self, rhs: DAffine2) -> Self::Output {
377 Self {
378 matrix2: self.matrix2 * rhs.matrix2,
379 translation: self.matrix2 * rhs.translation + self.translation,
380 }
381 }
382}
383
384impl MulAssign for DAffine2 {
385 #[inline]
386 fn mul_assign(&mut self, rhs: DAffine2) {
387 *self = self.mul(rhs);
388 }
389}
390
391impl From<DAffine2> for DMat3 {
392 #[inline]
393 fn from(m: DAffine2) -> DMat3 {
394 Self::from_cols(
395 m.matrix2.x_axis.extend(0.0),
396 m.matrix2.y_axis.extend(0.0),
397 m.translation.extend(1.0),
398 )
399 }
400}
401
402impl Mul<DMat3> for DAffine2 {
403 type Output = DMat3;
404
405 #[inline]
406 fn mul(self, rhs: DMat3) -> Self::Output {
407 DMat3::from(self) * rhs
408 }
409}
410
411impl Mul<DAffine2> for DMat3 {
412 type Output = DMat3;
413
414 #[inline]
415 fn mul(self, rhs: DAffine2) -> Self::Output {
416 self * DMat3::from(rhs)
417 }
418}