1use crate::*;
2
3use derive_more::{Add, AddAssign, Neg, Sub, SubAssign};
4use num_traits::{real::Real, Inv, One, Zero};
5use std::ops::{Div, DivAssign, Mul, MulAssign};
6use vector_space::{DotProduct, InnerSpace, VectorSpace};
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
10pub struct Rotor<T> {
11 pub scalar: T,
13 pub xy: T,
15}
16
17impl<T> Rotor<T> {
18 pub fn new(scalar: T, xy: T) -> Self {
20 Self { scalar, xy }
21 }
22}
23
24impl<T: Real> Rotor<T> {
25 pub fn rotate(self, vector: Vector<T>) -> Vector<T> {
27 self.normalize().rotate_normalized(vector)
28 }
29
30 pub fn rotate_normalized(self, vector: Vector<T>) -> Vector<T> {
33 let Self { scalar, xy } = self * self;
34
35 Vector {
36 x: scalar * vector.x + xy * vector.y,
37 y: scalar * vector.y - xy * vector.x,
38 }
39 }
40
41 pub fn reverse(self) -> Self {
43 Self {
44 scalar: self.scalar,
45 xy: -self.xy,
46 }
47 }
48}
49
50impl<T: Zero> Rotor<T> {
51 pub fn scalar(scalar: T) -> Self {
53 Self {
54 scalar,
55 xy: T::zero(),
56 }
57 }
58
59 pub fn xy(xy: T) -> Self {
61 Self {
62 scalar: T::zero(),
63 xy,
64 }
65 }
66}
67
68impl<T: Zero> Zero for Rotor<T> {
69 fn zero() -> Self {
70 Self {
71 scalar: T::zero(),
72 xy: T::zero(),
73 }
74 }
75
76 fn is_zero(&self) -> bool {
77 self.scalar.is_zero() && self.xy.is_zero()
78 }
79}
80
81impl<T: Real> One for Rotor<T> {
82 fn one() -> Self {
83 Self {
84 scalar: T::one(),
85 xy: T::zero(),
86 }
87 }
88
89 fn is_one(&self) -> bool {
90 self.scalar.is_one() && self.xy.is_zero()
91 }
92}
93
94impl<T: Real> Inv for Rotor<T> {
95 type Output = Self;
96
97 fn inv(self) -> Self {
98 let rev = self.reverse();
99 rev / self.dot(rev)
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 fn dot(self, other: Self) -> T {
162 self.scalar * other.scalar - self.xy * other.xy
163 }
164}
165
166impl<T: Real> DotProduct<Vector<T>> for Rotor<T> {
167 type Output = Vector<T>;
168 #[inline]
169 fn dot(self, other: Vector<T>) -> Vector<T> {
170 other.dot(self)
171 }
172}
173
174impl<T: Real> DotProduct<Bivector<T>> for Rotor<T> {
175 type Output = Self;
176 #[inline]
177 fn dot(self, other: Bivector<T>) -> Self {
178 other.dot(self)
179 }
180}
181
182impl<T: Real> InnerSpace for Rotor<T> {
183 fn scalar(self, other: Self) -> T {
184 self.dot(other)
185 }
186
187 fn magnitude2(self) -> T {
188 self.dot(self.reverse())
189 }
190}
191
192impl<T: Real> Mul for Rotor<T> {
193 type Output = Self;
194 fn mul(self, other: Self) -> Self {
195 Self {
196 scalar: self.dot(other),
197 xy: self.scalar * other.xy + other.scalar * self.xy,
198 }
199 }
200}
201
202impl<T: Real> MulAssign for Rotor<T> {
203 fn mul_assign(&mut self, other: Self) {
204 *self = *self * other;
205 }
206}
207
208impl<T: Real> Div for Rotor<T> {
209 type Output = Self;
210 fn div(self, other: Self) -> Self {
211 self * other.inv()
212 }
213}
214
215impl<T: Real> DivAssign for Rotor<T> {
216 fn div_assign(&mut self, other: Self) {
217 *self = *self / other;
218 }
219}