1
2use super::*;
3
4pub trait VersorMul<Rhs>: Sized {
15 type Output;
16 fn versor_mul(self, rhs: Rhs) -> Self::Output;
17}
18
19macro_rules! impl_versor_mul {
20
21 () => {};
22
23 (
24 @impl
25 $(&$a:lifetime)? $Ty1:ident<T1:$Alloc1:ident, N $(,$G1:ident)*> *
26 $(&$b:lifetime)? $Ty2:ident<T2:$Alloc2:ident, N $(,$G2:ident)*> ;
27 $($rest:tt)*
28 ) => {
29
30 impl<$($a,)? $($b,)? T1, T2, U, N:Dim $(, $G1:Dim)* $(, $G2:Dim)*>
31 VersorMul<$(&$b)? $Ty2<T2,N $(,$G2)?>> for $(&$a)? $Ty1<T1,N $(,$G1)?>
32 where
33 T1: $Alloc1<N $(,$G1)*> + AllRefMul<T2, AllOutput=U>,
34 T2: $Alloc2<N $(,$G2)*>,
35 U: $Alloc2<N $(,$G2)*> + for<'c> Mul<&'c T1, Output=U> + AddGroup,
36 {
37 type Output = $Ty2<U,N $(,$G2)?>;
38 fn versor_mul(self, rhs: $(&$b)? $Ty2<T2,N $(,$G2)?>) -> $Ty2<U,N $(,$G2)?> {
39 use crate::algebra::MultivectorSrc;
40 let shape = rhs.shape();
41 versor_mul_selected(self.odd(), self, rhs, shape)
42 }
43 }
44
45 impl_versor_mul!($($rest)*);
46
47 };
48
49 (
50 $Ty1:ident<T1:$Alloc1:ident, N $(,$G1:ident)*> *
51 $Ty2:ident<T2:$Alloc2:ident, N $(,$G2:ident)*> ;
52 $($rest:tt)*
53 ) => {
54 impl_versor_mul!(
55 @impl $Ty1<T1:$Alloc1, N $(,$G1)*> * $Ty2<T2:$Alloc2, N $(,$G2)*>;
56 @impl &'a $Ty1<T1:$Alloc1, N $(,$G1)*> * $Ty2<T2:$Alloc2, N $(,$G2)*>;
57 @impl $Ty1<T1:$Alloc1, N $(,$G1)*> * &'b $Ty2<T2:$Alloc2, N $(,$G2)*>;
58 @impl &'a $Ty1<T1:$Alloc1, N $(,$G1)*> * &'b $Ty2<T2:$Alloc2, N $(,$G2)*>;
59 $($rest)*
60 );
61 }
62
63}
64
65impl_versor_mul!(
66 UnitBlade<T1:AllocBlade,N,G1> * Blade<T2:AllocBlade,N,G2>;
67 UnitBlade<T1:AllocBlade,N,G1> * SimpleBlade<T2:AllocBlade,N,G2>;
68 UnitBlade<T1:AllocBlade,N,G1> * UnitBlade<T2:AllocBlade,N,G2>;
69 UnitBlade<T1:AllocBlade,N,G1> * Even<T2:AllocEven,N>;
70 UnitBlade<T1:AllocBlade,N,G1> * Rotor<T2:AllocEven,N>;
71 UnitBlade<T1:AllocBlade,N,G1> * Odd<T2:AllocOdd,N>;
72 UnitBlade<T1:AllocBlade,N,G1> * Reflector<T2:AllocOdd,N>;
73 UnitBlade<T1:AllocBlade,N,G1> * Multivector<T2:AllocMultivector,N>;
74
75 Rotor<T1:AllocEven,N> * Blade<T2:AllocBlade,N,G2>;
76 Rotor<T1:AllocEven,N> * SimpleBlade<T2:AllocBlade,N,G2>;
77 Rotor<T1:AllocEven,N> * UnitBlade<T2:AllocBlade,N,G2>;
78 Rotor<T1:AllocEven,N> * Even<T2:AllocEven,N>;
79 Rotor<T1:AllocEven,N> * Rotor<T2:AllocEven,N>;
80 Rotor<T1:AllocEven,N> * Odd<T2:AllocOdd,N>;
81 Rotor<T1:AllocEven,N> * Reflector<T2:AllocOdd,N>;
82 Rotor<T1:AllocEven,N> * Multivector<T2:AllocMultivector,N>;
83
84 Reflector<T1:AllocOdd,N> * Blade<T2:AllocBlade,N,G2>;
85 Reflector<T1:AllocOdd,N> * SimpleBlade<T2:AllocBlade,N,G2>;
86 Reflector<T1:AllocOdd,N> * UnitBlade<T2:AllocBlade,N,G2>;
87 Reflector<T1:AllocOdd,N> * Even<T2:AllocEven,N>;
88 Reflector<T1:AllocOdd,N> * Rotor<T2:AllocEven,N>;
89 Reflector<T1:AllocOdd,N> * Odd<T2:AllocOdd,N>;
90 Reflector<T1:AllocOdd,N> * Reflector<T2:AllocOdd,N>;
91 Reflector<T1:AllocOdd,N> * Multivector<T2:AllocMultivector,N>;
92);
93
94macro_rules! impl_non_unit_versor_mul {
95
96 () => {};
97
98 (
99 @impl
100 $(&$a:lifetime)? $Ty1:ident<T1:$Alloc1:ident, N $(,$G1:ident)*> *
101 $(&$b:lifetime)? $Ty2:ident<T2:$Alloc2:ident, N $(,$G2:ident)*>
102 $({$($where:tt)*})?;
103 $($rest:tt)*
104 ) => {
105
106 impl<$($a,)? $($b,)? T1, T2, U, N:Dim $(, $G1:Dim)* $(, $G2:Dim)*>
107 VersorMul<$(&$b)? $Ty2<T2,N $(,$G2)?>> for $(&$a)? $Ty1<T1,N $(,$G1)?>
108 where
109 T1: $Alloc1<N $(,$G1)*> + AllRefMul<T2, AllOutput=U> + AllRefMul<T1, AllOutput=U>,
110 T2: $Alloc2<N $(,$G2)*>,
111 U: $Alloc2<N $(,$G2)*> + for<'c> Mul<&'c T1, Output=U> + AddGroup,
112 U: for<'c> Div<&'c U, Output=U>,
113 $($($where)*)?
114 {
115 type Output = $Ty2<U,N $(,$G2)?>;
116 fn versor_mul(self, rhs: $(&$b)? $Ty2<T2,N $(,$G2)?>) -> $Ty2<U,N $(,$G2)?> {
117 use crate::algebra::MultivectorSrc;
118 let shape = rhs.shape();
119 let norm_sqrd = self.norm_sqrd();
120
121 let mut res: Self::Output = versor_mul_selected(self.odd(), self, rhs, shape);
122 res = res.inv_scale(&norm_sqrd);
123 res
124 }
125 }
126
127 impl_non_unit_versor_mul!($($rest)*);
128
129 };
130
131 (
132 $Ty1:ident<T1:$Alloc1:ident, N $(,$G1:ident)*> *
133 $Ty2:ident<T2:$Alloc2:ident, N $(,$G2:ident)*>
134 $({$($where:tt)*})?;
135 $($rest:tt)*
136 ) => {
137 impl_non_unit_versor_mul!(
138 @impl $Ty1<T1:$Alloc1, N $(,$G1)*> * $Ty2<T2:$Alloc2, N $(,$G2)*> $({$($where)*})?;
139 @impl &'a $Ty1<T1:$Alloc1, N $(,$G1)*> * $Ty2<T2:$Alloc2, N $(,$G2)*> $({$($where)*})?;
140 @impl $Ty1<T1:$Alloc1, N $(,$G1)*> * &'b $Ty2<T2:$Alloc2, N $(,$G2)*> $({$($where)*})?;
141 @impl &'a $Ty1<T1:$Alloc1, N $(,$G1)*> * &'b $Ty2<T2:$Alloc2, N $(,$G2)*> $({$($where)*})?;
142 $($rest)*
143 );
144 }
145
146}
147
148impl_non_unit_versor_mul!(
149 Blade<T1:AllocSimpleBlade,N,G1> * Blade<T2:AllocBlade,N,G2>;
150 Blade<T1:AllocSimpleBlade,N,G1> * SimpleBlade<T2:AllocBlade,N,G2>;
151 Blade<T1:AllocSimpleBlade,N,G1> * Even<T2:AllocEven,N>;
152 Blade<T1:AllocSimpleBlade,N,G1> * Odd<T2:AllocOdd,N>;
153 Blade<T1:AllocSimpleBlade,N,G1> * Multivector<T2:AllocMultivector,N>;
154
155 SimpleBlade<T1:AllocBlade,N,G1> * Blade<T2:AllocBlade,N,G2>;
156 SimpleBlade<T1:AllocBlade,N,G1> * SimpleBlade<T2:AllocBlade,N,G2>;
157 SimpleBlade<T1:AllocBlade,N,G1> * Even<T2:AllocEven,N>;
158 SimpleBlade<T1:AllocBlade,N,G1> * Odd<T2:AllocOdd,N>;
159 SimpleBlade<T1:AllocBlade,N,G1> * Multivector<T2:AllocMultivector,N>;
160
161 Even<T1:AllocEven,N> * Blade<T2:AllocBlade,N,G2> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
162 Even<T1:AllocEven,N> * SimpleBlade<T2:AllocBlade,N,G2> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
163 Even<T1:AllocEven,N> * Even<T2:AllocEven,N> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
164 Even<T1:AllocEven,N> * Odd<T2:AllocOdd,N> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
165 Even<T1:AllocEven,N> * Multivector<T2:AllocMultivector,N> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
166
167 Odd<T1:AllocOdd,N> * Blade<T2:AllocBlade,N,G2> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
168 Odd<T1:AllocOdd,N> * SimpleBlade<T2:AllocBlade,N,G2> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
169 Odd<T1:AllocOdd,N> * Even<T2:AllocEven,N> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
170 Odd<T1:AllocOdd,N> * Odd<T2:AllocOdd,N> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
171 Odd<T1:AllocOdd,N> * Multivector<T2:AllocMultivector,N> {N:ToTypenum, AsTypenum<N>: IsLessOrEqual<U3,Output=True>};
172);
173
174macro_rules! versor_versor_mul {
175
176 ($Ty:ident<T:$Alloc:ident, N $(,$G:ident)*>; $($a:lifetime)?; $($b:lifetime)?) => {
177
178 impl<$($a,)? $($b,)? T1, T2, U, N:Dim $(, $G:Dim)*>
179 VersorMul<$(&$b)? $Ty<T2,N $(,$G)?>> for $(&$a)? Versor<T1,N>
180 where
181 T1: AllocVersor<N> + AllRefMul<T2, AllOutput=U>,
182 T2: $Alloc<N $(,$G)*>,
183 U: $Alloc<N $(,$G)*> + for<'c> Mul<&'c T1, Output=U> + AddGroup,
184 {
185 type Output = $Ty<U,N $(,$G)?>;
186 fn versor_mul(self, rhs: $(&$b)? $Ty<T2,N $(,$G)*>) -> $Ty<U,N $(,$G)*> {
187 match self {
188 Versor::Even(r) => r.versor_mul(rhs),
189 Versor::Odd(r) => r.versor_mul(rhs),
190 }
191 }
192 }
193
194 };
195
196 () => {};
197 ($Ty:ident<T:$Alloc:ident, N $(,$G:ident)*>; $($rest:tt)*) => {
198 versor_versor_mul!($Ty<T:$Alloc, N $(,$G)*>; ; );
199 versor_versor_mul!($Ty<T:$Alloc, N $(,$G)*>; 'a; );
200 versor_versor_mul!($Ty<T:$Alloc, N $(,$G)*>; ; 'b);
201 versor_versor_mul!($Ty<T:$Alloc, N $(,$G)*>; 'a; 'b);
202 versor_versor_mul!($($rest)*);
203 };
204
205}
206
207versor_versor_mul!(
208 Blade<T:AllocBlade,N,G>;
209 SimpleBlade<T:AllocBlade,N,G>;
210 UnitBlade<T:AllocBlade,N,G>;
211 Even<T:AllocEven,N>;
212 Rotor<T:AllocEven,N>;
213 Odd<T:AllocOdd,N>;
214 Reflector<T:AllocOdd,N>;
215 Multivector<T:AllocMultivector,N>;
216);
217
218macro_rules! versor_mul_versor {
219
220 ($Ty:ident<T:$Alloc:ident, N $(,$G:ident)*>; $($a:lifetime)?; $($b:lifetime)?) => {
221
222 impl<$($a,)? $($b,)? T1, T2, U, N:Dim $(, $G:Dim)*>
223 VersorMul<$(&$b)? Versor<T2,N>> for $(&$a)? $Ty<T1,N $(,$G)?>
224 where
225 T1: $Alloc<N $(,$G)*> + AllRefMul<T2, AllOutput=U>,
226 T2: AllocVersor<N>,
227 U: AllocVersor<N> + for<'c> Mul<&'c T1, Output=U> + AddGroup,
228 {
229 type Output = Versor<U,N>;
230 fn versor_mul(self, rhs: $(&$b)? Versor<T2,N>) -> Versor<U,N> {
231 match rhs {
232 Versor::Even(r) => Versor::Even(self.versor_mul(r)),
233 Versor::Odd(r) => Versor::Odd(self.versor_mul(r)),
234 }
235 }
236 }
237
238 };
239
240 () => {};
241 ($Ty:ident<T:$Alloc:ident, N $(,$G:ident)*>; $($rest:tt)*) => {
242 versor_mul_versor!($Ty<T:$Alloc, N $(,$G)*>; ; );
243 versor_mul_versor!($Ty<T:$Alloc, N $(,$G)*>; 'a; );
244 versor_mul_versor!($Ty<T:$Alloc, N $(,$G)*>; ; 'b);
245 versor_mul_versor!($Ty<T:$Alloc, N $(,$G)*>; 'a; 'b);
246 versor_mul_versor!($($rest)*);
247 };
248
249}
250
251versor_mul_versor!(
252 UnitBlade<T:AllocBlade,N,G>;
253 Rotor<T:AllocEven,N>;
254 Reflector<T:AllocOdd,N>;
255 Versor<T:AllocVersor,N>;
256);
257
258impl<T:AllocBlade<N, U1>, N:Dim> VecN<T,N> {
259 pub fn reflect<'a,M>(&'a self, m:M) -> <&'a Self as VersorMul<M>>::Output where &'a Self: VersorMul<M> {
261 self.versor_mul(m)
262 }
263}
264
265impl<T:AllocBlade<N, U1>, N:Dim> SimpleVecN<T,N> {
266 pub fn reflect<'a,M>(&'a self, m:M) -> <&'a Self as VersorMul<M>>::Output where &'a Self: VersorMul<M> {
268 self.versor_mul(m)
269 }
270}
271
272impl<T:AllocBlade<N, U1>, N:Dim> UnitVecN<T,N> {
273 pub fn reflect<'a,M>(&'a self, m:M) -> <&'a Self as VersorMul<M>>::Output where &'a Self: VersorMul<M> {
275 self.versor_mul(m)
276 }
277}
278
279impl<T:AllocEven<N>, N:Dim> Rotor<T,N> {
280
281 pub fn rot<'a,M>(&'a self, m:M) -> <&'a Self as VersorMul<M>>::Output where &'a Self: VersorMul<M> {
283 self.versor_mul(m)
284 }
285
286}
287
288impl<T:AllocOdd<N>, N:Dim> Reflector<T,N> {
289
290 pub fn apply<'a,M>(&'a self, m:M) -> <&'a Self as VersorMul<M>>::Output where &'a Self: VersorMul<M> {
292 self.versor_mul(m)
293 }
294
295}
296
297impl<T:AllocVersor<N>, N:Dim> Versor<T,N> {
298
299 pub fn apply<'a,M>(&'a self, m:M) -> <&'a Self as VersorMul<M>>::Output where &'a Self: VersorMul<M> {
301 self.versor_mul(m)
302 }
303
304}
305
306impl<T:AllocEven<N>+RefRealField, N:Dim> Rotor<T,N> {
311
312 pub fn from_scaled_plane(plane: SimpleBiVecN<T,N>) -> Self where
314 T: AllocBlade<N,U2>
315 {
316 let two = T::one() + T::one();
317 (plane/two).exp()
318 }
319
320 pub fn from_plane_angle(plane: UnitBiVecN<T,N>, angle: T) -> Self where
322 T: AllocBlade<N,U2>
323 {
324
325 let two = T::one() + T::one();
327 let (s, c) = (angle/two).sin_cos();
328
329 let mut r = Even::from(plane.into_inner() * s);
331 r[0] = c;
332
333 r.into_rotor_unchecked()
335
336 }
337
338 pub fn log(self) -> BiVecN<T,N> where T: AllocBlade<N,U2> {
356 let (n, g) = (self.dim_generic(), <U2 as na::dimension::DimName>::name());
363 match n.value() {
364
365 0 | 1 => BiVecN::zeroed_generic(n, g),
367
368 2 => {
370 let angle = self.cast_dim_unchecked::<U2>().get_half_angle();
371 BiVec2::new(angle).cast_dim_generic(n)
372 },
373
374 3 => self.cast_dim_unchecked::<U3>().get_half_scaled_plane().into_inner().cast_dim_generic(n),
376
377 4 => {
379 let (plane1, plane2) = self.cast_dim_unchecked::<U4>().get_half_scaled_planes();
380 (plane1.into_inner() + plane2.into_inner()).cast_dim_generic(n)
381 }
382
383 _ => unimplemented!("error: log() currently only implemented up to 4 dimensions")
388
389
390 }
391
392 }
393
394 pub fn powf(self, t:T) -> Self where T:AllocBlade<N,U2> {
404 (self.log() * t).exp_rotor()
405 }
406
407 pub fn slerp(self, other: Self, t:T) -> Self where T:AllocBlade<N,U2> {
411 (other / &self).powf(t) * self
414 }
415
416}
417
418impl<T:AllocEven<U2>+RefRealField> Rotor2<T> {
419
420 pub fn from_angle(angle:T) -> Self
422 {
423 let two = T::one() + T::one();
424 let (s, c) = (angle/two).sin_cos();
425 Even2::new(c, s).into_rotor_unchecked()
426 }
427
428 fn get_half_angle(&self) -> T where T:RefRealField {
430 self.im.clone().atan2(self.re.clone())
431 }
432
433 pub fn get_angle(&self) -> T where T:RefRealField {
435 self.get_half_angle() * (T::one() + T::one())
436 }
437
438}
439
440impl<T:AllocEven<U2>+RefRealField> Rotor3<T> {
441
442 pub fn from_scaled_axis(scaled_axis: Vec3<T>) -> Self
444 {
445 Self::from_scaled_plane(scaled_axis.undual().into())
447 }
448
449 pub fn from_axis_angle(axis:UnitVec3<T>, angle:T) -> Self
451 {
452 Self::from_plane_angle(axis.undual(), angle)
453 }
454
455 fn get_half_plane_angle(self) -> Option<(UnitBiVec3<T>, T)> {
456 let [w, x, y, z] = self.into_inner().data;
457
458 let (c, s) = (w, (x.ref_mul(&x)+y.ref_mul(&y)+z.ref_mul(&z)).sqrt());
459 let angle = s.clone().atan2(c);
460
461 if angle.is_zero() {
462 None
463 } else {
464 Some((
465 (BiVec3::new(x, y, z)/&s).into_unit_unchecked(),
466 angle
467 ))
468 }
469 }
470
471 fn get_half_scaled_plane(self) -> SimpleBiVec3<T> {
472 self.get_half_plane_angle().map_or_else(|| Zero::zero(), |(d, a)| SimpleBiVec3::from(d) * a)
473 }
474
475 pub fn get_plane_angle(self) -> Option<(UnitBiVec3<T>, T)> {
477 self.get_half_plane_angle().map(|(b,a)| (b, a*(T::one()+T::one())))
478 }
479
480 pub fn get_scaled_plane(self) -> SimpleBiVec3<T> {
482 self.get_plane_angle().map_or_else(|| Zero::zero(), |(d, a)| SimpleBiVec3::from(d) * a)
483 }
484
485 pub fn get_axis_angle(self) -> Option<(UnitVec3<T>, T)> {
487 self.get_half_plane_angle().map(|(b,a)| (b.dual(), a*(T::one()+T::one())))
488 }
489
490 pub fn get_scaled_axis(self) -> Vec3<T> {
492 self.get_plane_angle().map_or_else(|| Zero::zero(), |(d, a)| BiVec3::from(d).dual() * a)
493 }
494
495}
496
497impl<T:AllocEven<U2>+RefRealField> Rotor4<T> {
498
499 fn get_half_plane_angles(self) -> (Option<(UnitBiVec4<T>, T)>, Option<(UnitBiVec4<T>, T)>) {
500
501 let two = T::one() + T::one();
507 let [s, b1, b2, b3, b4, b5, b6, q] = self.into_inner().data;
508
509 if q.is_zero() {
511
512 let b = BiVec4::new(b1, b2, b3, b4, b5, b6);
513
514 let (s, c) = (b.norm(), s);
516 let angle = s.clone().atan2(c);
517
518 if angle.is_zero() {
521 return (None, None);
522 } else {
523 return (Some(((b/s).into_unit_unchecked(), angle)), None);
524 }
525
526 }
527
528 let cos_minus = s.ref_add(&q);
530 let cos_plus = s - q;
531
532 let b = BiVec4::new(b1, b2, b3, b4, b5, b6);
538 let b_dual = b.clone().undual();
539
540 let b_plus = &b - &b_dual;
546 let b_minus = b + b_dual;
547
548 let sin_plus = (b_plus.norm_sqrd()/&two).sqrt();
550 let sin_minus = (b_minus.norm_sqrd()/&two).sqrt();
551
552 let b_plus = if sin_plus.is_zero() { None } else { Some(b_plus/&sin_plus) };
556 let b_minus = if sin_minus.is_zero() { None } else { Some(b_minus/&sin_minus) };
557
558 let angle_plus = sin_plus.atan2(cos_plus);
563 let angle_minus = sin_minus.atan2(cos_minus);
564
565 let angle1 = (angle_plus.ref_add(&angle_minus)) / &two;
569 let angle2 = (angle_plus - angle_minus) / &two;
570 match (b_plus, b_minus) {
573
574 (None, None) => (None, None),
577
578 (Some(b), None) => {
581
582 let(dir1, dir2) = b.split_isoclinic();
594 (
596 Some((dir1.into_unit_unchecked(), angle1)),
597 Some((dir2.into_unit_unchecked(), angle2)),
598 )
599
600 },
601 (None, Some(b)) => {
602 let(dir1, dir2) = b.split_isoclinic();
604 (
606 Some((dir1.into_unit_unchecked(), angle1)),
607 Some((-dir2.into_unit_unchecked(), angle2)),
608 )
609
610 },
611
612 (Some(b_plus), Some(b_minus)) => {
613
614 let dir1 = (&b_plus + &b_minus) / &two;
616 let dir2 = (b_plus - b_minus) / two;
617
618 (
621 Some((dir1.into_unit_unchecked(), angle1)),
622 Some((dir2.into_unit_unchecked(), angle2)),
623 )
624
625 }
626
627
628 }
629
630 }
631
632 fn get_half_scaled_planes(self) -> (SimpleBiVec4<T>, SimpleBiVec4<T>) {
633 let (x1, x2) = self.get_half_plane_angles();
634 (
635 x1.map_or_else(|| SimpleBiVec4::zeroed(), |(d, a)| d.into_simple() * a),
636 x2.map_or_else(|| SimpleBiVec4::zeroed(), |(d, a)| d.into_simple() * a),
637 )
638 }
639
640 pub fn get_plane_angles(self) -> (Option<(UnitBiVec4<T>, T)>, Option<(UnitBiVec4<T>, T)>) {
642 let (x1, x2) = self.get_half_plane_angles();
643 (
644 x1.map(|(d,a)| (d, a*(T::one()+T::one()))),
645 x2.map(|(d,a)| (d, a*(T::one()+T::one()))),
646 )
647 }
648
649 pub fn get_scaled_planes(self) -> (SimpleBiVec4<T>, SimpleBiVec4<T>) {
651 let (x1, x2) = self.get_plane_angles();
652 (
653 x1.map_or_else(|| SimpleBiVec4::zeroed(), |(d, a)| d.into_simple() * a),
654 x2.map_or_else(|| SimpleBiVec4::zeroed(), |(d, a)| d.into_simple() * a),
655 )
656 }
657
658}
659
660impl<T:AllocBlade<N,U2>+RefRealField, N:Dim> SimpleBiVecN<T, N> {
661
662 pub fn exp(self) -> Rotor<T,N> where T:AllocEven<N> {
672 self.into_inner().exp_even_simple().into_rotor_unchecked()
673 }
674}
675
676impl<T:AllocEven<N>+AllocBlade<N,U1>+RefRealField, N:Dim> Rotor<T,N> {
681
682 #[inline(always)]
683 pub fn rot_between_unit(v1:UnitVecN<T,N>, v2: UnitVecN<T,N>) -> Self where
684 T: AllocBlade<N,U1>
685 { v1.rot_to(v2) }
686
687 #[inline(always)]
688 pub fn rot_between_simple(v1:SimpleVecN<T,N>, v2: SimpleVecN<T,N>) -> Self where
689 T: AllocBlade<N,U1>
690 { v1.rot_to(v2) }
691
692 #[inline(always)]
693 pub fn rot_between(v1:VecN<T,N>, v2: VecN<T,N>) -> Self where
694 T: AllocBlade<N,U1>
695 { v1.rot_to(v2) }
696
697}
698
699impl<T:AllocBlade<N,U1>+RefRealField, N:Dim> UnitVecN<T, N> {
700 pub fn rot_to(self, v2: UnitVecN<T,N>) -> Rotor<T,N> where T:AllocEven<N> {
701
702 let two = T::one() + T::one();
707 let n = self.dim_generic();
708 let v2 = (self.as_inner() + v2.into_inner()) / &two;
709 let v1 = self;
710
711 match v2.into_simple_vec().try_normalize() {
713 Some(v2) => {
714 v2.into_blade().mul_even(v1.into_blade()).into_rotor_unchecked()
718 },
719 None => {
720 for i in 0..n.value() {
729
730 let ei = Blade::basis_generic(n, v1.grade_generic(), i);
733 let mut plane = v1.as_inner().mul_even(ei);
734 plane[0] = T::zero();
735
736 if let Some(plane) = plane.try_normalize() {
737 return plane.into_rotor_unchecked();
738 }
739 }
740
741 panic!("Cannot find rotation between vectors in 1D")
743 },
744 }
745
746 }
747}
748
749impl<T:AllocBlade<N,U1>+RefRealField, N:Dim> SimpleVecN<T, N> {
750 #[inline]
751 pub fn rot_to(self, v2: SimpleVecN<T,N>) -> Rotor<T,N> where T:AllocEven<N> {
752 let n = self.dim_generic();
753 match self.try_normalize() {
754 None => Rotor::from_inner_unchecked(Even::one_generic(n)),
755 Some(v1) => match v2.try_normalize() {
756 None => Rotor::from_inner_unchecked(Even::one_generic(n)),
757 Some(v2) => v1.rot_to(v2)
758 }
759 }
760 }
761}
762
763impl<T:AllocBlade<N,U1>+RefRealField, N:Dim> VecN<T, N> {
764 #[inline(always)]
765 pub fn rot_to(self, v2: VecN<T,N>) -> Rotor<T,N> where T:AllocEven<N> {
766 self.into_simple_unchecked().rot_to(v2.into_simple_unchecked())
767 }
768}
769
770impl<T:AllocOdd<N>+Zero, N:Dim> Reflector<T,N> {
775
776 pub fn reflect_normal(n: VecN<T,N>) -> Self where T:AllocBlade<N,U1>+RefRealField {
785 n.normalize().into_odd().into_reflector_unchecked()
786 }
787
788 pub fn reflect_unit_normal(n: UnitVecN<T,N>) -> Self where T:AllocBlade<N,U1> {
797 n.into_inner().into_odd().into_reflector_unchecked()
798 }
799
800 pub fn reflect_hyperplane<G:Dim>(plane: Blade<T,N,G>) -> Self where
809 T: AllocBlade<N,G> + AllocBlade<N,U1> + RefRealField,
810 N: DimSub<G,Output=U1>
811 {
812 Self::reflect_normal(plane.dual())
813 }
814
815 pub fn reflect_unit_hyperplane<G:Dim>(plane: UnitBlade<T,N,G>) -> Self where
824 T: AllocBlade<N,G> + AllocBlade<N,U1> + ClosedNeg,
825 N: DimSub<G,Output=U1>
826 {
827 Self::reflect_unit_normal(plane.dual())
828 }
829
830}
831
832
833#[cfg(test)]
834mod tests {
835
836 use super::*;
837 use approx::*;
838 use rayon::prelude::*;
839
840 use crate::SHORT_TEST_DIM;
841
842 #[test]
843 fn circle_fractions_2d() {
844
845 for n in 1..=360 {
846
847 let rot32 = Rotor2::from_angle(2.0*std::f32::consts::PI / n as f32);
848 let rot64 = Rotor2::from_angle(2.0*std::f64::consts::PI / n as f64);
849
850 let mut final_rot32 = Rotor2::<f32>::one();
851 let mut final_rot64 = Rotor2::<f64>::one();
852 for _ in 0..n {
853 final_rot32 *= rot32;
854 final_rot64 *= rot64;
855 }
856
857 assert_abs_diff_eq!(-Rotor2::<f32>::one(), final_rot32, epsilon=0.000015);
858 assert_abs_diff_eq!(-Rotor2::<f64>::one(), final_rot64, epsilon=0.0000000000002);
859
860 }
861
862
863 }
864
865 fn double_rot_iter(n:usize) -> impl ParallelIterator<Item=(usize,usize,f64,f64)> {
866 (0..binom(n,2)).into_par_iter()
867 .flat_map(|i| (0..=i).into_par_iter().map(move |j| (i,j)))
868 .flat_map(|(i,j)| (-45i32..45).into_par_iter().map(move |a| (i,j,a)))
869 .flat_map(|(i,j,a)| (-45i32..45).into_par_iter().map(move |b| (i,j,a,b)))
870 .map(|(i,j,a,b)| (i,j, (8.0*a as f64).to_radians(), (8.0*b as f64).to_radians()))
871 }
872
873 #[test]
882 fn double_rot_log() {
883
884
885 for n in 0..=4 {
886
887 let iter = double_rot_iter(n);
888
889 iter.for_each(
890 |(i,j,a,b)| {
891
892 let b1 = BiVecD::basis(n, i) * a;
897 let b2 = BiVecD::basis(n, j) * b;
898 let b = b1 + b2;
899
900 let rot = b.clone().exp_rotor();
901 let log = rot.clone().log();
902
903 assert_abs_diff_eq!(rot, log.exp_rotor(), epsilon=1024.0*f64::EPSILON);
906
907
908 }
909 )
910
911
912 }
913
914 }
915
916 #[test]
917 fn rot_to() {
918
919 for n in 2usize..=4 {
920
921 let s:usize = 3;
922
923 for k in 0..s.pow(2*n as u32) {
924
925 let mut k = k;
926
927 let mut v1 = VecD::zeroed(n);
928 for i in 0..n {
929 let (q, r) = (k/s, k%s);
930 v1[i] = r as f64 - (s-1) as f64/2.0;
931 k = q;
932 }
933
934 let mut v2 = VecD::zeroed(n);
935 for i in 0..n {
936 let (q, r) = (k/s, k%s);
937 v2[i] = r as f64 - (s-1) as f64/2.0;
938 k = q;
939 }
940
941 let rot1 = v1.clone().rot_to(v2.clone());
942 let rot2 = v2.clone().rot_to(v1.clone());
943
944 if v1.norm_sqrd() == 0.0 || v2.norm_sqrd() == 0.0 {
945 assert_relative_eq!(rot1, Rotor::one_dyn(n));
946 assert_relative_eq!(rot2, Rotor::one_dyn(n));
947 } else {
948 assert_relative_eq!(v2.clone().normalize(), rot1.rot(&v1).normalize(), epsilon=1e-10);
949 assert_relative_eq!(v1.clone().normalize(), rot2.rot(&v2).normalize(), epsilon=1e-10);
950 }
951
952 }
953
954
955 }
956
957
958
959 }
960
961 #[test]
962 fn double_rot_sqrt() {
963
964 for n in 0..=4 {
965
966 let iter = double_rot_iter(n);
967
968 iter.for_each(
969 |(i,j,a,b)| {
970
971 let b1 = BiVecD::basis(n, i) * a;
972 let b2 = BiVecD::basis(n, j) * b;
973 let b = &b1 + &b2;
974
975 let rot = b.clone().exp_rotor();
976 let sqrt1 = (b/2.0).exp_rotor();
977 let sqrt2 = rot.clone().powf(0.5);
978
979 let eps = 1024.0*f64::EPSILON;
980
981 assert_relative_eq!(&sqrt2*&sqrt2, rot, epsilon=eps);
985 assert_relative_eq!(&sqrt1*&sqrt1, rot, epsilon=eps);
986
987 }
988 )
989
990 }
991
992
993 }
994
995
996 #[test]
997 fn basis_reflection() {
998
999 for n in 0..=SHORT_TEST_DIM {
1000
1001 for i in 0..n {
1002
1003 let normal = VecD::<f64>::basis(n, i)*2.0;
1005 let unit_normal = normal.clone().into_simple().normalize();
1006 let r = Reflector::reflect_normal(normal.clone());
1007
1008 let v1 = VecD::from_element(n, 1.0);
1010 let v2 = VecD::from_index_fn(n, |j| if j==i {-1.0} else {1.0});
1011
1012 assert_eq!(r.apply(&v1), v2);
1013 assert_eq!(unit_normal.reflect(&v1), v2);
1014
1015 }
1016
1017 }
1018
1019 dim_name_test_loop!(
1020 {U1 U2 U3 U4 U5 U6}
1021 |$N| for i in 0..$N::dim() {
1022
1023 let normal = VecN::<f64, $N>::basis(i) * 2.0;
1024 let unit_normal = normal.into_simple().normalize();
1025 let plane = if $N::dim()<=2 { normal.undual() } else { PsuedoVecN::<f64, $N>::basis(i) };
1026
1027 let r1 = Reflector::reflect_normal(normal);
1028 let r2 = Reflector::reflect_hyperplane(plane);
1029
1030 let v1 = VecN::<_,$N>::from_element(1.0);
1031 let v2 = VecN::<_,$N>::from_index_fn(|j| if j==i {-1.0} else {1.0});
1032
1033 assert_eq!(r1, r2);
1034 assert_eq!(r1.apply(&v1), v2);
1035 assert_eq!(r2.apply(&v1), v2);
1036 assert_eq!(normal.reflect(&v1), v2);
1037 assert_eq!(unit_normal.reflect(&v1), v2);
1038
1039 }
1040 );
1041
1042 }
1043
1044}