1 // Generated from affine.rs.tera template. Edit the template, not the generated file. 2 3 use crate::{DMat2, DMat3, DVec2}; 4 use core::ops::{Deref, DerefMut, Mul, MulAssign}; 5 6 /// A 2D affine transform, which can represent translation, rotation, scaling and shear. 7 #[derive(Copy, Clone)] 8 #[repr(C)] 9 pub struct DAffine2 { 10 pub matrix2: DMat2, 11 pub translation: DVec2, 12 } 13 14 impl DAffine2 { 15 /// The degenerate zero transform. 16 /// 17 /// This transforms any finite vector and point to zero. 18 /// The zero transform is non-invertible. 19 pub const ZERO: Self = Self { 20 matrix2: DMat2::ZERO, 21 translation: DVec2::ZERO, 22 }; 23 24 /// The identity transform. 25 /// 26 /// Multiplying a vector with this returns the same vector. 27 pub const IDENTITY: Self = Self { 28 matrix2: DMat2::IDENTITY, 29 translation: DVec2::ZERO, 30 }; 31 32 /// All NAN:s. 33 pub const NAN: Self = Self { 34 matrix2: DMat2::NAN, 35 translation: DVec2::NAN, 36 }; 37 38 /// Creates an affine transform from three column vectors. 39 #[inline(always)] 40 #[must_use] from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self41 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 /// Creates an affine transform from a `[f64; 6]` array stored in column major order. 49 #[inline] 50 #[must_use] from_cols_array(m: &[f64; 6]) -> Self51 pub fn from_cols_array(m: &[f64; 6]) -> Self { 52 Self { 53 matrix2: DMat2::from_cols_slice(&m[0..4]), 54 translation: DVec2::from_slice(&m[4..6]), 55 } 56 } 57 58 /// Creates a `[f64; 6]` array storing data in column major order. 59 #[inline] 60 #[must_use] to_cols_array(&self) -> [f64; 6]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 /// Creates an affine transform from a `[[f64; 2]; 3]` 69 /// 2D array stored in column major order. 70 /// If your data is in row major order you will need to `transpose` the returned 71 /// matrix. 72 #[inline] 73 #[must_use] from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self74 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 /// Creates a `[[f64; 2]; 3]` 2D array storing data in 82 /// column major order. 83 /// If you require data in row major order `transpose` the matrix first. 84 #[inline] 85 #[must_use] to_cols_array_2d(&self) -> [[f64; 2]; 3]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 /// Creates an affine transform from the first 6 values in `slice`. 95 /// 96 /// # Panics 97 /// 98 /// Panics if `slice` is less than 6 elements long. 99 #[inline] 100 #[must_use] from_cols_slice(slice: &[f64]) -> Self101 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 /// Writes the columns of `self` to the first 6 elements in `slice`. 109 /// 110 /// # Panics 111 /// 112 /// Panics if `slice` is less than 6 elements long. 113 #[inline] write_cols_to_slice(self, slice: &mut [f64])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 /// Creates an affine transform that changes scale. 120 /// Note that if any scale is zero the transform will be non-invertible. 121 #[inline] 122 #[must_use] from_scale(scale: DVec2) -> Self123 pub fn from_scale(scale: DVec2) -> Self { 124 Self { 125 matrix2: DMat2::from_diagonal(scale), 126 translation: DVec2::ZERO, 127 } 128 } 129 130 /// Creates an affine transform from the given rotation `angle`. 131 #[inline] 132 #[must_use] from_angle(angle: f64) -> Self133 pub fn from_angle(angle: f64) -> Self { 134 Self { 135 matrix2: DMat2::from_angle(angle), 136 translation: DVec2::ZERO, 137 } 138 } 139 140 /// Creates an affine transformation from the given 2D `translation`. 141 #[inline] 142 #[must_use] from_translation(translation: DVec2) -> Self143 pub fn from_translation(translation: DVec2) -> Self { 144 Self { 145 matrix2: DMat2::IDENTITY, 146 translation, 147 } 148 } 149 150 /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) 151 #[inline] 152 #[must_use] from_mat2(matrix2: DMat2) -> Self153 pub fn from_mat2(matrix2: DMat2) -> Self { 154 Self { 155 matrix2, 156 translation: DVec2::ZERO, 157 } 158 } 159 160 /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) and a 161 /// translation vector. 162 /// 163 /// Equivalent to 164 /// `DAffine2::from_translation(translation) * DAffine2::from_mat2(mat2)` 165 #[inline] 166 #[must_use] from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self167 pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self { 168 Self { 169 matrix2, 170 translation, 171 } 172 } 173 174 /// Creates an affine transform from the given 2D `scale`, rotation `angle` (in radians) and 175 /// `translation`. 176 /// 177 /// Equivalent to `DAffine2::from_translation(translation) * 178 /// DAffine2::from_angle(angle) * DAffine2::from_scale(scale)` 179 #[inline] 180 #[must_use] from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self181 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 /// Creates an affine transform from the given 2D rotation `angle` (in radians) and 190 /// `translation`. 191 /// 192 /// Equivalent to `DAffine2::from_translation(translation) * DAffine2::from_angle(angle)` 193 #[inline] 194 #[must_use] from_angle_translation(angle: f64, translation: DVec2) -> Self195 pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self { 196 Self { 197 matrix2: DMat2::from_angle(angle), 198 translation, 199 } 200 } 201 202 /// The given `DMat3` must be an affine transform, 203 #[inline] 204 #[must_use] from_mat3(m: DMat3) -> Self205 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 /// Extracts `scale`, `angle` and `translation` from `self`. 214 /// 215 /// The transform is expected to be non-degenerate and without shearing, or the output 216 /// will be invalid. 217 /// 218 /// # Panics 219 /// 220 /// Will panic if the determinant `self.matrix2` is zero or if the resulting scale 221 /// vector contains any zero elements when `glam_assert` is enabled. 222 #[inline] 223 #[must_use] to_scale_angle_translation(self) -> (DVec2, f64, DVec2)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 /// Transforms the given 2D point, applying shear, scale, rotation and translation. 242 #[inline] 243 #[must_use] transform_point2(&self, rhs: DVec2) -> DVec2244 pub fn transform_point2(&self, rhs: DVec2) -> DVec2 { 245 self.matrix2 * rhs + self.translation 246 } 247 248 /// Transforms the given 2D vector, applying shear, scale and rotation (but NOT 249 /// translation). 250 /// 251 /// To also apply translation, use [`Self::transform_point2()`] instead. 252 #[inline] transform_vector2(&self, rhs: DVec2) -> DVec2253 pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 { 254 self.matrix2 * rhs 255 } 256 257 /// Returns `true` if, and only if, all elements are finite. 258 /// 259 /// If any element is either `NaN`, positive or negative infinity, this will return 260 /// `false`. 261 #[inline] 262 #[must_use] is_finite(&self) -> bool263 pub fn is_finite(&self) -> bool { 264 self.matrix2.is_finite() && self.translation.is_finite() 265 } 266 267 /// Returns `true` if any elements are `NaN`. 268 #[inline] 269 #[must_use] is_nan(&self) -> bool270 pub fn is_nan(&self) -> bool { 271 self.matrix2.is_nan() || self.translation.is_nan() 272 } 273 274 /// Returns true if the absolute difference of all elements between `self` and `rhs` 275 /// is less than or equal to `max_abs_diff`. 276 /// 277 /// This can be used to compare if two 3x4 matrices contain similar elements. It works 278 /// best when comparing with a known value. The `max_abs_diff` that should be used used 279 /// depends on the values being compared against. 280 /// 281 /// For more see 282 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/). 283 #[inline] 284 #[must_use] abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool285 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 /// Return the inverse of this transform. 291 /// 292 /// Note that if the transform is not invertible the result will be invalid. 293 #[inline] 294 #[must_use] inverse(&self) -> Self295 pub fn inverse(&self) -> Self { 296 let matrix2 = self.matrix2.inverse(); 297 // transform negative translation by the matrix inverse: 298 let translation = -(matrix2 * self.translation); 299 300 Self { 301 matrix2, 302 translation, 303 } 304 } 305 } 306 307 impl Default for DAffine2 { 308 #[inline(always)] default() -> Self309 fn default() -> Self { 310 Self::IDENTITY 311 } 312 } 313 314 impl Deref for DAffine2 { 315 type Target = crate::deref::Cols3<DVec2>; 316 #[inline(always)] deref(&self) -> &Self::Target317 fn deref(&self) -> &Self::Target { 318 unsafe { &*(self as *const Self as *const Self::Target) } 319 } 320 } 321 322 impl DerefMut for DAffine2 { 323 #[inline(always)] deref_mut(&mut self) -> &mut Self::Target324 fn deref_mut(&mut self) -> &mut Self::Target { 325 unsafe { &mut *(self as *mut Self as *mut Self::Target) } 326 } 327 } 328 329 impl PartialEq for DAffine2 { 330 #[inline] eq(&self, rhs: &Self) -> bool331 fn eq(&self, rhs: &Self) -> bool { 332 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation) 333 } 334 } 335 336 #[cfg(not(target_arch = "spirv"))] 337 impl core::fmt::Debug for DAffine2 { fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result338 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 339 fmt.debug_struct(stringify!(DAffine2)) 340 .field("matrix2", &self.matrix2) 341 .field("translation", &self.translation) 342 .finish() 343 } 344 } 345 346 #[cfg(not(target_arch = "spirv"))] 347 impl core::fmt::Display for DAffine2 { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result348 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 349 write!( 350 f, 351 "[{}, {}, {}]", 352 self.matrix2.x_axis, self.matrix2.y_axis, self.translation 353 ) 354 } 355 } 356 357 impl<'a> core::iter::Product<&'a Self> for DAffine2 { product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,358 fn product<I>(iter: I) -> Self 359 where 360 I: Iterator<Item = &'a Self>, 361 { 362 iter.fold(Self::IDENTITY, |a, &b| a * b) 363 } 364 } 365 366 impl Mul for DAffine2 { 367 type Output = DAffine2; 368 369 #[inline] mul(self, rhs: DAffine2) -> Self::Output370 fn mul(self, rhs: DAffine2) -> Self::Output { 371 Self { 372 matrix2: self.matrix2 * rhs.matrix2, 373 translation: self.matrix2 * rhs.translation + self.translation, 374 } 375 } 376 } 377 378 impl MulAssign for DAffine2 { 379 #[inline] mul_assign(&mut self, rhs: DAffine2)380 fn mul_assign(&mut self, rhs: DAffine2) { 381 *self = self.mul(rhs); 382 } 383 } 384 385 impl From<DAffine2> for DMat3 { 386 #[inline] from(m: DAffine2) -> DMat3387 fn from(m: DAffine2) -> DMat3 { 388 Self::from_cols( 389 m.matrix2.x_axis.extend(0.0), 390 m.matrix2.y_axis.extend(0.0), 391 m.translation.extend(1.0), 392 ) 393 } 394 } 395 396 impl Mul<DMat3> for DAffine2 { 397 type Output = DMat3; 398 399 #[inline] mul(self, rhs: DMat3) -> Self::Output400 fn mul(self, rhs: DMat3) -> Self::Output { 401 DMat3::from(self) * rhs 402 } 403 } 404 405 impl Mul<DAffine2> for DMat3 { 406 type Output = DMat3; 407 408 #[inline] mul(self, rhs: DAffine2) -> Self::Output409 fn mul(self, rhs: DAffine2) -> Self::Output { 410 self * DMat3::from(rhs) 411 } 412 } 413