simply_2dpga/extras/
transformations.rs1use num_traits::Float;
2
3use crate::{defs::{vector::Vector, bivector::{Bivector}, trivector::Trivector, multivector::Multivector}, traits::{GeometricProduct, Dagger}};
4
5use super::{angle::Angle, point2d::Point2d};
6
7impl<N: Float> Multivector<N> {
10 pub fn reflect(&self, other: &Vector<N>) -> Multivector<N> {
13 let a = other.geo(self);
14 self.geo(&a)
15 }
16}
17impl<N: Float> Vector<N> {
18 pub fn reflect(&self, other: &Vector<N>) -> Vector<N> {
21 other.geo(&self.geo(other))
22 .vector
23 }
24}
25impl<N: Float> Bivector<N> {
26 pub fn reflect(&self, other: &Vector<N>) -> Bivector<N> {
29 other.geo(&self.geo(other))
30 .bivector
31 }
32}
33
34pub trait RigidTransformation<V> {
38 fn apply(&self, target: &V) -> V;
41}
42
43
44pub struct Transformer<N: Float> {
46 multivector: Multivector<N>
47}
48impl<N: Float> Transformer<N> {
49 pub fn get_multivector(&self) -> &Multivector<N> {
50 &self.multivector
51 }
52}
53impl<N: Float> RigidTransformation<Multivector<N>> for Transformer<N> {
54 fn apply(&self, target: &Multivector<N>) -> Multivector<N> {
55 self.multivector.reverse()
56 .geo(&target.geo(&self.multivector))
57 }
58}
59impl<N: Float> RigidTransformation<Vector<N>> for Transformer<N> {
60 fn apply(&self, target: &Vector<N>) -> Vector<N> {
61 self.multivector.reverse()
62 .geo(&target.geo(&self.multivector))
63 .vector
64 }
65}
66impl<N: Float> RigidTransformation<Bivector<N>> for Transformer<N> {
67 fn apply(&self, target: &Bivector<N>) -> Bivector<N> {
68 self.multivector.reverse()
69 .geo(&target.geo(&self.multivector))
70 .bivector
71 }
72}
73
74
75pub struct Rotor<N: Float> {
76 angle: Angle<N>,
77 transformer: Transformer<N>,
78}
79impl<N: Float> Rotor<N> {
80 pub fn new(axis: Point2d<N>, angle: Angle<N>) -> Rotor<N> {
82 let alpha = angle.get_radians();
83 let half = N::from(0.5).unwrap();
84 let cos = (alpha * half).cos();
85 let sin = (alpha * half).sin();
86 let mv = Multivector {
87 scalar: cos,
88 vector: crate::defs::vector::Vector::zero(),
89 bivector: (axis.to_bivector() * sin),
90 trivector: Trivector::zero(),
91 };
92 Rotor { angle, transformer: Transformer { multivector: mv }}
93 }
94
95 pub fn get_angle(&self) -> Angle<N> {
97 self.angle
98 }
99 pub fn get_transformer(&self) -> &Transformer<N> {
101 &self.transformer
102 }
103}
104impl<N: Float> RigidTransformation<Multivector<N>> for Rotor<N> {
105 fn apply(&self, target: &Multivector<N>) -> Multivector<N> {
106 self.transformer.apply(target)
107 }
108}
109impl<N: Float> RigidTransformation<Vector<N>> for Rotor<N> {
110 fn apply(&self, target: &Vector<N>) -> Vector<N> {
111 self.transformer.apply(target)
112 }
113}
114impl<N: Float> RigidTransformation<Bivector<N>> for Rotor<N> {
115 fn apply(&self, target: &Bivector<N>) -> Bivector<N> {
116 self.transformer.apply(target)
117 }
118}
119
120pub struct Motor<N: Float> {
122 x: N,
123 y: N,
124 displacement: N,
125 transformer: Transformer<N>,
126}
127impl<N: Float> Motor<N> {
129 pub fn new(x: N, y: N, d: N) -> Motor<N> {
131 let direction = Bivector {
132 e20: x,
133 e01: y,
134 e12: N::zero()
135 };
136 let half = N::from(0.5).unwrap();
137
138 let multivector = Multivector {
139 scalar: N::from(1.0).unwrap(),
140 vector: Vector::zero(),
141 bivector: direction * (d * half),
142 trivector: Trivector::zero()
143 };
144
145 Motor {
146 x, y,
147 displacement: d,
148 transformer: Transformer { multivector }
149 }
150 }
151
152 pub fn get_direction(&self) -> Bivector<N> {
154 Bivector {
155 e20: self.x,
156 e01: self.y,
157 e12: N::zero()
158 }
159 }
160
161 pub fn get_displacement(&self) -> N {
163 self.displacement
164 }
165
166 pub fn get_transformer(&self) -> &Transformer<N> {
168 &self.transformer
169 }
170}
171impl<N: Float> RigidTransformation<Multivector<N>> for Motor<N> {
172 fn apply(&self, target: &Multivector<N>) -> Multivector<N> {
173 self.transformer.apply(target)
174 }
175}
176impl<N: Float> RigidTransformation<Bivector<N>> for Motor<N> {
177 fn apply(&self, target: &Bivector<N>) -> Bivector<N> {
178 self.transformer.apply(target)
179 }
180}
181impl<N: Float> RigidTransformation<Vector<N>> for Motor<N> {
182 fn apply(&self, target: &Vector<N>) -> Vector<N> {
183 self.transformer.apply(target)
184 }
185}
186
187
188pub struct MultiTransform<N: Float> {
190 multivector: Multivector<N>
191}
192impl<N: Float> MultiTransform<N> {
193 pub fn new(transformations: Vec<&Transformer<N>>) -> MultiTransform<N> {
194 let mut mv = transformations
195 .first()
196 .unwrap()
197 .multivector
198 .clone();
199
200 for tr in transformations.iter().skip(1) {
201 mv = mv.geo(&tr.multivector);
202 }
203
204 MultiTransform {
205 multivector: mv
206 }
207 }
208}
209impl<N: Float> RigidTransformation<Multivector<N>> for MultiTransform<N> {
210 fn apply(&self, target: &Multivector<N>) -> Multivector<N> {
211 self.multivector.reverse()
212 .geo(&target.geo(&self.multivector))
213 }
214}
215impl<N: Float> RigidTransformation<Vector<N>> for MultiTransform<N> {
216 fn apply(&self, target: &Vector<N>) -> Vector<N> {
217 self.multivector.reverse()
218 .geo(&target.geo(&self.multivector))
219 .vector
220 }
221}
222impl<N: Float> RigidTransformation<Bivector<N>> for MultiTransform<N> {
223 fn apply(&self, target: &Bivector<N>) -> Bivector<N> {
224 self.multivector.reverse()
225 .geo(&target.geo(&self.multivector))
226 .bivector
227 }
228}