1 use alga::general::{
2     AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup,
3     AbstractSemigroup, Id, Identity, Multiplicative, RealField, TwoSidedInverse,
4 };
5 use alga::linear::Isometry as AlgaIsometry;
6 use alga::linear::{
7     AffineTransformation, DirectIsometry, ProjectiveTransformation, Rotation, Similarity,
8     Transformation,
9 };
10 
11 use crate::base::SVector;
12 
13 use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
14 
15 /*
16  *
17  * Algebraic structures.
18  *
19  */
20 impl<T: RealField + simba::scalar::RealField, R, const D: usize> Identity<Multiplicative>
21     for Isometry<T, R, D>
22 where
23     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
24 {
25     #[inline]
identity() -> Self26     fn identity() -> Self {
27         Self::identity()
28     }
29 }
30 
31 impl<T: RealField + simba::scalar::RealField, R, const D: usize> TwoSidedInverse<Multiplicative>
32     for Isometry<T, R, D>
33 where
34     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
35 {
36     #[inline]
37     #[must_use = "Did you mean to use two_sided_inverse_mut()?"]
two_sided_inverse(&self) -> Self38     fn two_sided_inverse(&self) -> Self {
39         self.inverse()
40     }
41 
42     #[inline]
two_sided_inverse_mut(&mut self)43     fn two_sided_inverse_mut(&mut self) {
44         self.inverse_mut()
45     }
46 }
47 
48 impl<T: RealField + simba::scalar::RealField, R, const D: usize> AbstractMagma<Multiplicative>
49     for Isometry<T, R, D>
50 where
51     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
52 {
53     #[inline]
operate(&self, rhs: &Self) -> Self54     fn operate(&self, rhs: &Self) -> Self {
55         self * rhs
56     }
57 }
58 
59 macro_rules! impl_multiplicative_structures(
60     ($($marker: ident<$operator: ident>),* $(,)*) => {$(
61         impl<T: RealField + simba::scalar::RealField, R, const D: usize> $marker<$operator> for Isometry<T, R, D>
62             where R: Rotation<Point<T, D>> + AbstractRotation<T, D> { }
63     )*}
64 );
65 
66 impl_multiplicative_structures!(
67     AbstractSemigroup<Multiplicative>,
68     AbstractMonoid<Multiplicative>,
69     AbstractQuasigroup<Multiplicative>,
70     AbstractLoop<Multiplicative>,
71     AbstractGroup<Multiplicative>
72 );
73 
74 /*
75  *
76  * Transformation groups.
77  *
78  */
79 impl<T: RealField + simba::scalar::RealField, R, const D: usize> Transformation<Point<T, D>>
80     for Isometry<T, R, D>
81 where
82     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
83 {
84     #[inline]
transform_point(&self, pt: &Point<T, D>) -> Point<T, D>85     fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
86         self.transform_point(pt)
87     }
88 
89     #[inline]
transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D>90     fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
91         self.transform_vector(v)
92     }
93 }
94 
95 impl<T: RealField + simba::scalar::RealField, R, const D: usize>
96     ProjectiveTransformation<Point<T, D>> for Isometry<T, R, D>
97 where
98     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
99 {
100     #[inline]
inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D>101     fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
102         self.inverse_transform_point(pt)
103     }
104 
105     #[inline]
inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D>106     fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
107         self.inverse_transform_vector(v)
108     }
109 }
110 
111 impl<T: RealField + simba::scalar::RealField, R, const D: usize> AffineTransformation<Point<T, D>>
112     for Isometry<T, R, D>
113 where
114     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
115 {
116     type Rotation = R;
117     type NonUniformScaling = Id;
118     type Translation = Translation<T, D>;
119 
120     #[inline]
decompose(&self) -> (Self::Translation, R, Id, R)121     fn decompose(&self) -> (Self::Translation, R, Id, R) {
122         (
123             self.translation,
124             self.rotation.clone(),
125             Id::new(),
126             <R as AbstractRotation<T, D>>::identity(),
127         )
128     }
129 
130     #[inline]
append_translation(&self, t: &Self::Translation) -> Self131     fn append_translation(&self, t: &Self::Translation) -> Self {
132         t * self
133     }
134 
135     #[inline]
prepend_translation(&self, t: &Self::Translation) -> Self136     fn prepend_translation(&self, t: &Self::Translation) -> Self {
137         self * t
138     }
139 
140     #[inline]
append_rotation(&self, r: &Self::Rotation) -> Self141     fn append_rotation(&self, r: &Self::Rotation) -> Self {
142         let shift = Transformation::transform_vector(r, &self.translation.vector);
143         Isometry::from_parts(Translation::from(shift), r.clone() * self.rotation.clone())
144     }
145 
146     #[inline]
prepend_rotation(&self, r: &Self::Rotation) -> Self147     fn prepend_rotation(&self, r: &Self::Rotation) -> Self {
148         Isometry::from_parts(self.translation, self.rotation.prepend_rotation(r))
149     }
150 
151     #[inline]
append_scaling(&self, _: &Self::NonUniformScaling) -> Self152     fn append_scaling(&self, _: &Self::NonUniformScaling) -> Self {
153         self.clone()
154     }
155 
156     #[inline]
prepend_scaling(&self, _: &Self::NonUniformScaling) -> Self157     fn prepend_scaling(&self, _: &Self::NonUniformScaling) -> Self {
158         self.clone()
159     }
160 
161     #[inline]
append_rotation_wrt_point(&self, r: &Self::Rotation, p: &Point<T, D>) -> Option<Self>162     fn append_rotation_wrt_point(&self, r: &Self::Rotation, p: &Point<T, D>) -> Option<Self> {
163         let mut res = self.clone();
164         res.append_rotation_wrt_point_mut(r, p);
165         Some(res)
166     }
167 }
168 
169 impl<T: RealField + simba::scalar::RealField, R, const D: usize> Similarity<Point<T, D>>
170     for Isometry<T, R, D>
171 where
172     R: Rotation<Point<T, D>> + AbstractRotation<T, D>,
173 {
174     type Scaling = Id;
175 
176     #[inline]
translation(&self) -> Translation<T, D>177     fn translation(&self) -> Translation<T, D> {
178         self.translation
179     }
180 
181     #[inline]
rotation(&self) -> R182     fn rotation(&self) -> R {
183         self.rotation.clone()
184     }
185 
186     #[inline]
scaling(&self) -> Id187     fn scaling(&self) -> Id {
188         Id::new()
189     }
190 }
191 
192 macro_rules! marker_impl(
193     ($($Trait: ident),*) => {$(
194         impl<T: RealField + simba::scalar::RealField, R, const D: usize> $Trait<Point<T, D>> for Isometry<T, R, D>
195         where R: Rotation<Point<T, D>> + AbstractRotation<T, D> { }
196     )*}
197 );
198 
199 marker_impl!(AlgaIsometry, DirectIsometry);
200