1use crate::{DMat2, DMat3, DVec2};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[cfg(feature = "zerocopy-08")]
7use zerocopy_derive_08::*;
8
9#[derive(Copy, Clone)]
11#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
12#[cfg_attr(
13 feature = "zerocopy-08",
14 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
15)]
16#[repr(C)]
17pub struct DAffine2 {
18 pub matrix2: DMat2,
19 pub translation: DVec2,
20}
21
22impl DAffine2 {
23 pub const ZERO: Self = Self {
28 matrix2: DMat2::ZERO,
29 translation: DVec2::ZERO,
30 };
31
32 pub const IDENTITY: Self = Self {
36 matrix2: DMat2::IDENTITY,
37 translation: DVec2::ZERO,
38 };
39
40 pub const NAN: Self = Self {
42 matrix2: DMat2::NAN,
43 translation: DVec2::NAN,
44 };
45
46 #[inline(always)]
48 #[must_use]
49 pub const fn from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self {
50 Self {
51 matrix2: DMat2::from_cols(x_axis, y_axis),
52 translation: z_axis,
53 }
54 }
55
56 #[inline]
58 #[must_use]
59 pub fn from_cols_array(m: &[f64; 6]) -> Self {
60 Self {
61 matrix2: DMat2::from_cols_array(&[m[0], m[1], m[2], m[3]]),
62 translation: DVec2::from_array([m[4], m[5]]),
63 }
64 }
65
66 #[inline]
68 #[must_use]
69 pub fn to_cols_array(&self) -> [f64; 6] {
70 let x = &self.matrix2.x_axis;
71 let y = &self.matrix2.y_axis;
72 let z = &self.translation;
73 [x.x, x.y, y.x, y.y, z.x, z.y]
74 }
75
76 #[inline]
81 #[must_use]
82 pub fn from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self {
83 Self {
84 matrix2: DMat2::from_cols(m[0].into(), m[1].into()),
85 translation: m[2].into(),
86 }
87 }
88
89 #[inline]
93 #[must_use]
94 pub fn to_cols_array_2d(&self) -> [[f64; 2]; 3] {
95 [
96 self.matrix2.x_axis.into(),
97 self.matrix2.y_axis.into(),
98 self.translation.into(),
99 ]
100 }
101
102 #[inline]
108 #[must_use]
109 pub fn from_cols_slice(slice: &[f64]) -> Self {
110 Self {
111 matrix2: DMat2::from_cols_slice(&slice[0..4]),
112 translation: DVec2::from_slice(&slice[4..6]),
113 }
114 }
115
116 #[inline]
122 pub fn write_cols_to_slice(&self, slice: &mut [f64]) {
123 self.matrix2.write_cols_to_slice(&mut slice[0..4]);
124 self.translation.write_to_slice(&mut slice[4..6]);
125 }
126
127 #[inline]
130 #[must_use]
131 pub fn from_scale(scale: DVec2) -> Self {
132 Self {
133 matrix2: DMat2::from_diagonal(scale),
134 translation: DVec2::ZERO,
135 }
136 }
137
138 #[inline]
140 #[must_use]
141 pub fn from_angle(angle: f64) -> Self {
142 Self {
143 matrix2: DMat2::from_angle(angle),
144 translation: DVec2::ZERO,
145 }
146 }
147
148 #[inline]
150 #[must_use]
151 pub fn from_translation(translation: DVec2) -> Self {
152 Self {
153 matrix2: DMat2::IDENTITY,
154 translation,
155 }
156 }
157
158 #[inline]
160 #[must_use]
161 pub fn from_mat2(matrix2: DMat2) -> Self {
162 Self {
163 matrix2,
164 translation: DVec2::ZERO,
165 }
166 }
167
168 #[inline]
174 #[must_use]
175 pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self {
176 Self {
177 matrix2,
178 translation,
179 }
180 }
181
182 #[inline]
188 #[must_use]
189 pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
190 let rotation = DMat2::from_angle(angle);
191 Self {
192 matrix2: DMat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
193 translation,
194 }
195 }
196
197 #[inline]
202 #[must_use]
203 pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self {
204 Self {
205 matrix2: DMat2::from_angle(angle),
206 translation,
207 }
208 }
209
210 #[inline]
212 #[must_use]
213 pub fn from_mat3(m: DMat3) -> Self {
214 use crate::swizzles::Vec3Swizzles;
215 Self {
216 matrix2: DMat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
217 translation: m.z_axis.xy(),
218 }
219 }
220
221 #[inline]
231 #[must_use]
232 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
233 pub fn to_scale_angle_translation(&self) -> (DVec2, f64, DVec2) {
234 use crate::f64::math;
235 let det = self.matrix2.determinant();
236 glam_assert!(det != 0.0);
237
238 let scale = DVec2::new(
239 self.matrix2.x_axis.length() * math::signum(det),
240 self.matrix2.y_axis.length(),
241 );
242
243 glam_assert!(scale.cmpne(DVec2::ZERO).all());
244
245 let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
246
247 (scale, angle, self.translation)
248 }
249
250 #[inline]
252 #[must_use]
253 pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
254 self.matrix2 * rhs + self.translation
255 }
256
257 #[inline]
262 pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
263 self.matrix2 * rhs
264 }
265
266 #[inline]
271 #[must_use]
272 pub fn is_finite(&self) -> bool {
273 self.matrix2.is_finite() && self.translation.is_finite()
274 }
275
276 #[inline]
278 #[must_use]
279 pub fn is_nan(&self) -> bool {
280 self.matrix2.is_nan() || self.translation.is_nan()
281 }
282
283 #[inline]
293 #[must_use]
294 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
295 self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
296 && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
297 }
298
299 #[inline]
307 #[must_use]
308 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
309 pub fn inverse(&self) -> Self {
310 let matrix2 = self.matrix2.inverse();
311 let translation = -(matrix2 * self.translation);
313
314 Self {
315 matrix2,
316 translation,
317 }
318 }
319
320 #[inline]
322 #[must_use]
323 pub fn as_affine2(&self) -> crate::Affine2 {
324 crate::Affine2::from_mat2_translation(self.matrix2.as_mat2(), self.translation.as_vec2())
325 }
326}
327
328impl Default for DAffine2 {
329 #[inline(always)]
330 fn default() -> Self {
331 Self::IDENTITY
332 }
333}
334
335impl Deref for DAffine2 {
336 type Target = crate::deref::Cols3<DVec2>;
337 #[inline(always)]
338 fn deref(&self) -> &Self::Target {
339 unsafe { &*(self as *const Self as *const Self::Target) }
340 }
341}
342
343impl DerefMut for DAffine2 {
344 #[inline(always)]
345 fn deref_mut(&mut self) -> &mut Self::Target {
346 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
347 }
348}
349
350impl PartialEq for DAffine2 {
351 #[inline]
352 fn eq(&self, rhs: &Self) -> bool {
353 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
354 }
355}
356
357impl core::fmt::Debug for DAffine2 {
358 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
359 fmt.debug_struct(stringify!(DAffine2))
360 .field("matrix2", &self.matrix2)
361 .field("translation", &self.translation)
362 .finish()
363 }
364}
365
366impl core::fmt::Display for DAffine2 {
367 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
368 if let Some(p) = f.precision() {
369 write!(
370 f,
371 "[{:.*}, {:.*}, {:.*}]",
372 p, self.matrix2.x_axis, p, self.matrix2.y_axis, p, self.translation
373 )
374 } else {
375 write!(
376 f,
377 "[{}, {}, {}]",
378 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
379 )
380 }
381 }
382}
383
384impl<'a> core::iter::Product<&'a Self> for DAffine2 {
385 fn product<I>(iter: I) -> Self
386 where
387 I: Iterator<Item = &'a Self>,
388 {
389 iter.fold(Self::IDENTITY, |a, &b| a * b)
390 }
391}
392
393impl Mul for DAffine2 {
394 type Output = Self;
395
396 #[inline]
397 fn mul(self, rhs: Self) -> Self {
398 Self {
399 matrix2: self.matrix2 * rhs.matrix2,
400 translation: self.matrix2 * rhs.translation + self.translation,
401 }
402 }
403}
404
405impl Mul<&Self> for DAffine2 {
406 type Output = Self;
407 #[inline]
408 fn mul(self, rhs: &Self) -> Self {
409 self.mul(*rhs)
410 }
411}
412
413impl Mul<&DAffine2> for &DAffine2 {
414 type Output = DAffine2;
415 #[inline]
416 fn mul(self, rhs: &DAffine2) -> DAffine2 {
417 (*self).mul(*rhs)
418 }
419}
420
421impl Mul<DAffine2> for &DAffine2 {
422 type Output = DAffine2;
423 #[inline]
424 fn mul(self, rhs: DAffine2) -> DAffine2 {
425 (*self).mul(rhs)
426 }
427}
428
429impl MulAssign for DAffine2 {
430 #[inline]
431 fn mul_assign(&mut self, rhs: Self) {
432 *self = self.mul(rhs);
433 }
434}
435
436impl MulAssign<&Self> for DAffine2 {
437 #[inline]
438 fn mul_assign(&mut self, rhs: &Self) {
439 self.mul_assign(*rhs);
440 }
441}
442
443impl From<DAffine2> for DMat3 {
444 #[inline]
445 fn from(m: DAffine2) -> Self {
446 Self::from_cols(
447 m.matrix2.x_axis.extend(0.0),
448 m.matrix2.y_axis.extend(0.0),
449 m.translation.extend(1.0),
450 )
451 }
452}
453
454impl Mul<DMat3> for DAffine2 {
455 type Output = DMat3;
456
457 #[inline]
458 fn mul(self, rhs: DMat3) -> Self::Output {
459 DMat3::from(self) * rhs
460 }
461}
462
463impl Mul<&DMat3> for DAffine2 {
464 type Output = DMat3;
465 #[inline]
466 fn mul(self, rhs: &DMat3) -> DMat3 {
467 self.mul(*rhs)
468 }
469}
470
471impl Mul<&DMat3> for &DAffine2 {
472 type Output = DMat3;
473 #[inline]
474 fn mul(self, rhs: &DMat3) -> DMat3 {
475 (*self).mul(*rhs)
476 }
477}
478
479impl Mul<DMat3> for &DAffine2 {
480 type Output = DMat3;
481 #[inline]
482 fn mul(self, rhs: DMat3) -> DMat3 {
483 (*self).mul(rhs)
484 }
485}
486
487impl Mul<DAffine2> for DMat3 {
488 type Output = Self;
489
490 #[inline]
491 fn mul(self, rhs: DAffine2) -> Self {
492 self * Self::from(rhs)
493 }
494}
495
496impl Mul<&DAffine2> for DMat3 {
497 type Output = Self;
498 #[inline]
499 fn mul(self, rhs: &DAffine2) -> Self {
500 self.mul(*rhs)
501 }
502}
503
504impl Mul<&DAffine2> for &DMat3 {
505 type Output = DMat3;
506 #[inline]
507 fn mul(self, rhs: &DAffine2) -> DMat3 {
508 (*self).mul(*rhs)
509 }
510}
511
512impl Mul<DAffine2> for &DMat3 {
513 type Output = DMat3;
514 #[inline]
515 fn mul(self, rhs: DAffine2) -> DMat3 {
516 (*self).mul(rhs)
517 }
518}
519
520impl MulAssign<DAffine2> for DMat3 {
521 #[inline]
522 fn mul_assign(&mut self, rhs: DAffine2) {
523 *self = self.mul(rhs);
524 }
525}
526
527impl MulAssign<&DAffine2> for DMat3 {
528 #[inline]
529 fn mul_assign(&mut self, rhs: &DAffine2) {
530 self.mul_assign(*rhs);
531 }
532}