1use crate::{Mat2, Mat3, Mat3A, Vec2, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[derive(Copy, Clone)]
8#[repr(C)]
9pub struct Affine2 {
10 pub matrix2: Mat2,
11 pub translation: Vec2,
12}
13
14impl Affine2 {
15 pub const ZERO: Self = Self {
20 matrix2: Mat2::ZERO,
21 translation: Vec2::ZERO,
22 };
23
24 pub const IDENTITY: Self = Self {
28 matrix2: Mat2::IDENTITY,
29 translation: Vec2::ZERO,
30 };
31
32 pub const NAN: Self = Self {
34 matrix2: Mat2::NAN,
35 translation: Vec2::NAN,
36 };
37
38 #[inline(always)]
40 #[must_use]
41 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2, z_axis: Vec2) -> Self {
42 Self {
43 matrix2: Mat2::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: &[f32; 6]) -> Self {
52 Self {
53 matrix2: Mat2::from_cols_array(&[m[0], m[1], m[2], m[3]]),
54 translation: Vec2::from_array([m[4], m[5]]),
55 }
56 }
57
58 #[inline]
60 #[must_use]
61 pub fn to_cols_array(&self) -> [f32; 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: &[[f32; 2]; 3]) -> Self {
75 Self {
76 matrix2: Mat2::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) -> [[f32; 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: &[f32]) -> Self {
102 Self {
103 matrix2: Mat2::from_cols_slice(&slice[0..4]),
104 translation: Vec2::from_slice(&slice[4..6]),
105 }
106 }
107
108 #[inline]
114 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
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: Vec2) -> Self {
124 Self {
125 matrix2: Mat2::from_diagonal(scale),
126 translation: Vec2::ZERO,
127 }
128 }
129
130 #[inline]
132 #[must_use]
133 pub fn from_angle(angle: f32) -> Self {
134 Self {
135 matrix2: Mat2::from_angle(angle),
136 translation: Vec2::ZERO,
137 }
138 }
139
140 #[inline]
142 #[must_use]
143 pub fn from_translation(translation: Vec2) -> Self {
144 Self {
145 matrix2: Mat2::IDENTITY,
146 translation,
147 }
148 }
149
150 #[inline]
152 #[must_use]
153 pub fn from_mat2(matrix2: Mat2) -> Self {
154 Self {
155 matrix2,
156 translation: Vec2::ZERO,
157 }
158 }
159
160 #[inline]
166 #[must_use]
167 pub fn from_mat2_translation(matrix2: Mat2, translation: Vec2) -> Self {
168 Self {
169 matrix2,
170 translation,
171 }
172 }
173
174 #[inline]
180 #[must_use]
181 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
182 let rotation = Mat2::from_angle(angle);
183 Self {
184 matrix2: Mat2::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: f32, translation: Vec2) -> Self {
196 Self {
197 matrix2: Mat2::from_angle(angle),
198 translation,
199 }
200 }
201
202 #[inline]
204 #[must_use]
205 pub fn from_mat3(m: Mat3) -> Self {
206 use crate::swizzles::Vec3Swizzles;
207 Self {
208 matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
209 translation: m.z_axis.xy(),
210 }
211 }
212
213 #[inline]
215 #[must_use]
216 pub fn from_mat3a(m: Mat3A) -> Self {
217 use crate::swizzles::Vec3Swizzles;
218 Self {
219 matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
220 translation: m.z_axis.xy(),
221 }
222 }
223
224 #[inline]
234 #[must_use]
235 pub fn to_scale_angle_translation(self) -> (Vec2, f32, Vec2) {
236 use crate::f32::math;
237 let det = self.matrix2.determinant();
238 glam_assert!(det != 0.0);
239
240 let scale = Vec2::new(
241 self.matrix2.x_axis.length() * math::signum(det),
242 self.matrix2.y_axis.length(),
243 );
244
245 glam_assert!(scale.cmpne(Vec2::ZERO).all());
246
247 let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
248
249 (scale, angle, self.translation)
250 }
251
252 #[inline]
254 #[must_use]
255 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
256 self.matrix2 * rhs + self.translation
257 }
258
259 #[inline]
264 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
265 self.matrix2 * rhs
266 }
267
268 #[inline]
273 #[must_use]
274 pub fn is_finite(&self) -> bool {
275 self.matrix2.is_finite() && self.translation.is_finite()
276 }
277
278 #[inline]
280 #[must_use]
281 pub fn is_nan(&self) -> bool {
282 self.matrix2.is_nan() || self.translation.is_nan()
283 }
284
285 #[inline]
295 #[must_use]
296 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
297 self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
298 && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
299 }
300
301 #[inline]
305 #[must_use]
306 pub fn inverse(&self) -> Self {
307 let matrix2 = self.matrix2.inverse();
308 let translation = -(matrix2 * self.translation);
310
311 Self {
312 matrix2,
313 translation,
314 }
315 }
316}
317
318impl Default for Affine2 {
319 #[inline(always)]
320 fn default() -> Self {
321 Self::IDENTITY
322 }
323}
324
325impl Deref for Affine2 {
326 type Target = crate::deref::Cols3<Vec2>;
327 #[inline(always)]
328 fn deref(&self) -> &Self::Target {
329 unsafe { &*(self as *const Self as *const Self::Target) }
330 }
331}
332
333impl DerefMut for Affine2 {
334 #[inline(always)]
335 fn deref_mut(&mut self) -> &mut Self::Target {
336 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
337 }
338}
339
340impl PartialEq for Affine2 {
341 #[inline]
342 fn eq(&self, rhs: &Self) -> bool {
343 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
344 }
345}
346
347impl core::fmt::Debug for Affine2 {
348 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
349 fmt.debug_struct(stringify!(Affine2))
350 .field("matrix2", &self.matrix2)
351 .field("translation", &self.translation)
352 .finish()
353 }
354}
355
356impl core::fmt::Display for Affine2 {
357 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
358 if let Some(p) = f.precision() {
359 write!(
360 f,
361 "[{:.*}, {:.*}, {:.*}]",
362 p, self.matrix2.x_axis, p, self.matrix2.y_axis, p, self.translation
363 )
364 } else {
365 write!(
366 f,
367 "[{}, {}, {}]",
368 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
369 )
370 }
371 }
372}
373
374impl<'a> core::iter::Product<&'a Self> for Affine2 {
375 fn product<I>(iter: I) -> Self
376 where
377 I: Iterator<Item = &'a Self>,
378 {
379 iter.fold(Self::IDENTITY, |a, &b| a * b)
380 }
381}
382
383impl Mul for Affine2 {
384 type Output = Affine2;
385
386 #[inline]
387 fn mul(self, rhs: Affine2) -> Self::Output {
388 Self {
389 matrix2: self.matrix2 * rhs.matrix2,
390 translation: self.matrix2 * rhs.translation + self.translation,
391 }
392 }
393}
394
395impl MulAssign for Affine2 {
396 #[inline]
397 fn mul_assign(&mut self, rhs: Affine2) {
398 *self = self.mul(rhs);
399 }
400}
401
402impl From<Affine2> for Mat3 {
403 #[inline]
404 fn from(m: Affine2) -> Mat3 {
405 Self::from_cols(
406 m.matrix2.x_axis.extend(0.0),
407 m.matrix2.y_axis.extend(0.0),
408 m.translation.extend(1.0),
409 )
410 }
411}
412
413impl Mul<Mat3> for Affine2 {
414 type Output = Mat3;
415
416 #[inline]
417 fn mul(self, rhs: Mat3) -> Self::Output {
418 Mat3::from(self) * rhs
419 }
420}
421
422impl Mul<Affine2> for Mat3 {
423 type Output = Mat3;
424
425 #[inline]
426 fn mul(self, rhs: Affine2) -> Self::Output {
427 self * Mat3::from(rhs)
428 }
429}
430
431impl From<Affine2> for Mat3A {
432 #[inline]
433 fn from(m: Affine2) -> Mat3A {
434 Self::from_cols(
435 Vec3A::from((m.matrix2.x_axis, 0.0)),
436 Vec3A::from((m.matrix2.y_axis, 0.0)),
437 Vec3A::from((m.translation, 1.0)),
438 )
439 }
440}
441
442impl Mul<Mat3A> for Affine2 {
443 type Output = Mat3A;
444
445 #[inline]
446 fn mul(self, rhs: Mat3A) -> Self::Output {
447 Mat3A::from(self) * rhs
448 }
449}
450
451impl Mul<Affine2> for Mat3A {
452 type Output = Mat3A;
453
454 #[inline]
455 fn mul(self, rhs: Affine2) -> Self::Output {
456 self * Mat3A::from(rhs)
457 }
458}