1use crate::*;
2
3use std::{
4 fmt::{self, Display, Formatter},
5 ops::{Div, DivAssign, Mul, MulAssign},
6 str::FromStr,
7};
8
9use derive_more::{Add, AddAssign, Neg, Sub, SubAssign};
10use inner_space::{DotProduct, InnerSpace, VectorSpace};
11use scalars::{Inv, One, Real, Zero};
12use vector_space::Transform;
13
14#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
16pub struct Rotor<T> {
17 pub scalar: T,
19 pub xy: T,
21 pub xz: T,
23 pub yz: T,
25}
26
27impl<T> Rotor<T> {
28 pub fn new(scalar: T, xy: T, xz: T, yz: T) -> Self {
30 Self { scalar, xy, xz, yz }
31 }
32}
33
34impl<T: Real> Rotor<T> {
35 pub fn rotate(self, vector: Vector<T>) -> Vector<T> {
37 self.normalize().rotate_normalized(vector)
38 }
39
40 pub fn rotate_normalized(self, v: Vector<T>) -> Vector<T> {
43 let s = self.scalar;
44 let a = self.xy;
45 let b = self.xz;
46 let c = self.yz;
47
48 let two = T::one() + T::one();
49
50 let s2 = s * s;
51 let a2 = a * a;
52 let b2 = b * b;
53 let c2 = c * c;
54
55 Vector {
56 x: (s2 + c2 - a2 - b2) * v.x
57 + two * (s * a - b * c) * v.y
58 + two * (s * b + a * c) * v.z,
59 y: -two * (s * a + b * c) * v.x
60 + (s2 + b2 - a2 - c2) * v.y
61 + two * (s * c - a * b) * v.z,
62 z: two * (a * c - s * b) * v.x - two * (a * b + s * c) * v.y
63 + (s2 + a2 - b2 - c2) * v.z,
64 }
65 }
66
67 pub fn rotate_bivector(self, bivector: Bivector<T>) -> Bivector<T> {
69 self.normalize().rotate_bivector_normalized(bivector)
70 }
71
72 pub fn rotate_bivector_normalized(self, b: Bivector<T>) -> Bivector<T> {
75 let s = self.scalar;
76 let a = self.xy;
77 let br = self.xz;
78 let c = self.yz;
79
80 let two = T::one() + T::one();
81
82 let s2 = s * s;
83 let a2 = a * a;
84 let b2 = br * br;
85 let c2 = c * c;
86
87 Bivector {
88 xy: two * (a * c - s * br) * b.yz
89 + two * (a * br + s * c) * b.xz
90 + (s2 + a2 - b2 - c2) * b.xy,
91 xz: two * (s * a + br * c) * b.yz + (s2 + b2 - a2 - c2) * b.xz
92 - two * (s * c - a * br) * b.xy,
93 yz: (s2 + c2 - a2 - b2) * b.yz - two * (s * a - br * c) * b.xz
94 + two * (s * br + a * c) * b.xy,
95 }
96 }
97
98 pub fn reverse(self) -> Self {
100 Self {
101 scalar: self.scalar,
102 xy: -self.xy,
103 xz: -self.xz,
104 yz: -self.yz,
105 }
106 }
107}
108
109impl<T: Zero> Rotor<T> {
110 pub fn scalar(scalar: T) -> Self {
112 Self {
113 scalar,
114 xy: T::zero(),
115 xz: T::zero(),
116 yz: T::zero(),
117 }
118 }
119
120 pub fn xy(xy: T) -> Self {
122 Self {
123 scalar: T::zero(),
124 xy,
125 xz: T::zero(),
126 yz: T::zero(),
127 }
128 }
129
130 pub fn xz(xz: T) -> Self {
132 Self {
133 scalar: T::zero(),
134 xy: T::zero(),
135 xz,
136 yz: T::zero(),
137 }
138 }
139
140 pub fn yz(yz: T) -> Self {
142 Self {
143 scalar: T::zero(),
144 xy: T::zero(),
145 xz: T::zero(),
146 yz,
147 }
148 }
149}
150
151impl<T: Zero> Zero for Rotor<T> {
152 fn zero() -> Self {
153 Self {
154 scalar: T::zero(),
155 xy: T::zero(),
156 xz: T::zero(),
157 yz: T::zero(),
158 }
159 }
160
161 fn is_zero(&self) -> bool {
162 self.scalar.is_zero() && self.xy.is_zero() && self.xz.is_zero() && self.yz.is_zero()
163 }
164}
165
166impl<T: Real> One for Rotor<T> {
167 fn one() -> Self {
168 Self {
169 scalar: T::one(),
170 xy: T::zero(),
171 xz: T::zero(),
172 yz: T::zero(),
173 }
174 }
175
176 fn is_one(&self) -> bool {
177 self.scalar.is_one() && self.xy.is_zero() && self.xz.is_zero() && self.yz.is_zero()
178 }
179}
180
181impl<T: Real> Inv for Rotor<T> {
182 type Output = Self;
183
184 fn inv(self) -> Self {
185 self.reverse() / self.magnitude2()
186 }
187}
188
189impl<T: Real> From<T> for Rotor<T> {
190 fn from(scalar: T) -> Self {
191 Self::scalar(scalar)
192 }
193}
194
195impl<T> Mul<T> for Rotor<T>
196where
197 T: Mul<Output = T> + Copy,
198{
199 type Output = Self;
200 fn mul(self, other: T) -> Self {
201 Self {
202 scalar: self.scalar * other,
203 xy: self.xy * other,
204 xz: self.xz * other,
205 yz: self.yz * other,
206 }
207 }
208}
209
210impl<T> MulAssign<T> for Rotor<T>
211where
212 T: MulAssign + Copy,
213{
214 fn mul_assign(&mut self, other: T) {
215 self.scalar *= other;
216 self.xy *= other;
217 self.xz *= other;
218 self.yz *= other;
219 }
220}
221
222impl<T> Div<T> for Rotor<T>
223where
224 T: Div<Output = T> + Copy,
225{
226 type Output = Self;
227 fn div(self, other: T) -> Self {
228 Self {
229 scalar: self.scalar / other,
230 xy: self.xy / other,
231 xz: self.xz / other,
232 yz: self.yz / other,
233 }
234 }
235}
236
237impl<T> DivAssign<T> for Rotor<T>
238where
239 T: DivAssign + Copy,
240{
241 fn div_assign(&mut self, other: T) {
242 self.scalar /= other;
243 self.xy /= other;
244 self.xz /= other;
245 self.yz /= other;
246 }
247}
248
249impl<T: Real> VectorSpace for Rotor<T> {
250 type Scalar = T;
251}
252
253impl<T: Real> DotProduct for Rotor<T> {
254 type Output = Self::Scalar;
255
256 fn dot(&self, other: &Self) -> T {
257 self.scalar * other.scalar - self.xy * other.xy - self.xz * other.xz - self.yz * other.yz
258 }
259
260 fn scalar(&self, other: &Self) -> T {
261 self.scalar * other.scalar + self.xy * other.xy + self.xz * other.xz + self.yz * other.yz
262 }
263}
264
265impl<T: Real> DotProduct<Vector<T>> for Rotor<T> {
266 type Output = Vector<T>;
267 #[inline]
268 fn dot(&self, other: &Vector<T>) -> Vector<T> {
269 other.dot(self)
270 }
271}
272
273impl<T: Real> DotProduct<Bivector<T>> for Rotor<T> {
274 type Output = Self;
275 #[inline]
276 fn dot(&self, other: &Bivector<T>) -> Self {
277 other.dot(self)
278 }
279}
280
281impl<T: Real> Mul for Rotor<T> {
282 type Output = Self;
283 fn mul(self, other: Self) -> Self {
284 Self {
285 scalar: self.scalar * other.scalar
286 - self.xy * other.xy
287 - self.xz * other.xz
288 - self.yz * other.yz,
289 xy: self.scalar * other.xy + other.scalar * self.xy + self.xz * other.yz
290 - self.yz * other.xz,
291 xz: self.scalar * other.xz + other.scalar * self.xz - self.xy * other.yz
292 + self.yz * other.xy,
293 yz: self.scalar * other.yz + other.scalar * self.yz + self.xy * other.xz
294 - self.xz * other.xy,
295 }
296 }
297}
298
299impl<T: Real> MulAssign for Rotor<T> {
300 fn mul_assign(&mut self, other: Self) {
301 *self = *self * other;
302 }
303}
304
305impl<T: Real> Div for Rotor<T> {
306 type Output = Self;
307 fn div(self, other: Self) -> Self {
308 self * other.inv()
309 }
310}
311
312impl<T: Real> DivAssign for Rotor<T> {
313 fn div_assign(&mut self, other: Self) {
314 *self = *self / other;
315 }
316}
317
318impl<T: Real> Transform<Vector<T>> for Rotor<T> {
319 fn apply_point(&self, point: Vector<T>) -> Vector<T> {
320 self.rotate(point)
321 }
322}
323
324impl<T: Real> Transform<Bivector<T>> for Rotor<T> {
325 fn apply_point(&self, bivector: Bivector<T>) -> Bivector<T> {
326 self.rotate_bivector(bivector)
327 }
328}
329
330impl<T: Display> Display for Rotor<T> {
331 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
332 write!(
333 formatter,
334 "({}, {}, {}, {})",
335 self.scalar, self.xy, self.xz, self.yz
336 )
337 }
338}
339
340impl<T: FromStr> FromStr for Rotor<T> {
341 type Err = ParseRotorError;
342
343 fn from_str(source: &str) -> Result<Self, Self::Err> {
344 let trimmed = source.trim();
345 let inner = trimmed
346 .strip_prefix('(')
347 .and_then(|s| s.strip_suffix(')'))
348 .ok_or(ParseRotorError)?;
349 let parts: Vec<&str> = inner.split(',').collect();
350 if parts.len() != 4 {
351 return Err(ParseRotorError);
352 }
353 let scalar = parts[0].trim().parse().map_err(|_| ParseRotorError)?;
354 let xy = parts[1].trim().parse().map_err(|_| ParseRotorError)?;
355 let xz = parts[2].trim().parse().map_err(|_| ParseRotorError)?;
356 let yz = parts[3].trim().parse().map_err(|_| ParseRotorError)?;
357 Ok(Self { scalar, xy, xz, yz })
358 }
359}
360
361#[derive(Debug, Clone, PartialEq, Eq)]
363pub struct ParseRotorError;
364
365impl Display for ParseRotorError {
366 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
367 write!(formatter, "invalid rotor format")
368 }
369}
370
371impl std::error::Error for ParseRotorError {}