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 #[inline]
308 #[must_use]
309 pub fn as_affine2(&self) -> crate::Affine2 {
310 crate::Affine2::from_mat2_translation(self.matrix2.as_mat2(), self.translation.as_vec2())
311 }
312}
313
314impl Default for DAffine2 {
315 #[inline(always)]
316 fn default() -> Self {
317 Self::IDENTITY
318 }
319}
320
321impl Deref for DAffine2 {
322 type Target = crate::deref::Cols3<DVec2>;
323 #[inline(always)]
324 fn deref(&self) -> &Self::Target {
325 unsafe { &*(self as *const Self as *const Self::Target) }
326 }
327}
328
329impl DerefMut for DAffine2 {
330 #[inline(always)]
331 fn deref_mut(&mut self) -> &mut Self::Target {
332 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
333 }
334}
335
336impl PartialEq for DAffine2 {
337 #[inline]
338 fn eq(&self, rhs: &Self) -> bool {
339 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
340 }
341}
342
343impl core::fmt::Debug for DAffine2 {
344 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
345 fmt.debug_struct(stringify!(DAffine2))
346 .field("matrix2", &self.matrix2)
347 .field("translation", &self.translation)
348 .finish()
349 }
350}
351
352impl core::fmt::Display for DAffine2 {
353 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
354 if let Some(p) = f.precision() {
355 write!(
356 f,
357 "[{:.*}, {:.*}, {:.*}]",
358 p, self.matrix2.x_axis, p, self.matrix2.y_axis, p, self.translation
359 )
360 } else {
361 write!(
362 f,
363 "[{}, {}, {}]",
364 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
365 )
366 }
367 }
368}
369
370impl<'a> core::iter::Product<&'a Self> for DAffine2 {
371 fn product<I>(iter: I) -> Self
372 where
373 I: Iterator<Item = &'a Self>,
374 {
375 iter.fold(Self::IDENTITY, |a, &b| a * b)
376 }
377}
378
379impl Mul for DAffine2 {
380 type Output = DAffine2;
381
382 #[inline]
383 fn mul(self, rhs: DAffine2) -> Self::Output {
384 Self {
385 matrix2: self.matrix2 * rhs.matrix2,
386 translation: self.matrix2 * rhs.translation + self.translation,
387 }
388 }
389}
390
391impl MulAssign for DAffine2 {
392 #[inline]
393 fn mul_assign(&mut self, rhs: DAffine2) {
394 *self = self.mul(rhs);
395 }
396}
397
398impl From<DAffine2> for DMat3 {
399 #[inline]
400 fn from(m: DAffine2) -> DMat3 {
401 Self::from_cols(
402 m.matrix2.x_axis.extend(0.0),
403 m.matrix2.y_axis.extend(0.0),
404 m.translation.extend(1.0),
405 )
406 }
407}
408
409impl Mul<DMat3> for DAffine2 {
410 type Output = DMat3;
411
412 #[inline]
413 fn mul(self, rhs: DMat3) -> Self::Output {
414 DMat3::from(self) * rhs
415 }
416}
417
418impl Mul<DAffine2> for DMat3 {
419 type Output = DMat3;
420
421 #[inline]
422 fn mul(self, rhs: DAffine2) -> Self::Output {
423 self * DMat3::from(rhs)
424 }
425}