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 pub const fn from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self {
41 Self {
42 matrix2: DMat2::from_cols(x_axis, y_axis),
43 translation: z_axis,
44 }
45 }
46
47 #[inline]
49 pub fn from_cols_array(m: &[f64; 6]) -> Self {
50 Self {
51 matrix2: DMat2::from_cols_slice(&m[0..4]),
52 translation: DVec2::from_slice(&m[4..6]),
53 }
54 }
55
56 #[inline]
58 pub fn to_cols_array(&self) -> [f64; 6] {
59 let x = &self.matrix2.x_axis;
60 let y = &self.matrix2.y_axis;
61 let z = &self.translation;
62 [x.x, x.y, y.x, y.y, z.x, z.y]
63 }
64
65 #[inline]
70 pub fn from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self {
71 Self {
72 matrix2: DMat2::from_cols(m[0].into(), m[1].into()),
73 translation: m[2].into(),
74 }
75 }
76
77 #[inline]
81 pub fn to_cols_array_2d(&self) -> [[f64; 2]; 3] {
82 [
83 self.matrix2.x_axis.into(),
84 self.matrix2.y_axis.into(),
85 self.translation.into(),
86 ]
87 }
88
89 #[inline]
95 pub fn from_cols_slice(slice: &[f64]) -> Self {
96 Self {
97 matrix2: DMat2::from_cols_slice(&slice[0..4]),
98 translation: DVec2::from_slice(&slice[4..6]),
99 }
100 }
101
102 #[inline]
108 pub fn write_cols_to_slice(self, slice: &mut [f64]) {
109 self.matrix2.write_cols_to_slice(&mut slice[0..4]);
110 self.translation.write_to_slice(&mut slice[4..6]);
111 }
112
113 #[inline]
116 pub fn from_scale(scale: DVec2) -> Self {
117 Self {
118 matrix2: DMat2::from_diagonal(scale),
119 translation: DVec2::ZERO,
120 }
121 }
122
123 #[inline]
125 pub fn from_angle(angle: f64) -> Self {
126 Self {
127 matrix2: DMat2::from_angle(angle),
128 translation: DVec2::ZERO,
129 }
130 }
131
132 #[inline]
134 pub fn from_translation(translation: DVec2) -> Self {
135 Self {
136 matrix2: DMat2::IDENTITY,
137 translation,
138 }
139 }
140
141 #[inline]
143 pub fn from_mat2(matrix2: DMat2) -> Self {
144 Self {
145 matrix2,
146 translation: DVec2::ZERO,
147 }
148 }
149
150 #[inline]
156 pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self {
157 Self {
158 matrix2,
159 translation,
160 }
161 }
162
163 #[inline]
169 pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
170 let rotation = DMat2::from_angle(angle);
171 Self {
172 matrix2: DMat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
173 translation,
174 }
175 }
176
177 #[inline]
182 pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self {
183 Self {
184 matrix2: DMat2::from_angle(angle),
185 translation,
186 }
187 }
188
189 #[inline]
191 pub fn from_mat3(m: DMat3) -> Self {
192 use crate::swizzles::Vec3Swizzles;
193 Self {
194 matrix2: DMat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
195 translation: m.z_axis.xy(),
196 }
197 }
198
199 #[inline]
209 pub fn to_scale_angle_translation(self) -> (DVec2, f64, DVec2) {
210 use crate::f64::math;
211 let det = self.matrix2.determinant();
212 glam_assert!(det != 0.0);
213
214 let scale = DVec2::new(
215 self.matrix2.x_axis.length() * math::signum(det),
216 self.matrix2.y_axis.length(),
217 );
218
219 glam_assert!(scale.cmpne(DVec2::ZERO).all());
220
221 let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
222
223 (scale, angle, self.translation)
224 }
225
226 #[inline]
228 pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
229 self.matrix2 * rhs + self.translation
230 }
231
232 #[inline]
237 pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
238 self.matrix2 * rhs
239 }
240
241 #[inline]
246 pub fn is_finite(&self) -> bool {
247 self.matrix2.is_finite() && self.translation.is_finite()
248 }
249
250 #[inline]
252 pub fn is_nan(&self) -> bool {
253 self.matrix2.is_nan() || self.translation.is_nan()
254 }
255
256 #[inline]
266 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
267 self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
268 && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
269 }
270
271 #[must_use]
275 #[inline]
276 pub fn inverse(&self) -> Self {
277 let matrix2 = self.matrix2.inverse();
278 let translation = -(matrix2 * self.translation);
280
281 Self {
282 matrix2,
283 translation,
284 }
285 }
286}
287
288impl Default for DAffine2 {
289 #[inline(always)]
290 fn default() -> Self {
291 Self::IDENTITY
292 }
293}
294
295impl Deref for DAffine2 {
296 type Target = crate::deref::Cols3<DVec2>;
297 #[inline(always)]
298 fn deref(&self) -> &Self::Target {
299 unsafe { &*(self as *const Self as *const Self::Target) }
300 }
301}
302
303impl DerefMut for DAffine2 {
304 #[inline(always)]
305 fn deref_mut(&mut self) -> &mut Self::Target {
306 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
307 }
308}
309
310impl PartialEq for DAffine2 {
311 #[inline]
312 fn eq(&self, rhs: &Self) -> bool {
313 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
314 }
315}
316
317#[cfg(not(target_arch = "spirv"))]
318impl core::fmt::Debug for DAffine2 {
319 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
320 fmt.debug_struct(stringify!(DAffine2))
321 .field("matrix2", &self.matrix2)
322 .field("translation", &self.translation)
323 .finish()
324 }
325}
326
327#[cfg(not(target_arch = "spirv"))]
328impl core::fmt::Display for DAffine2 {
329 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
330 write!(
331 f,
332 "[{}, {}, {}]",
333 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
334 )
335 }
336}
337
338impl<'a> core::iter::Product<&'a Self> for DAffine2 {
339 fn product<I>(iter: I) -> Self
340 where
341 I: Iterator<Item = &'a Self>,
342 {
343 iter.fold(Self::IDENTITY, |a, &b| a * b)
344 }
345}
346
347impl Mul for DAffine2 {
348 type Output = DAffine2;
349
350 #[inline]
351 fn mul(self, rhs: DAffine2) -> Self::Output {
352 Self {
353 matrix2: self.matrix2 * rhs.matrix2,
354 translation: self.matrix2 * rhs.translation + self.translation,
355 }
356 }
357}
358
359impl MulAssign for DAffine2 {
360 #[inline]
361 fn mul_assign(&mut self, rhs: DAffine2) {
362 *self = self.mul(rhs);
363 }
364}
365
366impl From<DAffine2> for DMat3 {
367 #[inline]
368 fn from(m: DAffine2) -> DMat3 {
369 Self::from_cols(
370 m.matrix2.x_axis.extend(0.0),
371 m.matrix2.y_axis.extend(0.0),
372 m.translation.extend(1.0),
373 )
374 }
375}
376
377impl Mul<DMat3> for DAffine2 {
378 type Output = DMat3;
379
380 #[inline]
381 fn mul(self, rhs: DMat3) -> Self::Output {
382 DMat3::from(self) * rhs
383 }
384}
385
386impl Mul<DAffine2> for DMat3 {
387 type Output = DMat3;
388
389 #[inline]
390 fn mul(self, rhs: DAffine2) -> Self::Output {
391 self * DMat3::from(rhs)
392 }
393}