1use num::{One, Zero};
21use std::ops::{Div, DivAssign, Index, Mul, MulAssign};
22
23use simba::scalar::{ClosedAddAssign, ClosedMulAssign};
24
25use crate::base::allocator::Allocator;
26use crate::base::constraint::{AreMultipliable, ShapeConstraint};
27use crate::base::dimension::{Dim, U1};
28use crate::base::storage::Storage;
29use crate::base::{
30 Const, DefaultAllocator, Matrix, OMatrix, SMatrix, SVector, Scalar, Unit, Vector,
31};
32
33use crate::geometry::{Point, Rotation};
34
35impl<T: Scalar, const D: usize> Index<(usize, usize)> for Rotation<T, D> {
36 type Output = T;
37
38 #[inline]
39 fn index(&self, row_col: (usize, usize)) -> &T {
40 self.matrix().index(row_col)
41 }
42}
43
44md_impl_all!(
46 Mul, mul;
47 (Const<D>, Const<D>), (Const<D>, Const<D>)
48 const D;
49 for;
50 where;
51 self: Rotation<T, D>, right: Rotation<T, D>, Output = Rotation<T, D>;
52 [val val] => Rotation::from_matrix_unchecked(self.into_inner() * right.into_inner());
53 [ref val] => Rotation::from_matrix_unchecked(self.matrix() * right.into_inner());
54 [val ref] => Rotation::from_matrix_unchecked(self.into_inner() * right.matrix());
55 [ref ref] => Rotation::from_matrix_unchecked(self.matrix() * right.matrix());
56);
57
58md_impl_all!(
61 Div, div;
62 (Const<D>, Const<D>), (Const<D>, Const<D>)
63 const D;
64 for;
65 where;
66 self: Rotation<T, D>, right: Rotation<T, D>, Output = Rotation<T, D>;
67 [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
68 [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
69 [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
70 [ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
71);
72
73md_impl_all!(
75 Mul, mul;
76 (Const<D1>, Const<D1>), (R2, C2)
77 const D1;
78 for R2, C2, SB;
79 where R2: Dim, C2: Dim, SB: Storage<T, R2, C2>,
80 DefaultAllocator: Allocator<Const<D1>, C2>,
81 ShapeConstraint: AreMultipliable<Const<D1>, Const<D1>, R2, C2>;
82 self: Rotation<T, D1>, right: Matrix<T, R2, C2, SB>, Output = OMatrix<T, Const<D1>, C2>;
83 [val val] => self.into_inner() * right;
84 [ref val] => self.matrix() * right;
85 [val ref] => self.into_inner() * right;
86 [ref ref] => self.matrix() * right;
87);
88
89md_impl_all!(
91 Mul, mul;
92 (R1, C1), (Const<D2>, Const<D2>)
93 const D2;
94 for R1, C1, SA;
95 where R1: Dim, C1: Dim, SA: Storage<T, R1, C1>,
96 DefaultAllocator: Allocator<R1, Const<D2>>,
97 ShapeConstraint: AreMultipliable<R1, C1, Const<D2>, Const<D2>>;
98 self: Matrix<T, R1, C1, SA>, right: Rotation<T, D2>, Output = OMatrix<T, R1, Const<D2>>;
99 [val val] => self * right.into_inner();
100 [ref val] => self * right.into_inner();
101 [val ref] => self * right.matrix();
102 [ref ref] => self * right.matrix();
103);
104
105md_impl_all!(
107 Div, div;
108 (R1, C1), (Const<D2>, Const<D2>)
109 const D2;
110 for R1, C1, SA;
111 where R1: Dim, C1: Dim, SA: Storage<T, R1, C1>,
112 DefaultAllocator: Allocator<R1, Const<D2>>,
113 ShapeConstraint: AreMultipliable<R1, C1, Const<D2>, Const<D2>>;
114 self: Matrix<T, R1, C1, SA>, right: Rotation<T, D2>, Output = OMatrix<T, R1, Const<D2>>;
115 [val val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
116 [ref val] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
117 [val ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
118 [ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * right.inverse() };
119);
120
121md_impl_all!(
125 Mul, mul;
126 (Const<D>, Const<D>), (Const<D>, U1)
127 const D;
128 for;
129 where ShapeConstraint: AreMultipliable<Const<D>, Const<D>, Const<D>, U1>;
130 self: Rotation<T, D>, right: Point<T, D>, Output = Point<T, D>;
131 [val val] => self.into_inner() * right;
132 [ref val] => self.matrix() * right;
133 [val ref] => self.into_inner() * right;
134 [ref ref] => self.matrix() * right;
135);
136
137md_impl_all!(
139 Mul, mul;
140 (Const<D>, Const<D>), (Const<D>, U1)
141 const D;
142 for S;
143 where S: Storage<T, Const<D>>,
144 ShapeConstraint: AreMultipliable<Const<D>, Const<D>, Const<D>, U1>;
145 self: Rotation<T, D>, right: Unit<Vector<T, Const<D>, S>>, Output = Unit<SVector<T, D>>;
146 [val val] => Unit::new_unchecked(self.into_inner() * right.into_inner());
147 [ref val] => Unit::new_unchecked(self.matrix() * right.into_inner());
148 [val ref] => Unit::new_unchecked(self.into_inner() * right.as_ref());
149 [ref ref] => Unit::new_unchecked(self.matrix() * right.as_ref());
150);
151
152md_assign_impl_all!(
156 MulAssign, mul_assign;
157 (Const<D>, Const<D>), (Const<D>, Const<D>)
158 const D; for; where;
159 self: Rotation<T, D>, right: Rotation<T, D>;
160 [val] => self.matrix_mut_unchecked().mul_assign(right.into_inner());
161 [ref] => self.matrix_mut_unchecked().mul_assign(right.matrix());
162);
163
164md_assign_impl_all!(
165 DivAssign, div_assign;
166 (Const<D>, Const<D>), (Const<D>, Const<D>)
167 const D; for; where;
168 self: Rotation<T, D>, right: Rotation<T, D>;
169 [val] => self.matrix_mut_unchecked().mul_assign(right.inverse().into_inner());
170 [ref] => self.matrix_mut_unchecked().mul_assign(right.inverse().matrix());
171);
172
173md_assign_impl_all!(
180 MulAssign, mul_assign;
181 (Const<R1>, Const<C1>), (Const<C1>, Const<C1>)
182 const R1, C1; for; where;
183 self: SMatrix<T, R1, C1>, right: Rotation<T, C1>;
184 [val] => self.mul_assign(right.into_inner());
185 [ref] => self.mul_assign(right.matrix());
186);
187
188md_assign_impl_all!(
189 DivAssign, div_assign;
190 (Const<R1>, Const<C1>), (Const<C1>, Const<C1>)
191 const R1, C1; for; where;
192 self: SMatrix<T, R1, C1>, right: Rotation<T, C1>;
193 [val] => self.mul_assign(right.inverse().into_inner());
194 [ref] => self.mul_assign(right.inverse().matrix());
195);