1#![allow(clippy::op_ref)]
3
4use std::ops::{Div, DivAssign, Mul, MulAssign};
5
6use crate::base::storage::Storage;
7use crate::base::{Const, Unit, Vector, Vector2};
8use crate::geometry::{Isometry, Point2, Rotation, Similarity, Translation, UnitComplex};
9use simba::simd::SimdRealField;
10
11impl<T: SimdRealField> Mul<Self> for UnitComplex<T> {
47 type Output = Self;
48
49 #[inline]
50 fn mul(self, rhs: Self) -> Self {
51 Unit::new_unchecked(self.into_inner() * rhs.into_inner())
52 }
53}
54
55impl<'a, T: SimdRealField> Mul<UnitComplex<T>> for &'a UnitComplex<T>
56where
57 T::Element: SimdRealField,
58{
59 type Output = UnitComplex<T>;
60
61 #[inline]
62 fn mul(self, rhs: UnitComplex<T>) -> Self::Output {
63 Unit::new_unchecked(self.complex() * rhs.into_inner())
64 }
65}
66
67impl<'b, T: SimdRealField> Mul<&'b UnitComplex<T>> for UnitComplex<T>
68where
69 T::Element: SimdRealField,
70{
71 type Output = Self;
72
73 #[inline]
74 fn mul(self, rhs: &'b UnitComplex<T>) -> Self::Output {
75 Unit::new_unchecked(self.into_inner() * rhs.as_ref())
76 }
77}
78
79impl<'a, 'b, T: SimdRealField> Mul<&'b UnitComplex<T>> for &'a UnitComplex<T>
80where
81 T::Element: SimdRealField,
82{
83 type Output = UnitComplex<T>;
84
85 #[inline]
86 fn mul(self, rhs: &'b UnitComplex<T>) -> Self::Output {
87 Unit::new_unchecked(self.complex() * rhs.as_ref())
88 }
89}
90
91impl<T: SimdRealField> Div<Self> for UnitComplex<T>
93where
94 T::Element: SimdRealField,
95{
96 type Output = Self;
97
98 #[inline]
99 fn div(self, rhs: Self) -> Self::Output {
100 #[allow(clippy::suspicious_arithmetic_impl)]
101 Unit::new_unchecked(self.into_inner() * rhs.conjugate().into_inner())
102 }
103}
104
105impl<'a, T: SimdRealField> Div<UnitComplex<T>> for &'a UnitComplex<T>
106where
107 T::Element: SimdRealField,
108{
109 type Output = UnitComplex<T>;
110
111 #[inline]
112 fn div(self, rhs: UnitComplex<T>) -> Self::Output {
113 #[allow(clippy::suspicious_arithmetic_impl)]
114 Unit::new_unchecked(self.complex() * rhs.conjugate().into_inner())
115 }
116}
117
118impl<'b, T: SimdRealField> Div<&'b UnitComplex<T>> for UnitComplex<T>
119where
120 T::Element: SimdRealField,
121{
122 type Output = Self;
123
124 #[inline]
125 fn div(self, rhs: &'b UnitComplex<T>) -> Self::Output {
126 #[allow(clippy::suspicious_arithmetic_impl)]
127 Unit::new_unchecked(self.into_inner() * rhs.conjugate().into_inner())
128 }
129}
130
131impl<'a, 'b, T: SimdRealField> Div<&'b UnitComplex<T>> for &'a UnitComplex<T>
132where
133 T::Element: SimdRealField,
134{
135 type Output = UnitComplex<T>;
136
137 #[inline]
138 fn div(self, rhs: &'b UnitComplex<T>) -> Self::Output {
139 #[allow(clippy::suspicious_arithmetic_impl)]
140 Unit::new_unchecked(self.complex() * rhs.conjugate().into_inner())
141 }
142}
143
144macro_rules! complex_op_impl(
145 ($Op: ident, $op: ident;
146 $($Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*;
147 $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
148 $action: expr; $($lives: tt),*) => {
149 impl<$($lives ,)* T: SimdRealField $(, $Storage: $StoragesBound $(<$($BoundParam),*>)*)*> $Op<$Rhs> for $Lhs
150 where T::Element: SimdRealField {
151 type Output = $Result;
152
153 #[inline]
154 fn $op($lhs, $rhs: $Rhs) -> Self::Output {
155 $action
156 }
157 }
158 }
159);
160
161macro_rules! complex_op_impl_all(
162 ($Op: ident, $op: ident;
163 $($Storage: ident: $StoragesBound: ident $(<$($BoundParam: ty),*>)*),*;
164 $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
165 [val val] => $action_val_val: expr;
166 [ref val] => $action_ref_val: expr;
167 [val ref] => $action_val_ref: expr;
168 [ref ref] => $action_ref_ref: expr;) => {
169
170 complex_op_impl!($Op, $op;
171 $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
172 $lhs: $Lhs, $rhs: $Rhs, Output = $Result;
173 $action_val_val; );
174
175 complex_op_impl!($Op, $op;
176 $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
177 $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result;
178 $action_ref_val; 'a);
179
180 complex_op_impl!($Op, $op;
181 $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
182 $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result;
183 $action_val_ref; 'b);
184
185 complex_op_impl!($Op, $op;
186 $($Storage: $StoragesBound $(<$($BoundParam),*>)*),*;
187 $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result;
188 $action_ref_ref; 'a, 'b);
189
190
191 }
192);
193
194complex_op_impl_all!(
196 Mul, mul;
197 ;
198 self: UnitComplex<T>, rhs: Rotation<T, 2>, Output = UnitComplex<T>;
199 [val val] => &self * &rhs;
200 [ref val] => self * &rhs;
201 [val ref] => &self * rhs;
202 [ref ref] => self * UnitComplex::from_rotation_matrix(rhs);
203);
204
205complex_op_impl_all!(
207 Div, div;
208 ;
209 self: UnitComplex<T>, rhs: Rotation<T, 2>, Output = UnitComplex<T>;
210 [val val] => &self / &rhs;
211 [ref val] => self / &rhs;
212 [val ref] => &self / rhs;
213 [ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { self * UnitComplex::from_rotation_matrix(rhs).inverse() };
214);
215
216complex_op_impl_all!(
218 Mul, mul;
219 ;
220 self: Rotation<T, 2>, rhs: UnitComplex<T>, Output = UnitComplex<T>;
221 [val val] => &self * &rhs;
222 [ref val] => self * &rhs;
223 [val ref] => &self * rhs;
224 [ref ref] => UnitComplex::from_rotation_matrix(self) * rhs;
225);
226
227complex_op_impl_all!(
229 Div, div;
230 ;
231 self: Rotation<T, 2>, rhs: UnitComplex<T>, Output = UnitComplex<T>;
232 [val val] => &self / &rhs;
233 [ref val] => self / &rhs;
234 [val ref] => &self / rhs;
235 [ref ref] => #[allow(clippy::suspicious_arithmetic_impl)] { UnitComplex::from_rotation_matrix(self) * rhs.inverse() };
236);
237
238complex_op_impl_all!(
240 Mul, mul;
241 ;
242 self: UnitComplex<T>, rhs: Point2<T>, Output = Point2<T>;
243 [val val] => &self * &rhs;
244 [ref val] => self * &rhs;
245 [val ref] => &self * rhs;
246 [ref ref] => Point2::from(self * &rhs.coords);
247);
248
249complex_op_impl_all!(
251 Mul, mul;
252 S: Storage<T, Const<2>>;
253 self: UnitComplex<T>, rhs: Vector<T, Const<2>, S>, Output = Vector2<T>;
254 [val val] => &self * &rhs;
255 [ref val] => self * &rhs;
256 [val ref] => &self * rhs;
257 [ref ref] => {
258 let i = self.as_ref().im.clone();
259 let r = self.as_ref().re.clone();
260 Vector2::new(r.clone() * rhs[0].clone() - i.clone() * rhs[1].clone(), i * rhs[0].clone() + r * rhs[1].clone())
261 };
262);
263
264complex_op_impl_all!(
266 Mul, mul;
267 S: Storage<T, Const<2>>;
268 self: UnitComplex<T>, rhs: Unit<Vector<T, Const<2>, S>>, Output = Unit<Vector2<T>>;
269 [val val] => &self * &rhs;
270 [ref val] => self * &rhs;
271 [val ref] => &self * rhs;
272 [ref ref] => Unit::new_unchecked(self * rhs.as_ref());
273);
274
275complex_op_impl_all!(
277 Mul, mul;
278 ;
279 self: UnitComplex<T>, rhs: Isometry<T, UnitComplex<T>, 2>,
280 Output = Isometry<T, UnitComplex<T>, 2>;
281 [val val] => &self * &rhs;
282 [ref val] => self * &rhs;
283 [val ref] => &self * rhs;
284 [ref ref] => {
285 let shift = self * &rhs.translation.vector;
286 Isometry::from_parts(Translation::from(shift), self * &rhs.rotation)
287 };
288);
289
290complex_op_impl_all!(
292 Mul, mul;
293 ;
294 self: UnitComplex<T>, rhs: Similarity<T, UnitComplex<T>, 2>,
295 Output = Similarity<T, UnitComplex<T>, 2>;
296 [val val] => &self * &rhs;
297 [ref val] => self * &rhs;
298 [val ref] => &self * rhs;
299 [ref ref] => Similarity::from_isometry(self * &rhs.isometry, rhs.scaling());
300);
301
302complex_op_impl_all!(
304 Mul, mul;
305 ;
306 self: UnitComplex<T>, rhs: Translation<T, 2>,
307 Output = Isometry<T, UnitComplex<T>, 2>;
308 [val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self);
309 [ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), self.clone());
310 [val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self);
311 [ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), self.clone());
312);
313
314complex_op_impl_all!(
316 Mul, mul;
317 ;
318 self: Translation<T, 2>, right: UnitComplex<T>,
319 Output = Isometry<T, UnitComplex<T>, 2>;
320 [val val] => Isometry::from_parts(self, right);
321 [ref val] => Isometry::from_parts(self.clone(), right);
322 [val ref] => Isometry::from_parts(self, right.clone());
323 [ref ref] => Isometry::from_parts(self.clone(), right.clone());
324);
325
326impl<T: SimdRealField> MulAssign<UnitComplex<T>> for UnitComplex<T>
328where
329 T::Element: SimdRealField,
330{
331 #[inline]
332 fn mul_assign(&mut self, rhs: UnitComplex<T>) {
333 *self = self.clone() * rhs
334 }
335}
336
337impl<'b, T: SimdRealField> MulAssign<&'b UnitComplex<T>> for UnitComplex<T>
338where
339 T::Element: SimdRealField,
340{
341 #[inline]
342 fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
343 *self = self.clone() * rhs
344 }
345}
346
347impl<T: SimdRealField> DivAssign<UnitComplex<T>> for UnitComplex<T>
349where
350 T::Element: SimdRealField,
351{
352 #[inline]
353 fn div_assign(&mut self, rhs: UnitComplex<T>) {
354 *self = self.clone() / rhs
355 }
356}
357
358impl<'b, T: SimdRealField> DivAssign<&'b UnitComplex<T>> for UnitComplex<T>
359where
360 T::Element: SimdRealField,
361{
362 #[inline]
363 fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
364 *self = self.clone() / rhs
365 }
366}
367
368impl<T: SimdRealField> MulAssign<Rotation<T, 2>> for UnitComplex<T>
370where
371 T::Element: SimdRealField,
372{
373 #[inline]
374 fn mul_assign(&mut self, rhs: Rotation<T, 2>) {
375 *self = self.clone() * rhs
376 }
377}
378
379impl<'b, T: SimdRealField> MulAssign<&'b Rotation<T, 2>> for UnitComplex<T>
380where
381 T::Element: SimdRealField,
382{
383 #[inline]
384 fn mul_assign(&mut self, rhs: &'b Rotation<T, 2>) {
385 *self = self.clone() * rhs
386 }
387}
388
389impl<T: SimdRealField> DivAssign<Rotation<T, 2>> for UnitComplex<T>
391where
392 T::Element: SimdRealField,
393{
394 #[inline]
395 fn div_assign(&mut self, rhs: Rotation<T, 2>) {
396 *self = self.clone() / rhs
397 }
398}
399
400impl<'b, T: SimdRealField> DivAssign<&'b Rotation<T, 2>> for UnitComplex<T>
401where
402 T::Element: SimdRealField,
403{
404 #[inline]
405 fn div_assign(&mut self, rhs: &'b Rotation<T, 2>) {
406 *self = self.clone() / rhs
407 }
408}
409
410impl<T: SimdRealField> MulAssign<UnitComplex<T>> for Rotation<T, 2>
412where
413 T::Element: SimdRealField,
414{
415 #[inline]
416 fn mul_assign(&mut self, rhs: UnitComplex<T>) {
417 self.mul_assign(rhs.to_rotation_matrix())
418 }
419}
420
421impl<'b, T: SimdRealField> MulAssign<&'b UnitComplex<T>> for Rotation<T, 2>
422where
423 T::Element: SimdRealField,
424{
425 #[inline]
426 fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
427 self.mul_assign(rhs.clone().to_rotation_matrix())
428 }
429}
430
431impl<T: SimdRealField> DivAssign<UnitComplex<T>> for Rotation<T, 2>
433where
434 T::Element: SimdRealField,
435{
436 #[inline]
437 fn div_assign(&mut self, rhs: UnitComplex<T>) {
438 self.div_assign(rhs.to_rotation_matrix())
439 }
440}
441
442impl<'b, T: SimdRealField> DivAssign<&'b UnitComplex<T>> for Rotation<T, 2>
443where
444 T::Element: SimdRealField,
445{
446 #[inline]
447 fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
448 self.div_assign(rhs.clone().to_rotation_matrix())
449 }
450}