ga2/
rotor.rs

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/// The 2D bivector type.
9#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
10pub struct Rotor<T> {
11    /// The scalar component.
12    pub scalar: T,
13    /// The component representing the xy plane.
14    pub xy: T,
15}
16
17impl<T> Rotor<T> {
18    /// Creates a new rotor from its components.
19    pub fn new(scalar: T, xy: T) -> Self {
20        Self { scalar, xy }
21    }
22}
23
24impl<T: Real> Rotor<T> {
25    /// Rotates a vector by the rotor.
26    pub fn rotate(self, vector: Vector<T>) -> Vector<T> {
27        self.normalize().rotate_normalized(vector)
28    }
29
30    /// Rotates a vector by the rotor.
31    /// The rotor has to be normalized already.
32    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    /// The reverse of the rotor.
42    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    /// Creates a new scalar rotor.
52    pub fn scalar(scalar: T) -> Self {
53        Self {
54            scalar,
55            xy: T::zero(),
56        }
57    }
58
59    /// Creates a new rotor along the xy plane.
60    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}