1use crate::*;
2
3use std::ops::{Div, DivAssign, Mul, MulAssign};
4
5use derive_more::{Add, AddAssign, Neg, Sub, SubAssign};
6use inner_space::{DotProduct, InnerSpace, Transform, VectorSpace};
7use scalars::{Inv, One, Real, Zero};
8
9#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
11pub struct Rotor<T> {
12 pub scalar: T,
14 pub xy: T,
16}
17
18impl<T> Rotor<T> {
19 pub fn new(scalar: T, xy: T) -> Self {
21 Self { scalar, xy }
22 }
23}
24
25impl<T: Real> Rotor<T> {
26 pub fn rotate(self, vector: Vector<T>) -> Vector<T> {
28 self.normalize().rotate_normalized(vector)
29 }
30
31 pub fn rotate_normalized(self, vector: Vector<T>) -> Vector<T> {
34 let Self { scalar, xy } = self * self;
35
36 Vector {
37 x: scalar * vector.x + xy * vector.y,
38 y: scalar * vector.y - xy * vector.x,
39 }
40 }
41
42 pub fn reverse(self) -> Self {
44 Self {
45 scalar: self.scalar,
46 xy: -self.xy,
47 }
48 }
49}
50
51impl<T: Zero> Rotor<T> {
52 pub fn scalar(scalar: T) -> Self {
54 Self {
55 scalar,
56 xy: T::zero(),
57 }
58 }
59
60 pub fn xy(xy: T) -> Self {
62 Self {
63 scalar: T::zero(),
64 xy,
65 }
66 }
67}
68
69impl<T: Zero> Zero for Rotor<T> {
70 fn zero() -> Self {
71 Self {
72 scalar: T::zero(),
73 xy: T::zero(),
74 }
75 }
76
77 fn is_zero(&self) -> bool {
78 self.scalar.is_zero() && self.xy.is_zero()
79 }
80}
81
82impl<T: Real> One for Rotor<T> {
83 fn one() -> Self {
84 Self {
85 scalar: T::one(),
86 xy: T::zero(),
87 }
88 }
89
90 fn is_one(&self) -> bool {
91 self.scalar.is_one() && self.xy.is_zero()
92 }
93}
94
95impl<T: Real> Inv for Rotor<T> {
96 type Output = Self;
97
98 fn inv(self) -> Self {
99 self.reverse() / self.magnitude2()
100 }
101}
102
103impl<T: Real> From<T> for Rotor<T> {
104 fn from(scalar: T) -> Self {
105 Self::scalar(scalar)
106 }
107}
108
109impl<T> Mul<T> for Rotor<T>
110where
111 T: Mul<Output = T> + Copy,
112{
113 type Output = Self;
114 fn mul(self, other: T) -> Self {
115 Self {
116 scalar: self.scalar * other,
117 xy: self.xy * other,
118 }
119 }
120}
121
122impl<T> MulAssign<T> for Rotor<T>
123where
124 T: MulAssign + Copy,
125{
126 fn mul_assign(&mut self, other: T) {
127 self.scalar *= other;
128 self.xy *= other;
129 }
130}
131
132impl<T> Div<T> for Rotor<T>
133where
134 T: Div<Output = T> + Copy,
135{
136 type Output = Self;
137 fn div(self, other: T) -> Self {
138 Self {
139 scalar: self.scalar / other,
140 xy: self.xy / other,
141 }
142 }
143}
144
145impl<T> DivAssign<T> for Rotor<T>
146where
147 T: DivAssign + Copy,
148{
149 fn div_assign(&mut self, other: T) {
150 self.scalar /= other;
151 self.xy /= other;
152 }
153}
154
155impl<T: Real> VectorSpace for Rotor<T> {
156 type Scalar = T;
157}
158
159impl<T: Real> DotProduct for Rotor<T> {
160 type Output = Self::Scalar;
161
162 fn dot(&self, other: &Self) -> T {
163 self.scalar * other.scalar - self.xy * other.xy
164 }
165
166 fn scalar(&self, other: &Self) -> T {
167 self.scalar * other.scalar + self.xy * other.xy
168 }
169}
170
171impl<T: Real> DotProduct<Vector<T>> for Rotor<T> {
172 type Output = Vector<T>;
173 #[inline]
174 fn dot(&self, other: &Vector<T>) -> Vector<T> {
175 other.dot(self)
176 }
177}
178
179impl<T: Real> DotProduct<Bivector<T>> for Rotor<T> {
180 type Output = Self;
181 #[inline]
182 fn dot(&self, other: &Bivector<T>) -> Self {
183 other.dot(self)
184 }
185}
186
187impl<T: Real> Mul for Rotor<T> {
188 type Output = Self;
189 fn mul(self, other: Self) -> Self {
190 Self {
191 scalar: self.dot(&other),
192 xy: self.scalar * other.xy + other.scalar * self.xy,
193 }
194 }
195}
196
197impl<T: Real> MulAssign for Rotor<T> {
198 fn mul_assign(&mut self, other: Self) {
199 *self = *self * other;
200 }
201}
202
203impl<T: Real> Div for Rotor<T> {
204 type Output = Self;
205 fn div(self, other: Self) -> Self {
206 self * other.inv()
207 }
208}
209
210impl<T: Real> DivAssign for Rotor<T> {
211 fn div_assign(&mut self, other: Self) {
212 *self = *self / other;
213 }
214}
215
216impl<T: Real> Transform<Vector<T>> for Rotor<T> {
217 fn apply_point(&self, point: Vector<T>) -> Vector<T> {
218 self.rotate(point)
219 }
220}
221
222impl<T: Real + std::fmt::Display> std::fmt::Display for Rotor<T> {
223 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 write!(formatter, "({}, {})", self.scalar, self.xy)
225 }
226}
227
228impl<T: Real + std::str::FromStr> std::str::FromStr for Rotor<T> {
229 type Err = String;
230
231 fn from_str(source: &str) -> Result<Self, Self::Err> {
232 let trimmed = source
233 .strip_prefix('(')
234 .and_then(|s| s.strip_suffix(')'))
235 .ok_or_else(|| format!("expected format (scalar, xy), got {source}"))?;
236 let mut parts = trimmed.split(',');
237 let scalar = parts
238 .next()
239 .ok_or_else(|| "missing scalar component".to_string())?
240 .trim()
241 .parse::<T>()
242 .map_err(|_| "failed to parse scalar component".to_string())?;
243 let xy = parts
244 .next()
245 .ok_or_else(|| "missing xy component".to_string())?
246 .trim()
247 .parse::<T>()
248 .map_err(|_| "failed to parse xy component".to_string())?;
249 if parts.next().is_some() {
250 return Err("too many components".to_string());
251 }
252 Ok(Self { scalar, xy })
253 }
254}