1use nalgebra::{Affine3, Rotation3, Unit, Vector3};
2use num_traits::Float;
3
4use crate::Number;
5
6pub trait Affine3Ext<T: Number> {
13 fn scale(self, factor: T) -> Self;
15
16 fn scale_xyz(self, factors: Vector3<T>) -> Self;
18
19 fn rotate_x(self, angle_deg: T) -> Self;
21
22 fn rotate_y(self, angle_deg: T) -> Self;
24
25 fn rotate_z(self, angle_deg: T) -> Self;
27
28 fn rotate_axis(self, axis: Unit<Vector3<T>>, angle_deg: T) -> Self;
30
31 fn translate(self, offset: Vector3<T>) -> Self;
33}
34
35impl<T: Number> Affine3Ext<T> for Affine3<T> {
36 fn scale(self, factor: T) -> Self {
37 self.scale_xyz(Vector3::new(factor, factor, factor))
38 }
39
40 fn scale_xyz(self, factors: Vector3<T>) -> Self {
41 let m = nalgebra::Matrix4::new_nonuniform_scaling(&factors);
42 Affine3::from_matrix_unchecked(m) * self
43 }
44
45 fn rotate_x(self, angle_deg: T) -> Self {
46 self.rotate_axis(Unit::new_normalize(Vector3::x()), angle_deg)
47 }
48
49 fn rotate_y(self, angle_deg: T) -> Self {
50 self.rotate_axis(Unit::new_normalize(Vector3::y()), angle_deg)
51 }
52
53 fn rotate_z(self, angle_deg: T) -> Self {
54 self.rotate_axis(Unit::new_normalize(Vector3::z()), angle_deg)
55 }
56
57 fn rotate_axis(self, axis: Unit<Vector3<T>>, angle_deg: T) -> Self {
58 let rot = Rotation3::from_axis_angle(&axis, Float::to_radians(angle_deg));
59 Affine3::from_matrix_unchecked(rot.to_homogeneous()) * self
60 }
61
62 fn translate(self, offset: Vector3<T>) -> Self {
63 let m = nalgebra::Matrix4::new_translation(&offset);
64 Affine3::from_matrix_unchecked(m) * self
65 }
66}