1#![allow(clippy::assign_op_pattern)]
2use crate::{simd::*, *};
3use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
4
5#[derive(Clone, Copy)]
6struct MultiVectorGroups {
7 g0: Simd32x4,
9 g1: Simd32x4,
11}
12
13#[derive(Clone, Copy)]
14pub union MultiVector {
15 groups: MultiVectorGroups,
16 elements: [f32; 8],
18}
19
20impl MultiVector {
21 #[allow(clippy::too_many_arguments)]
22 pub const fn new(scalar: f32, e12: f32, e1: f32, e2: f32, e0: f32, e012: f32, e01: f32, _e02: f32) -> Self {
23 Self { elements: [scalar, e12, e1, e2, e0, e012, e01, _e02] }
24 }
25 pub const fn from_groups(g0: Simd32x4, g1: Simd32x4) -> Self {
26 Self { groups: MultiVectorGroups { g0, g1 } }
27 }
28 #[inline(always)]
29 pub fn group0(&self) -> Simd32x4 {
30 unsafe { self.groups.g0 }
31 }
32 #[inline(always)]
33 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
34 unsafe { &mut self.groups.g0 }
35 }
36 #[inline(always)]
37 pub fn group1(&self) -> Simd32x4 {
38 unsafe { self.groups.g1 }
39 }
40 #[inline(always)]
41 pub fn group1_mut(&mut self) -> &mut Simd32x4 {
42 unsafe { &mut self.groups.g1 }
43 }
44}
45
46const MULTIVECTOR_INDEX_REMAP: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
47
48impl std::ops::Index<usize> for MultiVector {
49 type Output = f32;
50
51 fn index(&self, index: usize) -> &Self::Output {
52 unsafe { &self.elements[MULTIVECTOR_INDEX_REMAP[index]] }
53 }
54}
55
56impl std::ops::IndexMut<usize> for MultiVector {
57 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
58 unsafe { &mut self.elements[MULTIVECTOR_INDEX_REMAP[index]] }
59 }
60}
61
62impl std::convert::From<MultiVector> for [f32; 8] {
63 fn from(vector: MultiVector) -> Self {
64 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3], vector.elements[4], vector.elements[5], vector.elements[6], vector.elements[7]] }
65 }
66}
67
68impl std::convert::From<[f32; 8]> for MultiVector {
69 fn from(array: [f32; 8]) -> Self {
70 Self { elements: [array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7]] }
71 }
72}
73
74impl std::fmt::Debug for MultiVector {
75 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
76 formatter
77 .debug_struct("MultiVector")
78 .field("1", &self[0])
79 .field("e12", &self[1])
80 .field("e1", &self[2])
81 .field("e2", &self[3])
82 .field("e0", &self[4])
83 .field("e012", &self[5])
84 .field("e01", &self[6])
85 .field("-e02", &self[7])
86 .finish()
87 }
88}
89
90#[derive(Clone, Copy)]
91struct RotorGroups {
92 g0: Simd32x2,
94}
95
96#[derive(Clone, Copy)]
97pub union Rotor {
98 groups: RotorGroups,
99 elements: [f32; 4],
101}
102
103impl Rotor {
104 #[allow(clippy::too_many_arguments)]
105 pub const fn new(scalar: f32, e12: f32) -> Self {
106 Self { elements: [scalar, e12, 0.0, 0.0] }
107 }
108 pub const fn from_groups(g0: Simd32x2) -> Self {
109 Self { groups: RotorGroups { g0 } }
110 }
111 #[inline(always)]
112 pub fn group0(&self) -> Simd32x2 {
113 unsafe { self.groups.g0 }
114 }
115 #[inline(always)]
116 pub fn group0_mut(&mut self) -> &mut Simd32x2 {
117 unsafe { &mut self.groups.g0 }
118 }
119}
120
121const ROTOR_INDEX_REMAP: [usize; 2] = [0, 1];
122
123impl std::ops::Index<usize> for Rotor {
124 type Output = f32;
125
126 fn index(&self, index: usize) -> &Self::Output {
127 unsafe { &self.elements[ROTOR_INDEX_REMAP[index]] }
128 }
129}
130
131impl std::ops::IndexMut<usize> for Rotor {
132 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
133 unsafe { &mut self.elements[ROTOR_INDEX_REMAP[index]] }
134 }
135}
136
137impl std::convert::From<Rotor> for [f32; 2] {
138 fn from(vector: Rotor) -> Self {
139 unsafe { [vector.elements[0], vector.elements[1]] }
140 }
141}
142
143impl std::convert::From<[f32; 2]> for Rotor {
144 fn from(array: [f32; 2]) -> Self {
145 Self { elements: [array[0], array[1], 0.0, 0.0] }
146 }
147}
148
149impl std::fmt::Debug for Rotor {
150 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
151 formatter
152 .debug_struct("Rotor")
153 .field("1", &self[0])
154 .field("e12", &self[1])
155 .finish()
156 }
157}
158
159#[derive(Clone, Copy)]
160struct PointGroups {
161 g0: Simd32x3,
163}
164
165#[derive(Clone, Copy)]
166pub union Point {
167 groups: PointGroups,
168 elements: [f32; 4],
170}
171
172impl Point {
173 #[allow(clippy::too_many_arguments)]
174 pub const fn new(e12: f32, e01: f32, _e02: f32) -> Self {
175 Self { elements: [e12, e01, _e02, 0.0] }
176 }
177 pub const fn from_groups(g0: Simd32x3) -> Self {
178 Self { groups: PointGroups { g0 } }
179 }
180 #[inline(always)]
181 pub fn group0(&self) -> Simd32x3 {
182 unsafe { self.groups.g0 }
183 }
184 #[inline(always)]
185 pub fn group0_mut(&mut self) -> &mut Simd32x3 {
186 unsafe { &mut self.groups.g0 }
187 }
188}
189
190const POINT_INDEX_REMAP: [usize; 3] = [0, 1, 2];
191
192impl std::ops::Index<usize> for Point {
193 type Output = f32;
194
195 fn index(&self, index: usize) -> &Self::Output {
196 unsafe { &self.elements[POINT_INDEX_REMAP[index]] }
197 }
198}
199
200impl std::ops::IndexMut<usize> for Point {
201 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
202 unsafe { &mut self.elements[POINT_INDEX_REMAP[index]] }
203 }
204}
205
206impl std::convert::From<Point> for [f32; 3] {
207 fn from(vector: Point) -> Self {
208 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2]] }
209 }
210}
211
212impl std::convert::From<[f32; 3]> for Point {
213 fn from(array: [f32; 3]) -> Self {
214 Self { elements: [array[0], array[1], array[2], 0.0] }
215 }
216}
217
218impl std::fmt::Debug for Point {
219 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
220 formatter
221 .debug_struct("Point")
222 .field("e12", &self[0])
223 .field("e01", &self[1])
224 .field("-e02", &self[2])
225 .finish()
226 }
227}
228
229#[derive(Clone, Copy)]
230struct IdealPointGroups {
231 g0: Simd32x2,
233}
234
235#[derive(Clone, Copy)]
236pub union IdealPoint {
237 groups: IdealPointGroups,
238 elements: [f32; 4],
240}
241
242impl IdealPoint {
243 #[allow(clippy::too_many_arguments)]
244 pub const fn new(e01: f32, _e02: f32) -> Self {
245 Self { elements: [e01, _e02, 0.0, 0.0] }
246 }
247 pub const fn from_groups(g0: Simd32x2) -> Self {
248 Self { groups: IdealPointGroups { g0 } }
249 }
250 #[inline(always)]
251 pub fn group0(&self) -> Simd32x2 {
252 unsafe { self.groups.g0 }
253 }
254 #[inline(always)]
255 pub fn group0_mut(&mut self) -> &mut Simd32x2 {
256 unsafe { &mut self.groups.g0 }
257 }
258}
259
260const IDEALPOINT_INDEX_REMAP: [usize; 2] = [0, 1];
261
262impl std::ops::Index<usize> for IdealPoint {
263 type Output = f32;
264
265 fn index(&self, index: usize) -> &Self::Output {
266 unsafe { &self.elements[IDEALPOINT_INDEX_REMAP[index]] }
267 }
268}
269
270impl std::ops::IndexMut<usize> for IdealPoint {
271 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
272 unsafe { &mut self.elements[IDEALPOINT_INDEX_REMAP[index]] }
273 }
274}
275
276impl std::convert::From<IdealPoint> for [f32; 2] {
277 fn from(vector: IdealPoint) -> Self {
278 unsafe { [vector.elements[0], vector.elements[1]] }
279 }
280}
281
282impl std::convert::From<[f32; 2]> for IdealPoint {
283 fn from(array: [f32; 2]) -> Self {
284 Self { elements: [array[0], array[1], 0.0, 0.0] }
285 }
286}
287
288impl std::fmt::Debug for IdealPoint {
289 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
290 formatter
291 .debug_struct("IdealPoint")
292 .field("e01", &self[0])
293 .field("-e02", &self[1])
294 .finish()
295 }
296}
297
298#[derive(Clone, Copy)]
299struct PlaneGroups {
300 g0: Simd32x3,
302}
303
304#[derive(Clone, Copy)]
305pub union Plane {
306 groups: PlaneGroups,
307 elements: [f32; 4],
309}
310
311impl Plane {
312 #[allow(clippy::too_many_arguments)]
313 pub const fn new(e0: f32, e2: f32, e1: f32) -> Self {
314 Self { elements: [e0, e2, e1, 0.0] }
315 }
316 pub const fn from_groups(g0: Simd32x3) -> Self {
317 Self { groups: PlaneGroups { g0 } }
318 }
319 #[inline(always)]
320 pub fn group0(&self) -> Simd32x3 {
321 unsafe { self.groups.g0 }
322 }
323 #[inline(always)]
324 pub fn group0_mut(&mut self) -> &mut Simd32x3 {
325 unsafe { &mut self.groups.g0 }
326 }
327}
328
329const PLANE_INDEX_REMAP: [usize; 3] = [0, 1, 2];
330
331impl std::ops::Index<usize> for Plane {
332 type Output = f32;
333
334 fn index(&self, index: usize) -> &Self::Output {
335 unsafe { &self.elements[PLANE_INDEX_REMAP[index]] }
336 }
337}
338
339impl std::ops::IndexMut<usize> for Plane {
340 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
341 unsafe { &mut self.elements[PLANE_INDEX_REMAP[index]] }
342 }
343}
344
345impl std::convert::From<Plane> for [f32; 3] {
346 fn from(vector: Plane) -> Self {
347 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2]] }
348 }
349}
350
351impl std::convert::From<[f32; 3]> for Plane {
352 fn from(array: [f32; 3]) -> Self {
353 Self { elements: [array[0], array[1], array[2], 0.0] }
354 }
355}
356
357impl std::fmt::Debug for Plane {
358 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
359 formatter
360 .debug_struct("Plane")
361 .field("e0", &self[0])
362 .field("e2", &self[1])
363 .field("e1", &self[2])
364 .finish()
365 }
366}
367
368#[derive(Clone, Copy)]
369struct TranslatorGroups {
370 g0: Simd32x3,
372}
373
374#[derive(Clone, Copy)]
375pub union Translator {
376 groups: TranslatorGroups,
377 elements: [f32; 4],
379}
380
381impl Translator {
382 #[allow(clippy::too_many_arguments)]
383 pub const fn new(scalar: f32, e01: f32, _e02: f32) -> Self {
384 Self { elements: [scalar, e01, _e02, 0.0] }
385 }
386 pub const fn from_groups(g0: Simd32x3) -> Self {
387 Self { groups: TranslatorGroups { g0 } }
388 }
389 #[inline(always)]
390 pub fn group0(&self) -> Simd32x3 {
391 unsafe { self.groups.g0 }
392 }
393 #[inline(always)]
394 pub fn group0_mut(&mut self) -> &mut Simd32x3 {
395 unsafe { &mut self.groups.g0 }
396 }
397}
398
399const TRANSLATOR_INDEX_REMAP: [usize; 3] = [0, 1, 2];
400
401impl std::ops::Index<usize> for Translator {
402 type Output = f32;
403
404 fn index(&self, index: usize) -> &Self::Output {
405 unsafe { &self.elements[TRANSLATOR_INDEX_REMAP[index]] }
406 }
407}
408
409impl std::ops::IndexMut<usize> for Translator {
410 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
411 unsafe { &mut self.elements[TRANSLATOR_INDEX_REMAP[index]] }
412 }
413}
414
415impl std::convert::From<Translator> for [f32; 3] {
416 fn from(vector: Translator) -> Self {
417 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2]] }
418 }
419}
420
421impl std::convert::From<[f32; 3]> for Translator {
422 fn from(array: [f32; 3]) -> Self {
423 Self { elements: [array[0], array[1], array[2], 0.0] }
424 }
425}
426
427impl std::fmt::Debug for Translator {
428 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
429 formatter
430 .debug_struct("Translator")
431 .field("1", &self[0])
432 .field("e01", &self[1])
433 .field("-e02", &self[2])
434 .finish()
435 }
436}
437
438#[derive(Clone, Copy)]
439struct MotorGroups {
440 g0: Simd32x4,
442}
443
444#[derive(Clone, Copy)]
445pub union Motor {
446 groups: MotorGroups,
447 elements: [f32; 4],
449}
450
451impl Motor {
452 #[allow(clippy::too_many_arguments)]
453 pub const fn new(scalar: f32, e12: f32, e01: f32, _e02: f32) -> Self {
454 Self { elements: [scalar, e12, e01, _e02] }
455 }
456 pub const fn from_groups(g0: Simd32x4) -> Self {
457 Self { groups: MotorGroups { g0 } }
458 }
459 #[inline(always)]
460 pub fn group0(&self) -> Simd32x4 {
461 unsafe { self.groups.g0 }
462 }
463 #[inline(always)]
464 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
465 unsafe { &mut self.groups.g0 }
466 }
467}
468
469const MOTOR_INDEX_REMAP: [usize; 4] = [0, 1, 2, 3];
470
471impl std::ops::Index<usize> for Motor {
472 type Output = f32;
473
474 fn index(&self, index: usize) -> &Self::Output {
475 unsafe { &self.elements[MOTOR_INDEX_REMAP[index]] }
476 }
477}
478
479impl std::ops::IndexMut<usize> for Motor {
480 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
481 unsafe { &mut self.elements[MOTOR_INDEX_REMAP[index]] }
482 }
483}
484
485impl std::convert::From<Motor> for [f32; 4] {
486 fn from(vector: Motor) -> Self {
487 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3]] }
488 }
489}
490
491impl std::convert::From<[f32; 4]> for Motor {
492 fn from(array: [f32; 4]) -> Self {
493 Self { elements: [array[0], array[1], array[2], array[3]] }
494 }
495}
496
497impl std::fmt::Debug for Motor {
498 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
499 formatter
500 .debug_struct("Motor")
501 .field("1", &self[0])
502 .field("e12", &self[1])
503 .field("e01", &self[2])
504 .field("-e02", &self[3])
505 .finish()
506 }
507}
508
509#[derive(Clone, Copy)]
510struct MotorDualGroups {
511 g0: Simd32x4,
513}
514
515#[derive(Clone, Copy)]
516pub union MotorDual {
517 groups: MotorDualGroups,
518 elements: [f32; 4],
520}
521
522impl MotorDual {
523 #[allow(clippy::too_many_arguments)]
524 pub const fn new(e012: f32, e0: f32, e2: f32, e1: f32) -> Self {
525 Self { elements: [e012, e0, e2, e1] }
526 }
527 pub const fn from_groups(g0: Simd32x4) -> Self {
528 Self { groups: MotorDualGroups { g0 } }
529 }
530 #[inline(always)]
531 pub fn group0(&self) -> Simd32x4 {
532 unsafe { self.groups.g0 }
533 }
534 #[inline(always)]
535 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
536 unsafe { &mut self.groups.g0 }
537 }
538}
539
540const MOTORDUAL_INDEX_REMAP: [usize; 4] = [0, 1, 2, 3];
541
542impl std::ops::Index<usize> for MotorDual {
543 type Output = f32;
544
545 fn index(&self, index: usize) -> &Self::Output {
546 unsafe { &self.elements[MOTORDUAL_INDEX_REMAP[index]] }
547 }
548}
549
550impl std::ops::IndexMut<usize> for MotorDual {
551 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
552 unsafe { &mut self.elements[MOTORDUAL_INDEX_REMAP[index]] }
553 }
554}
555
556impl std::convert::From<MotorDual> for [f32; 4] {
557 fn from(vector: MotorDual) -> Self {
558 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3]] }
559 }
560}
561
562impl std::convert::From<[f32; 4]> for MotorDual {
563 fn from(array: [f32; 4]) -> Self {
564 Self { elements: [array[0], array[1], array[2], array[3]] }
565 }
566}
567
568impl std::fmt::Debug for MotorDual {
569 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
570 formatter
571 .debug_struct("MotorDual")
572 .field("e012", &self[0])
573 .field("e0", &self[1])
574 .field("e2", &self[2])
575 .field("e1", &self[3])
576 .finish()
577 }
578}
579
580impl Add<MultiVector> for f32 {
581 type Output = MultiVector;
582
583 fn add(self, other: MultiVector) -> MultiVector {
584 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0(), g1: other.group1() } }
585 }
586}
587
588impl Sub<MultiVector> for f32 {
589 type Output = MultiVector;
590
591 fn sub(self, other: MultiVector) -> MultiVector {
592 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0(), g1: Simd32x4::from(0.0) - other.group1() } }
593 }
594}
595
596impl GeometricProduct<MultiVector> for f32 {
597 type Output = MultiVector;
598
599 fn geometric_product(self, other: MultiVector) -> MultiVector {
600 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
601 }
602}
603
604impl RegressiveProduct<MultiVector> for f32 {
605 type Output = f32;
606
607 fn regressive_product(self, other: MultiVector) -> f32 {
608 self * other.group1()[1]
609 }
610}
611
612impl OuterProduct<MultiVector> for f32 {
613 type Output = MultiVector;
614
615 fn outer_product(self, other: MultiVector) -> MultiVector {
616 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
617 }
618}
619
620impl InnerProduct<MultiVector> for f32 {
621 type Output = MultiVector;
622
623 fn inner_product(self, other: MultiVector) -> MultiVector {
624 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
625 }
626}
627
628impl LeftContraction<MultiVector> for f32 {
629 type Output = MultiVector;
630
631 fn left_contraction(self, other: MultiVector) -> MultiVector {
632 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
633 }
634}
635
636impl RightContraction<MultiVector> for f32 {
637 type Output = f32;
638
639 fn right_contraction(self, other: MultiVector) -> f32 {
640 self * other.group0()[0]
641 }
642}
643
644impl ScalarProduct<MultiVector> for f32 {
645 type Output = f32;
646
647 fn scalar_product(self, other: MultiVector) -> f32 {
648 self * other.group0()[0]
649 }
650}
651
652impl Add<Rotor> for f32 {
653 type Output = Rotor;
654
655 fn add(self, other: Rotor) -> Rotor {
656 Rotor { groups: RotorGroups { g0: Simd32x2::from(self) * Simd32x2::from([1.0, 0.0]) + other.group0() } }
657 }
658}
659
660impl Sub<Rotor> for f32 {
661 type Output = Rotor;
662
663 fn sub(self, other: Rotor) -> Rotor {
664 Rotor { groups: RotorGroups { g0: Simd32x2::from(self) * Simd32x2::from([1.0, 0.0]) - other.group0() } }
665 }
666}
667
668impl GeometricProduct<Rotor> for f32 {
669 type Output = Rotor;
670
671 fn geometric_product(self, other: Rotor) -> Rotor {
672 Rotor { groups: RotorGroups { g0: Simd32x2::from(self) * other.group0() } }
673 }
674}
675
676impl OuterProduct<Rotor> for f32 {
677 type Output = Rotor;
678
679 fn outer_product(self, other: Rotor) -> Rotor {
680 Rotor { groups: RotorGroups { g0: Simd32x2::from(self) * other.group0() } }
681 }
682}
683
684impl InnerProduct<Rotor> for f32 {
685 type Output = Rotor;
686
687 fn inner_product(self, other: Rotor) -> Rotor {
688 Rotor { groups: RotorGroups { g0: Simd32x2::from(self) * other.group0() } }
689 }
690}
691
692impl LeftContraction<Rotor> for f32 {
693 type Output = Rotor;
694
695 fn left_contraction(self, other: Rotor) -> Rotor {
696 Rotor { groups: RotorGroups { g0: Simd32x2::from(self) * other.group0() } }
697 }
698}
699
700impl RightContraction<Rotor> for f32 {
701 type Output = f32;
702
703 fn right_contraction(self, other: Rotor) -> f32 {
704 self * other.group0()[0]
705 }
706}
707
708impl ScalarProduct<Rotor> for f32 {
709 type Output = f32;
710
711 fn scalar_product(self, other: Rotor) -> f32 {
712 self * other.group0()[0]
713 }
714}
715
716impl Add<Point> for f32 {
717 type Output = Motor;
718
719 fn add(self, other: Point) -> Motor {
720 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
721 }
722}
723
724impl Sub<Point> for f32 {
725 type Output = Motor;
726
727 fn sub(self, other: Point) -> Motor {
728 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
729 }
730}
731
732impl GeometricProduct<Point> for f32 {
733 type Output = Point;
734
735 fn geometric_product(self, other: Point) -> Point {
736 Point { groups: PointGroups { g0: Simd32x3::from(self) * other.group0() } }
737 }
738}
739
740impl OuterProduct<Point> for f32 {
741 type Output = Point;
742
743 fn outer_product(self, other: Point) -> Point {
744 Point { groups: PointGroups { g0: Simd32x3::from(self) * other.group0() } }
745 }
746}
747
748impl InnerProduct<Point> for f32 {
749 type Output = Point;
750
751 fn inner_product(self, other: Point) -> Point {
752 Point { groups: PointGroups { g0: Simd32x3::from(self) * other.group0() } }
753 }
754}
755
756impl LeftContraction<Point> for f32 {
757 type Output = Point;
758
759 fn left_contraction(self, other: Point) -> Point {
760 Point { groups: PointGroups { g0: Simd32x3::from(self) * other.group0() } }
761 }
762}
763
764impl Add<IdealPoint> for f32 {
765 type Output = Translator;
766
767 fn add(self, other: IdealPoint) -> Translator {
768 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
769 }
770}
771
772impl Sub<IdealPoint> for f32 {
773 type Output = Translator;
774
775 fn sub(self, other: IdealPoint) -> Translator {
776 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * Simd32x3::from([1.0, 0.0, 0.0]) - Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
777 }
778}
779
780impl GeometricProduct<IdealPoint> for f32 {
781 type Output = IdealPoint;
782
783 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
784 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self) * other.group0() } }
785 }
786}
787
788impl OuterProduct<IdealPoint> for f32 {
789 type Output = IdealPoint;
790
791 fn outer_product(self, other: IdealPoint) -> IdealPoint {
792 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self) * other.group0() } }
793 }
794}
795
796impl InnerProduct<IdealPoint> for f32 {
797 type Output = IdealPoint;
798
799 fn inner_product(self, other: IdealPoint) -> IdealPoint {
800 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self) * other.group0() } }
801 }
802}
803
804impl LeftContraction<IdealPoint> for f32 {
805 type Output = IdealPoint;
806
807 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
808 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self) * other.group0() } }
809 }
810}
811
812impl GeometricProduct<Plane> for f32 {
813 type Output = Plane;
814
815 fn geometric_product(self, other: Plane) -> Plane {
816 Plane { groups: PlaneGroups { g0: Simd32x3::from(self) * other.group0() } }
817 }
818}
819
820impl OuterProduct<Plane> for f32 {
821 type Output = Plane;
822
823 fn outer_product(self, other: Plane) -> Plane {
824 Plane { groups: PlaneGroups { g0: Simd32x3::from(self) * other.group0() } }
825 }
826}
827
828impl InnerProduct<Plane> for f32 {
829 type Output = Plane;
830
831 fn inner_product(self, other: Plane) -> Plane {
832 Plane { groups: PlaneGroups { g0: Simd32x3::from(self) * other.group0() } }
833 }
834}
835
836impl LeftContraction<Plane> for f32 {
837 type Output = Plane;
838
839 fn left_contraction(self, other: Plane) -> Plane {
840 Plane { groups: PlaneGroups { g0: Simd32x3::from(self) * other.group0() } }
841 }
842}
843
844impl Add<Translator> for f32 {
845 type Output = Translator;
846
847 fn add(self, other: Translator) -> Translator {
848 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * Simd32x3::from([1.0, 0.0, 0.0]) + other.group0() } }
849 }
850}
851
852impl Sub<Translator> for f32 {
853 type Output = Translator;
854
855 fn sub(self, other: Translator) -> Translator {
856 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * Simd32x3::from([1.0, 0.0, 0.0]) - other.group0() } }
857 }
858}
859
860impl GeometricProduct<Translator> for f32 {
861 type Output = Translator;
862
863 fn geometric_product(self, other: Translator) -> Translator {
864 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * other.group0() } }
865 }
866}
867
868impl OuterProduct<Translator> for f32 {
869 type Output = Translator;
870
871 fn outer_product(self, other: Translator) -> Translator {
872 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * other.group0() } }
873 }
874}
875
876impl InnerProduct<Translator> for f32 {
877 type Output = Translator;
878
879 fn inner_product(self, other: Translator) -> Translator {
880 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * other.group0() } }
881 }
882}
883
884impl LeftContraction<Translator> for f32 {
885 type Output = Translator;
886
887 fn left_contraction(self, other: Translator) -> Translator {
888 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self) * other.group0() } }
889 }
890}
891
892impl RightContraction<Translator> for f32 {
893 type Output = f32;
894
895 fn right_contraction(self, other: Translator) -> f32 {
896 self * other.group0()[0]
897 }
898}
899
900impl ScalarProduct<Translator> for f32 {
901 type Output = f32;
902
903 fn scalar_product(self, other: Translator) -> f32 {
904 self * other.group0()[0]
905 }
906}
907
908impl Add<Motor> for f32 {
909 type Output = Motor;
910
911 fn add(self, other: Motor) -> Motor {
912 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0() } }
913 }
914}
915
916impl Sub<Motor> for f32 {
917 type Output = Motor;
918
919 fn sub(self, other: Motor) -> Motor {
920 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0() } }
921 }
922}
923
924impl GeometricProduct<Motor> for f32 {
925 type Output = Motor;
926
927 fn geometric_product(self, other: Motor) -> Motor {
928 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0() } }
929 }
930}
931
932impl OuterProduct<Motor> for f32 {
933 type Output = Motor;
934
935 fn outer_product(self, other: Motor) -> Motor {
936 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0() } }
937 }
938}
939
940impl InnerProduct<Motor> for f32 {
941 type Output = Motor;
942
943 fn inner_product(self, other: Motor) -> Motor {
944 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0() } }
945 }
946}
947
948impl LeftContraction<Motor> for f32 {
949 type Output = Motor;
950
951 fn left_contraction(self, other: Motor) -> Motor {
952 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0() } }
953 }
954}
955
956impl RightContraction<Motor> for f32 {
957 type Output = f32;
958
959 fn right_contraction(self, other: Motor) -> f32 {
960 self * other.group0()[0]
961 }
962}
963
964impl ScalarProduct<Motor> for f32 {
965 type Output = f32;
966
967 fn scalar_product(self, other: Motor) -> f32 {
968 self * other.group0()[0]
969 }
970}
971
972impl GeometricProduct<MotorDual> for f32 {
973 type Output = MotorDual;
974
975 fn geometric_product(self, other: MotorDual) -> MotorDual {
976 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self) * other.group0() } }
977 }
978}
979
980impl RegressiveProduct<MotorDual> for f32 {
981 type Output = f32;
982
983 fn regressive_product(self, other: MotorDual) -> f32 {
984 self * other.group0()[0]
985 }
986}
987
988impl OuterProduct<MotorDual> for f32 {
989 type Output = MotorDual;
990
991 fn outer_product(self, other: MotorDual) -> MotorDual {
992 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self) * other.group0() } }
993 }
994}
995
996impl InnerProduct<MotorDual> for f32 {
997 type Output = MotorDual;
998
999 fn inner_product(self, other: MotorDual) -> MotorDual {
1000 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self) * other.group0() } }
1001 }
1002}
1003
1004impl LeftContraction<MotorDual> for f32 {
1005 type Output = MotorDual;
1006
1007 fn left_contraction(self, other: MotorDual) -> MotorDual {
1008 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self) * other.group0() } }
1009 }
1010}
1011
1012impl Zero for MultiVector {
1013 fn zero() -> Self {
1014 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0), g1: Simd32x4::from(0.0) } }
1015 }
1016}
1017
1018impl One for MultiVector {
1019 fn one() -> Self {
1020 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(0.0) } }
1021 }
1022}
1023
1024impl Neg for MultiVector {
1025 type Output = MultiVector;
1026
1027 fn neg(self) -> MultiVector {
1028 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(-1.0), g1: self.group1() * Simd32x4::from(-1.0) } }
1029 }
1030}
1031
1032impl Automorphism for MultiVector {
1033 type Output = MultiVector;
1034
1035 fn automorphism(self) -> MultiVector {
1036 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g1: self.group1() * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) } }
1037 }
1038}
1039
1040impl Reversal for MultiVector {
1041 type Output = MultiVector;
1042
1043 fn reversal(self) -> MultiVector {
1044 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: self.group1() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
1045 }
1046}
1047
1048impl Conjugation for MultiVector {
1049 type Output = MultiVector;
1050
1051 fn conjugation(self) -> MultiVector {
1052 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: self.group1() * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) } }
1053 }
1054}
1055
1056impl Dual for MultiVector {
1057 type Output = MultiVector;
1058
1059 fn dual(self) -> MultiVector {
1060 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group1(), 1, 0, 3, 2), g1: swizzle!(self.group0(), 1, 0, 3, 2) } }
1061 }
1062}
1063
1064impl Into<f32> for MultiVector {
1065 fn into(self) -> f32 {
1066 self.group0()[0]
1067 }
1068}
1069
1070impl Add<f32> for MultiVector {
1071 type Output = MultiVector;
1072
1073 fn add(self, other: f32) -> MultiVector {
1074 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() } }
1075 }
1076}
1077
1078impl AddAssign<f32> for MultiVector {
1079 fn add_assign(&mut self, other: f32) {
1080 *self = (*self).add(other);
1081 }
1082}
1083
1084impl Sub<f32> for MultiVector {
1085 type Output = MultiVector;
1086
1087 fn sub(self, other: f32) -> MultiVector {
1088 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() } }
1089 }
1090}
1091
1092impl SubAssign<f32> for MultiVector {
1093 fn sub_assign(&mut self, other: f32) {
1094 *self = (*self).sub(other);
1095 }
1096}
1097
1098impl GeometricProduct<f32> for MultiVector {
1099 type Output = MultiVector;
1100
1101 fn geometric_product(self, other: f32) -> MultiVector {
1102 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
1103 }
1104}
1105
1106impl RegressiveProduct<f32> for MultiVector {
1107 type Output = f32;
1108
1109 fn regressive_product(self, other: f32) -> f32 {
1110 self.group1()[1] * other
1111 }
1112}
1113
1114impl OuterProduct<f32> for MultiVector {
1115 type Output = MultiVector;
1116
1117 fn outer_product(self, other: f32) -> MultiVector {
1118 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
1119 }
1120}
1121
1122impl InnerProduct<f32> for MultiVector {
1123 type Output = MultiVector;
1124
1125 fn inner_product(self, other: f32) -> MultiVector {
1126 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
1127 }
1128}
1129
1130impl LeftContraction<f32> for MultiVector {
1131 type Output = f32;
1132
1133 fn left_contraction(self, other: f32) -> f32 {
1134 self.group0()[0] * other
1135 }
1136}
1137
1138impl RightContraction<f32> for MultiVector {
1139 type Output = MultiVector;
1140
1141 fn right_contraction(self, other: f32) -> MultiVector {
1142 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
1143 }
1144}
1145
1146impl ScalarProduct<f32> for MultiVector {
1147 type Output = f32;
1148
1149 fn scalar_product(self, other: f32) -> f32 {
1150 self.group0()[0] * other
1151 }
1152}
1153
1154impl Add<MultiVector> for MultiVector {
1155 type Output = MultiVector;
1156
1157 fn add(self, other: MultiVector) -> MultiVector {
1158 MultiVector { groups: MultiVectorGroups { g0: self.group0() + other.group0(), g1: self.group1() + other.group1() } }
1159 }
1160}
1161
1162impl AddAssign<MultiVector> for MultiVector {
1163 fn add_assign(&mut self, other: MultiVector) {
1164 *self = (*self).add(other);
1165 }
1166}
1167
1168impl Sub<MultiVector> for MultiVector {
1169 type Output = MultiVector;
1170
1171 fn sub(self, other: MultiVector) -> MultiVector {
1172 MultiVector { groups: MultiVectorGroups { g0: self.group0() - other.group0(), g1: self.group1() - other.group1() } }
1173 }
1174}
1175
1176impl SubAssign<MultiVector> for MultiVector {
1177 fn sub_assign(&mut self, other: MultiVector) {
1178 *self = (*self).sub(other);
1179 }
1180}
1181
1182impl Mul<MultiVector> for MultiVector {
1183 type Output = MultiVector;
1184
1185 fn mul(self, other: MultiVector) -> MultiVector {
1186 MultiVector { groups: MultiVectorGroups { g0: self.group0() * other.group0(), g1: self.group1() * other.group1() } }
1187 }
1188}
1189
1190impl MulAssign<MultiVector> for MultiVector {
1191 fn mul_assign(&mut self, other: MultiVector) {
1192 *self = (*self).mul(other);
1193 }
1194}
1195
1196impl Div<MultiVector> for MultiVector {
1197 type Output = MultiVector;
1198
1199 fn div(self, other: MultiVector) -> MultiVector {
1200 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) / Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from([self.group1()[0], self.group1()[1], self.group1()[2], self.group1()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) / Simd32x4::from([other.group1()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) } }
1201 }
1202}
1203
1204impl DivAssign<MultiVector> for MultiVector {
1205 fn div_assign(&mut self, other: MultiVector) {
1206 *self = (*self).div(other);
1207 }
1208}
1209
1210impl GeometricProduct<MultiVector> for MultiVector {
1211 type Output = MultiVector;
1212
1213 fn geometric_product(self, other: MultiVector) -> MultiVector {
1214 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 2, 1, 0) + Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1215 }
1216}
1217
1218impl RegressiveProduct<MultiVector> for MultiVector {
1219 type Output = MultiVector;
1220
1221 fn regressive_product(self, other: MultiVector) -> MultiVector {
1222 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * other.group1() * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 1, 3) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 2, 1) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * other.group0() + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 1, 3) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 2, 1) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[1]) * other.group1() + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 1, 3) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 2, 1) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1223 }
1224}
1225
1226impl OuterProduct<MultiVector> for MultiVector {
1227 type Output = MultiVector;
1228
1229 fn outer_product(self, other: MultiVector) -> MultiVector {
1230 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 0, 3) * Simd32x4::from([0.0, 1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 2, 0) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 0, 3) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 2, 0) * Simd32x4::from([0.0, 1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 0, 3) * Simd32x4::from([0.0, 1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 2, 0) * Simd32x4::from([0.0, 1.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) } }
1231 }
1232}
1233
1234impl InnerProduct<MultiVector> for MultiVector {
1235 type Output = MultiVector;
1236
1237 fn inner_product(self, other: MultiVector) -> MultiVector {
1238 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 1, 0) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 2, 0, 2, 2) * swizzle!(other.group0(), 2, 0, 0, 1) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 2, 1) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 1, 3) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
1239 }
1240}
1241
1242impl LeftContraction<MultiVector> for MultiVector {
1243 type Output = MultiVector;
1244
1245 fn left_contraction(self, other: MultiVector) -> MultiVector {
1246 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 2, 1) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 1, 3) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 2, 1) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 1, 3) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
1247 }
1248}
1249
1250impl RightContraction<MultiVector> for MultiVector {
1251 type Output = MultiVector;
1252
1253 fn right_contraction(self, other: MultiVector) -> MultiVector {
1254 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1255 }
1256}
1257
1258impl ScalarProduct<MultiVector> for MultiVector {
1259 type Output = f32;
1260
1261 fn scalar_product(self, other: MultiVector) -> f32 {
1262 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
1263 }
1264}
1265
1266impl Into<Rotor> for MultiVector {
1267 fn into(self) -> Rotor {
1268 Rotor { groups: RotorGroups { g0: Simd32x2::from([self.group0()[0], self.group0()[1]]) } }
1269 }
1270}
1271
1272impl Add<Rotor> for MultiVector {
1273 type Output = MultiVector;
1274
1275 fn add(self, other: Rotor) -> MultiVector {
1276 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: self.group1() } }
1277 }
1278}
1279
1280impl AddAssign<Rotor> for MultiVector {
1281 fn add_assign(&mut self, other: Rotor) {
1282 *self = (*self).add(other);
1283 }
1284}
1285
1286impl Sub<Rotor> for MultiVector {
1287 type Output = MultiVector;
1288
1289 fn sub(self, other: Rotor) -> MultiVector {
1290 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: self.group1() } }
1291 }
1292}
1293
1294impl SubAssign<Rotor> for MultiVector {
1295 fn sub_assign(&mut self, other: Rotor) {
1296 *self = (*self).sub(other);
1297 }
1298}
1299
1300impl GeometricProduct<Rotor> for MultiVector {
1301 type Output = MultiVector;
1302
1303 fn geometric_product(self, other: Rotor) -> MultiVector {
1304 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]), g1: Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(self.group1(), 0, 0, 2, 2) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
1305 }
1306}
1307
1308impl OuterProduct<Rotor> for MultiVector {
1309 type Output = MultiVector;
1310
1311 fn outer_product(self, other: Rotor) -> MultiVector {
1312 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]), g1: Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + swizzle!(self.group1(), 0, 0, 2, 3) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) } }
1313 }
1314}
1315
1316impl InnerProduct<Rotor> for MultiVector {
1317 type Output = MultiVector;
1318
1319 fn inner_product(self, other: Rotor) -> MultiVector {
1320 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]), g1: Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group1(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
1321 }
1322}
1323
1324impl RightContraction<Rotor> for MultiVector {
1325 type Output = MultiVector;
1326
1327 fn right_contraction(self, other: Rotor) -> MultiVector {
1328 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]), g1: Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group1(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
1329 }
1330}
1331
1332impl ScalarProduct<Rotor> for MultiVector {
1333 type Output = f32;
1334
1335 fn scalar_product(self, other: Rotor) -> f32 {
1336 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
1337 }
1338}
1339
1340impl Into<Point> for MultiVector {
1341 fn into(self) -> Point {
1342 Point { groups: PointGroups { g0: Simd32x3::from([self.group0()[1], self.group1()[2], self.group1()[3]]) } }
1343 }
1344}
1345
1346impl Add<Point> for MultiVector {
1347 type Output = MultiVector;
1348
1349 fn add(self, other: Point) -> MultiVector {
1350 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]), g1: self.group1() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1351 }
1352}
1353
1354impl AddAssign<Point> for MultiVector {
1355 fn add_assign(&mut self, other: Point) {
1356 *self = (*self).add(other);
1357 }
1358}
1359
1360impl Sub<Point> for MultiVector {
1361 type Output = MultiVector;
1362
1363 fn sub(self, other: Point) -> MultiVector {
1364 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]), g1: self.group1() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1365 }
1366}
1367
1368impl SubAssign<Point> for MultiVector {
1369 fn sub_assign(&mut self, other: Point) {
1370 *self = (*self).sub(other);
1371 }
1372}
1373
1374impl GeometricProduct<Point> for MultiVector {
1375 type Output = MultiVector;
1376
1377 fn geometric_product(self, other: Point) -> MultiVector {
1378 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 1, 0, 3, 2) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + swizzle!(self.group0(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1379 }
1380}
1381
1382impl ScalarProduct<Point> for MultiVector {
1383 type Output = f32;
1384
1385 fn scalar_product(self, other: Point) -> f32 {
1386 0.0 - self.group0()[1] * other.group0()[0]
1387 }
1388}
1389
1390impl Into<IdealPoint> for MultiVector {
1391 fn into(self) -> IdealPoint {
1392 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group1()[2], self.group1()[3]]) } }
1393 }
1394}
1395
1396impl Add<IdealPoint> for MultiVector {
1397 type Output = MultiVector;
1398
1399 fn add(self, other: IdealPoint) -> MultiVector {
1400 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1401 }
1402}
1403
1404impl AddAssign<IdealPoint> for MultiVector {
1405 fn add_assign(&mut self, other: IdealPoint) {
1406 *self = (*self).add(other);
1407 }
1408}
1409
1410impl Sub<IdealPoint> for MultiVector {
1411 type Output = MultiVector;
1412
1413 fn sub(self, other: IdealPoint) -> MultiVector {
1414 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1415 }
1416}
1417
1418impl SubAssign<IdealPoint> for MultiVector {
1419 fn sub_assign(&mut self, other: IdealPoint) {
1420 *self = (*self).sub(other);
1421 }
1422}
1423
1424impl Into<Plane> for MultiVector {
1425 fn into(self) -> Plane {
1426 Plane { groups: PlaneGroups { g0: Simd32x3::from([self.group1()[0], self.group0()[3], self.group0()[2]]) } }
1427 }
1428}
1429
1430impl Add<Plane> for MultiVector {
1431 type Output = MultiVector;
1432
1433 fn add(self, other: Plane) -> MultiVector {
1434 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]), g1: self.group1() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1435 }
1436}
1437
1438impl AddAssign<Plane> for MultiVector {
1439 fn add_assign(&mut self, other: Plane) {
1440 *self = (*self).add(other);
1441 }
1442}
1443
1444impl Sub<Plane> for MultiVector {
1445 type Output = MultiVector;
1446
1447 fn sub(self, other: Plane) -> MultiVector {
1448 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]), g1: self.group1() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1449 }
1450}
1451
1452impl SubAssign<Plane> for MultiVector {
1453 fn sub_assign(&mut self, other: Plane) {
1454 *self = (*self).sub(other);
1455 }
1456}
1457
1458impl GeometricProduct<Plane> for MultiVector {
1459 type Output = MultiVector;
1460
1461 fn geometric_product(self, other: Plane) -> MultiVector {
1462 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + swizzle!(self.group0(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[1]]), g1: Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) } }
1463 }
1464}
1465
1466impl ScalarProduct<Plane> for MultiVector {
1467 type Output = f32;
1468
1469 fn scalar_product(self, other: Plane) -> f32 {
1470 self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[1]
1471 }
1472}
1473
1474impl Into<Translator> for MultiVector {
1475 fn into(self) -> Translator {
1476 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group1()[2], self.group1()[3]]) } }
1477 }
1478}
1479
1480impl Add<Translator> for MultiVector {
1481 type Output = MultiVector;
1482
1483 fn add(self, other: Translator) -> MultiVector {
1484 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1485 }
1486}
1487
1488impl AddAssign<Translator> for MultiVector {
1489 fn add_assign(&mut self, other: Translator) {
1490 *self = (*self).add(other);
1491 }
1492}
1493
1494impl Sub<Translator> for MultiVector {
1495 type Output = MultiVector;
1496
1497 fn sub(self, other: Translator) -> MultiVector {
1498 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1499 }
1500}
1501
1502impl SubAssign<Translator> for MultiVector {
1503 fn sub_assign(&mut self, other: Translator) {
1504 *self = (*self).sub(other);
1505 }
1506}
1507
1508impl GeometricProduct<Translator> for MultiVector {
1509 type Output = MultiVector;
1510
1511 fn geometric_product(self, other: Translator) -> MultiVector {
1512 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1513 }
1514}
1515
1516impl OuterProduct<Translator> for MultiVector {
1517 type Output = MultiVector;
1518
1519 fn outer_product(self, other: Translator) -> MultiVector {
1520 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group1()[0], self.group0()[2], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[2], other.group0()[1], other.group0()[2]]) } }
1521 }
1522}
1523
1524impl InnerProduct<Translator> for MultiVector {
1525 type Output = MultiVector;
1526
1527 fn inner_product(self, other: Translator) -> MultiVector {
1528 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[2], self.group1()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1529 }
1530}
1531
1532impl RightContraction<Translator> for MultiVector {
1533 type Output = MultiVector;
1534
1535 fn right_contraction(self, other: Translator) -> MultiVector {
1536 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: self.group1() * Simd32x4::from(other.group0()[0]) } }
1537 }
1538}
1539
1540impl ScalarProduct<Translator> for MultiVector {
1541 type Output = f32;
1542
1543 fn scalar_product(self, other: Translator) -> f32 {
1544 self.group0()[0] * other.group0()[0]
1545 }
1546}
1547
1548impl Into<Motor> for MultiVector {
1549 fn into(self) -> Motor {
1550 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group1()[2], self.group1()[3]]) } }
1551 }
1552}
1553
1554impl Add<Motor> for MultiVector {
1555 type Output = MultiVector;
1556
1557 fn add(self, other: Motor) -> MultiVector {
1558 MultiVector { groups: MultiVectorGroups { g0: self.group0() + swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: self.group1() + swizzle!(other.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1559 }
1560}
1561
1562impl AddAssign<Motor> for MultiVector {
1563 fn add_assign(&mut self, other: Motor) {
1564 *self = (*self).add(other);
1565 }
1566}
1567
1568impl Sub<Motor> for MultiVector {
1569 type Output = MultiVector;
1570
1571 fn sub(self, other: Motor) -> MultiVector {
1572 MultiVector { groups: MultiVectorGroups { g0: self.group0() - swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: self.group1() - swizzle!(other.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
1573 }
1574}
1575
1576impl SubAssign<Motor> for MultiVector {
1577 fn sub_assign(&mut self, other: Motor) {
1578 *self = (*self).sub(other);
1579 }
1580}
1581
1582impl GeometricProduct<Motor> for MultiVector {
1583 type Output = MultiVector;
1584
1585 fn geometric_product(self, other: Motor) -> MultiVector {
1586 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * swizzle!(other.group0(), 0, 1, 0, 1), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 3, 3) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(self.group0(), 2, 2, 0, 0) * swizzle!(other.group0(), 2, 3, 2, 3) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1587 }
1588}
1589
1590impl OuterProduct<Motor> for MultiVector {
1591 type Output = MultiVector;
1592
1593 fn outer_product(self, other: Motor) -> MultiVector {
1594 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * swizzle!(other.group0(), 0, 1, 0, 0), g1: Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 2, 0, 0) * swizzle!(other.group0(), 0, 3, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1595 }
1596}
1597
1598impl InnerProduct<Motor> for MultiVector {
1599 type Output = MultiVector;
1600
1601 fn inner_product(self, other: Motor) -> MultiVector {
1602 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * swizzle!(other.group0(), 0, 1, 0, 1), g1: Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 2, 0, 0, 0) * swizzle!(other.group0(), 2, 0, 2, 3) * Simd32x4::from([-1.0, 0.0, 1.0, 1.0]) } }
1603 }
1604}
1605
1606impl RightContraction<Motor> for MultiVector {
1607 type Output = MultiVector;
1608
1609 fn right_contraction(self, other: Motor) -> MultiVector {
1610 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]), g1: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group1(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
1611 }
1612}
1613
1614impl ScalarProduct<Motor> for MultiVector {
1615 type Output = f32;
1616
1617 fn scalar_product(self, other: Motor) -> f32 {
1618 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
1619 }
1620}
1621
1622impl Into<MotorDual> for MultiVector {
1623 fn into(self) -> MotorDual {
1624 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group1()[1], self.group1()[0], self.group0()[3], self.group0()[2]]) } }
1625 }
1626}
1627
1628impl Add<MotorDual> for MultiVector {
1629 type Output = MultiVector;
1630
1631 fn add(self, other: MotorDual) -> MultiVector {
1632 MultiVector { groups: MultiVectorGroups { g0: self.group0() + swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]), g1: self.group1() + swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
1633 }
1634}
1635
1636impl AddAssign<MotorDual> for MultiVector {
1637 fn add_assign(&mut self, other: MotorDual) {
1638 *self = (*self).add(other);
1639 }
1640}
1641
1642impl Sub<MotorDual> for MultiVector {
1643 type Output = MultiVector;
1644
1645 fn sub(self, other: MotorDual) -> MultiVector {
1646 MultiVector { groups: MultiVectorGroups { g0: self.group0() - swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]), g1: self.group1() - swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
1647 }
1648}
1649
1650impl SubAssign<MotorDual> for MultiVector {
1651 fn sub_assign(&mut self, other: MotorDual) {
1652 *self = (*self).sub(other);
1653 }
1654}
1655
1656impl GeometricProduct<MotorDual> for MultiVector {
1657 type Output = MultiVector;
1658
1659 fn geometric_product(self, other: MotorDual) -> MultiVector {
1660 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 3, 2, 2) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + swizzle!(self.group0(), 2, 2, 0, 0) * swizzle!(other.group0(), 3, 2, 3, 2), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 2, 3, 3) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 3, 2, 2) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * swizzle!(other.group0(), 1, 0, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) } }
1661 }
1662}
1663
1664impl RegressiveProduct<MotorDual> for MultiVector {
1665 type Output = MultiVector;
1666
1667 fn regressive_product(self, other: MotorDual) -> MultiVector {
1668 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]), g1: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group1(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
1669 }
1670}
1671
1672impl ScalarProduct<MotorDual> for MultiVector {
1673 type Output = f32;
1674
1675 fn scalar_product(self, other: MotorDual) -> f32 {
1676 self.group0()[2] * other.group0()[3] + self.group0()[3] * other.group0()[2]
1677 }
1678}
1679
1680impl SquaredMagnitude for MultiVector {
1681 type Output = f32;
1682
1683 fn squared_magnitude(self) -> f32 {
1684 self.scalar_product(self.reversal())
1685 }
1686}
1687
1688impl Magnitude for MultiVector {
1689 type Output = f32;
1690
1691 fn magnitude(self) -> f32 {
1692 self.squared_magnitude().sqrt()
1693 }
1694}
1695
1696impl Mul<f32> for MultiVector {
1697 type Output = MultiVector;
1698
1699 fn mul(self, other: f32) -> MultiVector {
1700 self.geometric_product(other)
1701 }
1702}
1703
1704impl MulAssign<f32> for MultiVector {
1705 fn mul_assign(&mut self, other: f32) {
1706 *self = (*self).mul(other);
1707 }
1708}
1709
1710impl Signum for MultiVector {
1711 type Output = MultiVector;
1712
1713 fn signum(self) -> MultiVector {
1714 self.geometric_product(1.0 / self.magnitude())
1715 }
1716}
1717
1718impl Inverse for MultiVector {
1719 type Output = MultiVector;
1720
1721 fn inverse(self) -> MultiVector {
1722 self.reversal().geometric_product(1.0 / self.squared_magnitude())
1723 }
1724}
1725
1726impl Zero for Rotor {
1727 fn zero() -> Self {
1728 Rotor { groups: RotorGroups { g0: Simd32x2::from(0.0) } }
1729 }
1730}
1731
1732impl One for Rotor {
1733 fn one() -> Self {
1734 Rotor { groups: RotorGroups { g0: Simd32x2::from([1.0, 0.0]) } }
1735 }
1736}
1737
1738impl Neg for Rotor {
1739 type Output = Rotor;
1740
1741 fn neg(self) -> Rotor {
1742 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
1743 }
1744}
1745
1746impl Automorphism for Rotor {
1747 type Output = Rotor;
1748
1749 fn automorphism(self) -> Rotor {
1750 Rotor { groups: RotorGroups { g0: self.group0() } }
1751 }
1752}
1753
1754impl Reversal for Rotor {
1755 type Output = Rotor;
1756
1757 fn reversal(self) -> Rotor {
1758 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from([1.0, -1.0]) } }
1759 }
1760}
1761
1762impl Conjugation for Rotor {
1763 type Output = Rotor;
1764
1765 fn conjugation(self) -> Rotor {
1766 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from([1.0, -1.0]) } }
1767 }
1768}
1769
1770impl Into<f32> for Rotor {
1771 fn into(self) -> f32 {
1772 self.group0()[0]
1773 }
1774}
1775
1776impl Add<f32> for Rotor {
1777 type Output = Rotor;
1778
1779 fn add(self, other: f32) -> Rotor {
1780 Rotor { groups: RotorGroups { g0: self.group0() + Simd32x2::from(other) * Simd32x2::from([1.0, 0.0]) } }
1781 }
1782}
1783
1784impl AddAssign<f32> for Rotor {
1785 fn add_assign(&mut self, other: f32) {
1786 *self = (*self).add(other);
1787 }
1788}
1789
1790impl Sub<f32> for Rotor {
1791 type Output = Rotor;
1792
1793 fn sub(self, other: f32) -> Rotor {
1794 Rotor { groups: RotorGroups { g0: self.group0() - Simd32x2::from(other) * Simd32x2::from([1.0, 0.0]) } }
1795 }
1796}
1797
1798impl SubAssign<f32> for Rotor {
1799 fn sub_assign(&mut self, other: f32) {
1800 *self = (*self).sub(other);
1801 }
1802}
1803
1804impl GeometricProduct<f32> for Rotor {
1805 type Output = Rotor;
1806
1807 fn geometric_product(self, other: f32) -> Rotor {
1808 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1809 }
1810}
1811
1812impl OuterProduct<f32> for Rotor {
1813 type Output = Rotor;
1814
1815 fn outer_product(self, other: f32) -> Rotor {
1816 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1817 }
1818}
1819
1820impl InnerProduct<f32> for Rotor {
1821 type Output = Rotor;
1822
1823 fn inner_product(self, other: f32) -> Rotor {
1824 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1825 }
1826}
1827
1828impl LeftContraction<f32> for Rotor {
1829 type Output = f32;
1830
1831 fn left_contraction(self, other: f32) -> f32 {
1832 self.group0()[0] * other
1833 }
1834}
1835
1836impl RightContraction<f32> for Rotor {
1837 type Output = Rotor;
1838
1839 fn right_contraction(self, other: f32) -> Rotor {
1840 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1841 }
1842}
1843
1844impl ScalarProduct<f32> for Rotor {
1845 type Output = f32;
1846
1847 fn scalar_product(self, other: f32) -> f32 {
1848 self.group0()[0] * other
1849 }
1850}
1851
1852impl Add<MultiVector> for Rotor {
1853 type Output = MultiVector;
1854
1855 fn add(self, other: MultiVector) -> MultiVector {
1856 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + other.group0(), g1: other.group1() } }
1857 }
1858}
1859
1860impl Sub<MultiVector> for Rotor {
1861 type Output = MultiVector;
1862
1863 fn sub(self, other: MultiVector) -> MultiVector {
1864 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - other.group0(), g1: Simd32x4::from(0.0) - other.group1() } }
1865 }
1866}
1867
1868impl GeometricProduct<MultiVector> for Rotor {
1869 type Output = MultiVector;
1870
1871 fn geometric_product(self, other: MultiVector) -> MultiVector {
1872 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
1873 }
1874}
1875
1876impl OuterProduct<MultiVector> for Rotor {
1877 type Output = MultiVector;
1878
1879 fn outer_product(self, other: MultiVector) -> MultiVector {
1880 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) } }
1881 }
1882}
1883
1884impl InnerProduct<MultiVector> for Rotor {
1885 type Output = MultiVector;
1886
1887 fn inner_product(self, other: MultiVector) -> MultiVector {
1888 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
1889 }
1890}
1891
1892impl LeftContraction<MultiVector> for Rotor {
1893 type Output = MultiVector;
1894
1895 fn left_contraction(self, other: MultiVector) -> MultiVector {
1896 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
1897 }
1898}
1899
1900impl ScalarProduct<MultiVector> for Rotor {
1901 type Output = f32;
1902
1903 fn scalar_product(self, other: MultiVector) -> f32 {
1904 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
1905 }
1906}
1907
1908impl Add<Rotor> for Rotor {
1909 type Output = Rotor;
1910
1911 fn add(self, other: Rotor) -> Rotor {
1912 Rotor { groups: RotorGroups { g0: self.group0() + other.group0() } }
1913 }
1914}
1915
1916impl AddAssign<Rotor> for Rotor {
1917 fn add_assign(&mut self, other: Rotor) {
1918 *self = (*self).add(other);
1919 }
1920}
1921
1922impl Sub<Rotor> for Rotor {
1923 type Output = Rotor;
1924
1925 fn sub(self, other: Rotor) -> Rotor {
1926 Rotor { groups: RotorGroups { g0: self.group0() - other.group0() } }
1927 }
1928}
1929
1930impl SubAssign<Rotor> for Rotor {
1931 fn sub_assign(&mut self, other: Rotor) {
1932 *self = (*self).sub(other);
1933 }
1934}
1935
1936impl Mul<Rotor> for Rotor {
1937 type Output = Rotor;
1938
1939 fn mul(self, other: Rotor) -> Rotor {
1940 Rotor { groups: RotorGroups { g0: self.group0() * other.group0() } }
1941 }
1942}
1943
1944impl MulAssign<Rotor> for Rotor {
1945 fn mul_assign(&mut self, other: Rotor) {
1946 *self = (*self).mul(other);
1947 }
1948}
1949
1950impl Div<Rotor> for Rotor {
1951 type Output = Rotor;
1952
1953 fn div(self, other: Rotor) -> Rotor {
1954 Rotor { groups: RotorGroups { g0: Simd32x2::from([self.group0()[0], self.group0()[1]]) * Simd32x2::from([1.0, 1.0]) / Simd32x2::from([other.group0()[0], other.group0()[1]]) * Simd32x2::from([1.0, 1.0]) } }
1955 }
1956}
1957
1958impl DivAssign<Rotor> for Rotor {
1959 fn div_assign(&mut self, other: Rotor) {
1960 *self = (*self).div(other);
1961 }
1962}
1963
1964impl GeometricProduct<Rotor> for Rotor {
1965 type Output = Rotor;
1966
1967 fn geometric_product(self, other: Rotor) -> Rotor {
1968 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 1.0]) } }
1969 }
1970}
1971
1972impl OuterProduct<Rotor> for Rotor {
1973 type Output = Rotor;
1974
1975 fn outer_product(self, other: Rotor) -> Rotor {
1976 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x2::from(other.group0()[0]) * Simd32x2::from([0.0, 1.0]) } }
1977 }
1978}
1979
1980impl InnerProduct<Rotor> for Rotor {
1981 type Output = Rotor;
1982
1983 fn inner_product(self, other: Rotor) -> Rotor {
1984 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 1.0]) } }
1985 }
1986}
1987
1988impl LeftContraction<Rotor> for Rotor {
1989 type Output = Rotor;
1990
1991 fn left_contraction(self, other: Rotor) -> Rotor {
1992 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 1, 0) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 0.0]) } }
1993 }
1994}
1995
1996impl RightContraction<Rotor> for Rotor {
1997 type Output = Rotor;
1998
1999 fn right_contraction(self, other: Rotor) -> Rotor {
2000 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 1.0]) + Simd32x2::from(self.group0()[0]) * Simd32x2::from(other.group0()[0]) * Simd32x2::from([1.0, 0.0]) } }
2001 }
2002}
2003
2004impl ScalarProduct<Rotor> for Rotor {
2005 type Output = f32;
2006
2007 fn scalar_product(self, other: Rotor) -> f32 {
2008 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
2009 }
2010}
2011
2012impl Add<Point> for Rotor {
2013 type Output = Motor;
2014
2015 fn add(self, other: Point) -> Motor {
2016 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
2017 }
2018}
2019
2020impl Sub<Point> for Rotor {
2021 type Output = Motor;
2022
2023 fn sub(self, other: Point) -> Motor {
2024 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
2025 }
2026}
2027
2028impl GeometricProduct<Point> for Rotor {
2029 type Output = Motor;
2030
2031 fn geometric_product(self, other: Point) -> Motor {
2032 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
2033 }
2034}
2035
2036impl OuterProduct<Point> for Rotor {
2037 type Output = Point;
2038
2039 fn outer_product(self, other: Point) -> Point {
2040 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2041 }
2042}
2043
2044impl InnerProduct<Point> for Rotor {
2045 type Output = Motor;
2046
2047 fn inner_product(self, other: Point) -> Motor {
2048 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2049 }
2050}
2051
2052impl LeftContraction<Point> for Rotor {
2053 type Output = Motor;
2054
2055 fn left_contraction(self, other: Point) -> Motor {
2056 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2057 }
2058}
2059
2060impl RightContraction<Point> for Rotor {
2061 type Output = f32;
2062
2063 fn right_contraction(self, other: Point) -> f32 {
2064 0.0 - self.group0()[1] * other.group0()[0]
2065 }
2066}
2067
2068impl ScalarProduct<Point> for Rotor {
2069 type Output = f32;
2070
2071 fn scalar_product(self, other: Point) -> f32 {
2072 0.0 - self.group0()[1] * other.group0()[0]
2073 }
2074}
2075
2076impl Add<IdealPoint> for Rotor {
2077 type Output = Motor;
2078
2079 fn add(self, other: IdealPoint) -> Motor {
2080 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
2081 }
2082}
2083
2084impl Sub<IdealPoint> for Rotor {
2085 type Output = Motor;
2086
2087 fn sub(self, other: IdealPoint) -> Motor {
2088 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
2089 }
2090}
2091
2092impl GeometricProduct<IdealPoint> for Rotor {
2093 type Output = IdealPoint;
2094
2095 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
2096 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 1.0]) } }
2097 }
2098}
2099
2100impl OuterProduct<IdealPoint> for Rotor {
2101 type Output = IdealPoint;
2102
2103 fn outer_product(self, other: IdealPoint) -> IdealPoint {
2104 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
2105 }
2106}
2107
2108impl InnerProduct<IdealPoint> for Rotor {
2109 type Output = IdealPoint;
2110
2111 fn inner_product(self, other: IdealPoint) -> IdealPoint {
2112 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
2113 }
2114}
2115
2116impl LeftContraction<IdealPoint> for Rotor {
2117 type Output = IdealPoint;
2118
2119 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
2120 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
2121 }
2122}
2123
2124impl GeometricProduct<Plane> for Rotor {
2125 type Output = MotorDual;
2126
2127 fn geometric_product(self, other: Plane) -> MotorDual {
2128 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
2129 }
2130}
2131
2132impl RegressiveProduct<Plane> for Rotor {
2133 type Output = f32;
2134
2135 fn regressive_product(self, other: Plane) -> f32 {
2136 self.group0()[1] * other.group0()[0]
2137 }
2138}
2139
2140impl OuterProduct<Plane> for Rotor {
2141 type Output = MotorDual;
2142
2143 fn outer_product(self, other: Plane) -> MotorDual {
2144 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
2145 }
2146}
2147
2148impl InnerProduct<Plane> for Rotor {
2149 type Output = Plane;
2150
2151 fn inner_product(self, other: Plane) -> Plane {
2152 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([0.0, -1.0, 1.0]) } }
2153 }
2154}
2155
2156impl LeftContraction<Plane> for Rotor {
2157 type Output = Plane;
2158
2159 fn left_contraction(self, other: Plane) -> Plane {
2160 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2161 }
2162}
2163
2164impl Add<Translator> for Rotor {
2165 type Output = Motor;
2166
2167 fn add(self, other: Translator) -> Motor {
2168 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
2169 }
2170}
2171
2172impl Sub<Translator> for Rotor {
2173 type Output = Motor;
2174
2175 fn sub(self, other: Translator) -> Motor {
2176 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
2177 }
2178}
2179
2180impl GeometricProduct<Translator> for Rotor {
2181 type Output = Motor;
2182
2183 fn geometric_product(self, other: Translator) -> Motor {
2184 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
2185 }
2186}
2187
2188impl OuterProduct<Translator> for Rotor {
2189 type Output = Motor;
2190
2191 fn outer_product(self, other: Translator) -> Motor {
2192 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
2193 }
2194}
2195
2196impl InnerProduct<Translator> for Rotor {
2197 type Output = Motor;
2198
2199 fn inner_product(self, other: Translator) -> Motor {
2200 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
2201 }
2202}
2203
2204impl LeftContraction<Translator> for Rotor {
2205 type Output = Translator;
2206
2207 fn left_contraction(self, other: Translator) -> Translator {
2208 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2209 }
2210}
2211
2212impl RightContraction<Translator> for Rotor {
2213 type Output = Rotor;
2214
2215 fn right_contraction(self, other: Translator) -> Rotor {
2216 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
2217 }
2218}
2219
2220impl ScalarProduct<Translator> for Rotor {
2221 type Output = f32;
2222
2223 fn scalar_product(self, other: Translator) -> f32 {
2224 self.group0()[0] * other.group0()[0]
2225 }
2226}
2227
2228impl Add<Motor> for Rotor {
2229 type Output = Motor;
2230
2231 fn add(self, other: Motor) -> Motor {
2232 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + other.group0() } }
2233 }
2234}
2235
2236impl Sub<Motor> for Rotor {
2237 type Output = Motor;
2238
2239 fn sub(self, other: Motor) -> Motor {
2240 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - other.group0() } }
2241 }
2242}
2243
2244impl GeometricProduct<Motor> for Rotor {
2245 type Output = Motor;
2246
2247 fn geometric_product(self, other: Motor) -> Motor {
2248 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
2249 }
2250}
2251
2252impl OuterProduct<Motor> for Rotor {
2253 type Output = Motor;
2254
2255 fn outer_product(self, other: Motor) -> Motor {
2256 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) } }
2257 }
2258}
2259
2260impl InnerProduct<Motor> for Rotor {
2261 type Output = Motor;
2262
2263 fn inner_product(self, other: Motor) -> Motor {
2264 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[1], self.group0()[1], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) } }
2265 }
2266}
2267
2268impl LeftContraction<Motor> for Rotor {
2269 type Output = Motor;
2270
2271 fn left_contraction(self, other: Motor) -> Motor {
2272 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
2273 }
2274}
2275
2276impl RightContraction<Motor> for Rotor {
2277 type Output = Rotor;
2278
2279 fn right_contraction(self, other: Motor) -> Rotor {
2280 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[1]) * Simd32x2::from([other.group0()[1], other.group0()[0]]) * Simd32x2::from([-1.0, 1.0]) + Simd32x2::from(self.group0()[0]) * Simd32x2::from(other.group0()[0]) * Simd32x2::from([1.0, 0.0]) } }
2281 }
2282}
2283
2284impl ScalarProduct<Motor> for Rotor {
2285 type Output = f32;
2286
2287 fn scalar_product(self, other: Motor) -> f32 {
2288 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
2289 }
2290}
2291
2292impl GeometricProduct<MotorDual> for Rotor {
2293 type Output = MotorDual;
2294
2295 fn geometric_product(self, other: MotorDual) -> MotorDual {
2296 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
2297 }
2298}
2299
2300impl RegressiveProduct<MotorDual> for Rotor {
2301 type Output = Rotor;
2302
2303 fn regressive_product(self, other: MotorDual) -> Rotor {
2304 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[1]) * Simd32x2::from([other.group0()[1], other.group0()[0]]) + Simd32x2::from(self.group0()[0]) * Simd32x2::from(other.group0()[0]) * Simd32x2::from([1.0, 0.0]) } }
2305 }
2306}
2307
2308impl OuterProduct<MotorDual> for Rotor {
2309 type Output = MotorDual;
2310
2311 fn outer_product(self, other: MotorDual) -> MotorDual {
2312 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2313 }
2314}
2315
2316impl InnerProduct<MotorDual> for Rotor {
2317 type Output = MotorDual;
2318
2319 fn inner_product(self, other: MotorDual) -> MotorDual {
2320 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) } }
2321 }
2322}
2323
2324impl LeftContraction<MotorDual> for Rotor {
2325 type Output = MotorDual;
2326
2327 fn left_contraction(self, other: MotorDual) -> MotorDual {
2328 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) } }
2329 }
2330}
2331
2332impl SquaredMagnitude for Rotor {
2333 type Output = f32;
2334
2335 fn squared_magnitude(self) -> f32 {
2336 self.scalar_product(self.reversal())
2337 }
2338}
2339
2340impl Magnitude for Rotor {
2341 type Output = f32;
2342
2343 fn magnitude(self) -> f32 {
2344 self.squared_magnitude().sqrt()
2345 }
2346}
2347
2348impl Mul<f32> for Rotor {
2349 type Output = Rotor;
2350
2351 fn mul(self, other: f32) -> Rotor {
2352 self.geometric_product(other)
2353 }
2354}
2355
2356impl MulAssign<f32> for Rotor {
2357 fn mul_assign(&mut self, other: f32) {
2358 *self = (*self).mul(other);
2359 }
2360}
2361
2362impl Signum for Rotor {
2363 type Output = Rotor;
2364
2365 fn signum(self) -> Rotor {
2366 self.geometric_product(1.0 / self.magnitude())
2367 }
2368}
2369
2370impl Inverse for Rotor {
2371 type Output = Rotor;
2372
2373 fn inverse(self) -> Rotor {
2374 self.reversal().geometric_product(1.0 / self.squared_magnitude())
2375 }
2376}
2377
2378impl Zero for Point {
2379 fn zero() -> Self {
2380 Point { groups: PointGroups { g0: Simd32x3::from(0.0) } }
2381 }
2382}
2383
2384impl One for Point {
2385 fn one() -> Self {
2386 Point { groups: PointGroups { g0: Simd32x3::from(0.0) } }
2387 }
2388}
2389
2390impl Neg for Point {
2391 type Output = Point;
2392
2393 fn neg(self) -> Point {
2394 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
2395 }
2396}
2397
2398impl Automorphism for Point {
2399 type Output = Point;
2400
2401 fn automorphism(self) -> Point {
2402 Point { groups: PointGroups { g0: self.group0() } }
2403 }
2404}
2405
2406impl Reversal for Point {
2407 type Output = Point;
2408
2409 fn reversal(self) -> Point {
2410 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
2411 }
2412}
2413
2414impl Conjugation for Point {
2415 type Output = Point;
2416
2417 fn conjugation(self) -> Point {
2418 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
2419 }
2420}
2421
2422impl Dual for Point {
2423 type Output = Plane;
2424
2425 fn dual(self) -> Plane {
2426 Plane { groups: PlaneGroups { g0: self.group0() } }
2427 }
2428}
2429
2430impl Add<f32> for Point {
2431 type Output = Motor;
2432
2433 fn add(self, other: f32) -> Motor {
2434 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2435 }
2436}
2437
2438impl Sub<f32> for Point {
2439 type Output = Motor;
2440
2441 fn sub(self, other: f32) -> Motor {
2442 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2443 }
2444}
2445
2446impl GeometricProduct<f32> for Point {
2447 type Output = Point;
2448
2449 fn geometric_product(self, other: f32) -> Point {
2450 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2451 }
2452}
2453
2454impl OuterProduct<f32> for Point {
2455 type Output = Point;
2456
2457 fn outer_product(self, other: f32) -> Point {
2458 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2459 }
2460}
2461
2462impl InnerProduct<f32> for Point {
2463 type Output = Point;
2464
2465 fn inner_product(self, other: f32) -> Point {
2466 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2467 }
2468}
2469
2470impl RightContraction<f32> for Point {
2471 type Output = Point;
2472
2473 fn right_contraction(self, other: f32) -> Point {
2474 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2475 }
2476}
2477
2478impl Add<MultiVector> for Point {
2479 type Output = MultiVector;
2480
2481 fn add(self, other: MultiVector) -> MultiVector {
2482 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + other.group0(), g1: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group1() } }
2483 }
2484}
2485
2486impl Sub<MultiVector> for Point {
2487 type Output = MultiVector;
2488
2489 fn sub(self, other: MultiVector) -> MultiVector {
2490 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) - other.group0(), g1: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group1() } }
2491 }
2492}
2493
2494impl GeometricProduct<MultiVector> for Point {
2495 type Output = MultiVector;
2496
2497 fn geometric_product(self, other: MultiVector) -> MultiVector {
2498 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2499 }
2500}
2501
2502impl ScalarProduct<MultiVector> for Point {
2503 type Output = f32;
2504
2505 fn scalar_product(self, other: MultiVector) -> f32 {
2506 0.0 - self.group0()[0] * other.group0()[1]
2507 }
2508}
2509
2510impl Add<Rotor> for Point {
2511 type Output = Motor;
2512
2513 fn add(self, other: Rotor) -> Motor {
2514 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
2515 }
2516}
2517
2518impl Sub<Rotor> for Point {
2519 type Output = Motor;
2520
2521 fn sub(self, other: Rotor) -> Motor {
2522 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
2523 }
2524}
2525
2526impl GeometricProduct<Rotor> for Point {
2527 type Output = Motor;
2528
2529 fn geometric_product(self, other: Rotor) -> Motor {
2530 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) } }
2531 }
2532}
2533
2534impl OuterProduct<Rotor> for Point {
2535 type Output = Point;
2536
2537 fn outer_product(self, other: Rotor) -> Point {
2538 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2539 }
2540}
2541
2542impl InnerProduct<Rotor> for Point {
2543 type Output = Motor;
2544
2545 fn inner_product(self, other: Rotor) -> Motor {
2546 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[0], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2547 }
2548}
2549
2550impl LeftContraction<Rotor> for Point {
2551 type Output = f32;
2552
2553 fn left_contraction(self, other: Rotor) -> f32 {
2554 0.0 - self.group0()[0] * other.group0()[1]
2555 }
2556}
2557
2558impl RightContraction<Rotor> for Point {
2559 type Output = Motor;
2560
2561 fn right_contraction(self, other: Rotor) -> Motor {
2562 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[0], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2563 }
2564}
2565
2566impl ScalarProduct<Rotor> for Point {
2567 type Output = f32;
2568
2569 fn scalar_product(self, other: Rotor) -> f32 {
2570 0.0 - self.group0()[0] * other.group0()[1]
2571 }
2572}
2573
2574impl Add<Point> for Point {
2575 type Output = Point;
2576
2577 fn add(self, other: Point) -> Point {
2578 Point { groups: PointGroups { g0: self.group0() + other.group0() } }
2579 }
2580}
2581
2582impl AddAssign<Point> for Point {
2583 fn add_assign(&mut self, other: Point) {
2584 *self = (*self).add(other);
2585 }
2586}
2587
2588impl Sub<Point> for Point {
2589 type Output = Point;
2590
2591 fn sub(self, other: Point) -> Point {
2592 Point { groups: PointGroups { g0: self.group0() - other.group0() } }
2593 }
2594}
2595
2596impl SubAssign<Point> for Point {
2597 fn sub_assign(&mut self, other: Point) {
2598 *self = (*self).sub(other);
2599 }
2600}
2601
2602impl Mul<Point> for Point {
2603 type Output = Point;
2604
2605 fn mul(self, other: Point) -> Point {
2606 Point { groups: PointGroups { g0: self.group0() * other.group0() } }
2607 }
2608}
2609
2610impl MulAssign<Point> for Point {
2611 fn mul_assign(&mut self, other: Point) {
2612 *self = (*self).mul(other);
2613 }
2614}
2615
2616impl Div<Point> for Point {
2617 type Output = Point;
2618
2619 fn div(self, other: Point) -> Point {
2620 Point { groups: PointGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) / Simd32x3::from([other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) } }
2621 }
2622}
2623
2624impl DivAssign<Point> for Point {
2625 fn div_assign(&mut self, other: Point) {
2626 *self = (*self).div(other);
2627 }
2628}
2629
2630impl GeometricProduct<Point> for Point {
2631 type Output = Translator;
2632
2633 fn geometric_product(self, other: Point) -> Translator {
2634 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([-1.0, -1.0, 1.0]) + swizzle!(self.group0(), 0, 2, 1) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([0.0, 1.0, -1.0]) } }
2635 }
2636}
2637
2638impl RegressiveProduct<Point> for Point {
2639 type Output = Plane;
2640
2641 fn regressive_product(self, other: Point) -> Plane {
2642 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([0.0, 1.0, -1.0]) } }
2643 }
2644}
2645
2646impl InnerProduct<Point> for Point {
2647 type Output = f32;
2648
2649 fn inner_product(self, other: Point) -> f32 {
2650 0.0 - self.group0()[0] * other.group0()[0]
2651 }
2652}
2653
2654impl LeftContraction<Point> for Point {
2655 type Output = f32;
2656
2657 fn left_contraction(self, other: Point) -> f32 {
2658 0.0 - self.group0()[0] * other.group0()[0]
2659 }
2660}
2661
2662impl RightContraction<Point> for Point {
2663 type Output = f32;
2664
2665 fn right_contraction(self, other: Point) -> f32 {
2666 0.0 - self.group0()[0] * other.group0()[0]
2667 }
2668}
2669
2670impl ScalarProduct<Point> for Point {
2671 type Output = f32;
2672
2673 fn scalar_product(self, other: Point) -> f32 {
2674 0.0 - self.group0()[0] * other.group0()[0]
2675 }
2676}
2677
2678impl Into<IdealPoint> for Point {
2679 fn into(self) -> IdealPoint {
2680 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[1], self.group0()[2]]) } }
2681 }
2682}
2683
2684impl Add<IdealPoint> for Point {
2685 type Output = Point;
2686
2687 fn add(self, other: IdealPoint) -> Point {
2688 Point { groups: PointGroups { g0: self.group0() + Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
2689 }
2690}
2691
2692impl AddAssign<IdealPoint> for Point {
2693 fn add_assign(&mut self, other: IdealPoint) {
2694 *self = (*self).add(other);
2695 }
2696}
2697
2698impl Sub<IdealPoint> for Point {
2699 type Output = Point;
2700
2701 fn sub(self, other: IdealPoint) -> Point {
2702 Point { groups: PointGroups { g0: self.group0() - Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
2703 }
2704}
2705
2706impl SubAssign<IdealPoint> for Point {
2707 fn sub_assign(&mut self, other: IdealPoint) {
2708 *self = (*self).sub(other);
2709 }
2710}
2711
2712impl GeometricProduct<IdealPoint> for Point {
2713 type Output = IdealPoint;
2714
2715 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
2716 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 1.0]) } }
2717 }
2718}
2719
2720impl RegressiveProduct<IdealPoint> for Point {
2721 type Output = Plane;
2722
2723 fn regressive_product(self, other: IdealPoint) -> Plane {
2724 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * Simd32x3::from([other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x3::from([-1.0, 1.0, -1.0]) } }
2725 }
2726}
2727
2728impl GeometricProduct<Plane> for Point {
2729 type Output = MotorDual;
2730
2731 fn geometric_product(self, other: Plane) -> MotorDual {
2732 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) } }
2733 }
2734}
2735
2736impl RegressiveProduct<Plane> for Point {
2737 type Output = f32;
2738
2739 fn regressive_product(self, other: Plane) -> f32 {
2740 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
2741 }
2742}
2743
2744impl InnerProduct<Plane> for Point {
2745 type Output = Plane;
2746
2747 fn inner_product(self, other: Plane) -> Plane {
2748 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([-1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * swizzle!(other.group0(), 2, 2, 1) * Simd32x3::from([1.0, -1.0, 1.0]) } }
2749 }
2750}
2751
2752impl RightContraction<Plane> for Point {
2753 type Output = Plane;
2754
2755 fn right_contraction(self, other: Plane) -> Plane {
2756 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([-1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * swizzle!(other.group0(), 2, 2, 1) * Simd32x3::from([1.0, -1.0, 1.0]) } }
2757 }
2758}
2759
2760impl Add<Translator> for Point {
2761 type Output = Motor;
2762
2763 fn add(self, other: Translator) -> Motor {
2764 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
2765 }
2766}
2767
2768impl Sub<Translator> for Point {
2769 type Output = Motor;
2770
2771 fn sub(self, other: Translator) -> Motor {
2772 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
2773 }
2774}
2775
2776impl GeometricProduct<Translator> for Point {
2777 type Output = Point;
2778
2779 fn geometric_product(self, other: Translator) -> Point {
2780 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([1.0, -1.0, 1.0]) + self.group0() * Simd32x3::from(other.group0()[0]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
2781 }
2782}
2783
2784impl RegressiveProduct<Translator> for Point {
2785 type Output = Plane;
2786
2787 fn regressive_product(self, other: Translator) -> Plane {
2788 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * swizzle!(other.group0(), 2, 2, 1) * Simd32x3::from([-1.0, 1.0, -1.0]) } }
2789 }
2790}
2791
2792impl OuterProduct<Translator> for Point {
2793 type Output = Point;
2794
2795 fn outer_product(self, other: Translator) -> Point {
2796 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2797 }
2798}
2799
2800impl InnerProduct<Translator> for Point {
2801 type Output = Point;
2802
2803 fn inner_product(self, other: Translator) -> Point {
2804 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2805 }
2806}
2807
2808impl RightContraction<Translator> for Point {
2809 type Output = Point;
2810
2811 fn right_contraction(self, other: Translator) -> Point {
2812 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2813 }
2814}
2815
2816impl Add<Motor> for Point {
2817 type Output = Motor;
2818
2819 fn add(self, other: Motor) -> Motor {
2820 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group0() } }
2821 }
2822}
2823
2824impl Sub<Motor> for Point {
2825 type Output = Motor;
2826
2827 fn sub(self, other: Motor) -> Motor {
2828 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group0() } }
2829 }
2830}
2831
2832impl GeometricProduct<Motor> for Point {
2833 type Output = Motor;
2834
2835 fn geometric_product(self, other: Motor) -> Motor {
2836 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
2837 }
2838}
2839
2840impl RegressiveProduct<Motor> for Point {
2841 type Output = Plane;
2842
2843 fn regressive_product(self, other: Motor) -> Plane {
2844 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[1]]) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x3::from([0.0, 1.0, -1.0]) } }
2845 }
2846}
2847
2848impl OuterProduct<Motor> for Point {
2849 type Output = Point;
2850
2851 fn outer_product(self, other: Motor) -> Point {
2852 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2853 }
2854}
2855
2856impl InnerProduct<Motor> for Point {
2857 type Output = Motor;
2858
2859 fn inner_product(self, other: Motor) -> Motor {
2860 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2861 }
2862}
2863
2864impl LeftContraction<Motor> for Point {
2865 type Output = f32;
2866
2867 fn left_contraction(self, other: Motor) -> f32 {
2868 0.0 - self.group0()[0] * other.group0()[1]
2869 }
2870}
2871
2872impl RightContraction<Motor> for Point {
2873 type Output = Motor;
2874
2875 fn right_contraction(self, other: Motor) -> Motor {
2876 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2877 }
2878}
2879
2880impl ScalarProduct<Motor> for Point {
2881 type Output = f32;
2882
2883 fn scalar_product(self, other: Motor) -> f32 {
2884 0.0 - self.group0()[0] * other.group0()[1]
2885 }
2886}
2887
2888impl GeometricProduct<MotorDual> for Point {
2889 type Output = MotorDual;
2890
2891 fn geometric_product(self, other: MotorDual) -> MotorDual {
2892 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 3, 3) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 2, 3, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
2893 }
2894}
2895
2896impl RegressiveProduct<MotorDual> for Point {
2897 type Output = Motor;
2898
2899 fn regressive_product(self, other: MotorDual) -> Motor {
2900 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
2901 }
2902}
2903
2904impl InnerProduct<MotorDual> for Point {
2905 type Output = Plane;
2906
2907 fn inner_product(self, other: MotorDual) -> Plane {
2908 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x3::from([-1.0, -1.0, 1.0]) + Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([-1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 0.0]) } }
2909 }
2910}
2911
2912impl RightContraction<MotorDual> for Point {
2913 type Output = Plane;
2914
2915 fn right_contraction(self, other: MotorDual) -> Plane {
2916 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([-1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 1.0]) } }
2917 }
2918}
2919
2920impl SquaredMagnitude for Point {
2921 type Output = f32;
2922
2923 fn squared_magnitude(self) -> f32 {
2924 self.scalar_product(self.reversal())
2925 }
2926}
2927
2928impl Magnitude for Point {
2929 type Output = f32;
2930
2931 fn magnitude(self) -> f32 {
2932 self.squared_magnitude().sqrt()
2933 }
2934}
2935
2936impl Mul<f32> for Point {
2937 type Output = Point;
2938
2939 fn mul(self, other: f32) -> Point {
2940 self.geometric_product(other)
2941 }
2942}
2943
2944impl MulAssign<f32> for Point {
2945 fn mul_assign(&mut self, other: f32) {
2946 *self = (*self).mul(other);
2947 }
2948}
2949
2950impl Signum for Point {
2951 type Output = Point;
2952
2953 fn signum(self) -> Point {
2954 self.geometric_product(1.0 / self.magnitude())
2955 }
2956}
2957
2958impl Inverse for Point {
2959 type Output = Point;
2960
2961 fn inverse(self) -> Point {
2962 self.reversal().geometric_product(1.0 / self.squared_magnitude())
2963 }
2964}
2965
2966impl Zero for IdealPoint {
2967 fn zero() -> Self {
2968 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(0.0) } }
2969 }
2970}
2971
2972impl One for IdealPoint {
2973 fn one() -> Self {
2974 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(0.0) } }
2975 }
2976}
2977
2978impl Neg for IdealPoint {
2979 type Output = IdealPoint;
2980
2981 fn neg(self) -> IdealPoint {
2982 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
2983 }
2984}
2985
2986impl Automorphism for IdealPoint {
2987 type Output = IdealPoint;
2988
2989 fn automorphism(self) -> IdealPoint {
2990 IdealPoint { groups: IdealPointGroups { g0: self.group0() } }
2991 }
2992}
2993
2994impl Reversal for IdealPoint {
2995 type Output = IdealPoint;
2996
2997 fn reversal(self) -> IdealPoint {
2998 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
2999 }
3000}
3001
3002impl Conjugation for IdealPoint {
3003 type Output = IdealPoint;
3004
3005 fn conjugation(self) -> IdealPoint {
3006 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
3007 }
3008}
3009
3010impl Add<f32> for IdealPoint {
3011 type Output = Translator;
3012
3013 fn add(self, other: f32) -> Translator {
3014 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) + Simd32x3::from(other) * Simd32x3::from([1.0, 0.0, 0.0]) } }
3015 }
3016}
3017
3018impl Sub<f32> for IdealPoint {
3019 type Output = Translator;
3020
3021 fn sub(self, other: f32) -> Translator {
3022 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) - Simd32x3::from(other) * Simd32x3::from([1.0, 0.0, 0.0]) } }
3023 }
3024}
3025
3026impl GeometricProduct<f32> for IdealPoint {
3027 type Output = IdealPoint;
3028
3029 fn geometric_product(self, other: f32) -> IdealPoint {
3030 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3031 }
3032}
3033
3034impl OuterProduct<f32> for IdealPoint {
3035 type Output = IdealPoint;
3036
3037 fn outer_product(self, other: f32) -> IdealPoint {
3038 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3039 }
3040}
3041
3042impl InnerProduct<f32> for IdealPoint {
3043 type Output = IdealPoint;
3044
3045 fn inner_product(self, other: f32) -> IdealPoint {
3046 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3047 }
3048}
3049
3050impl RightContraction<f32> for IdealPoint {
3051 type Output = IdealPoint;
3052
3053 fn right_contraction(self, other: f32) -> IdealPoint {
3054 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3055 }
3056}
3057
3058impl Add<MultiVector> for IdealPoint {
3059 type Output = MultiVector;
3060
3061 fn add(self, other: MultiVector) -> MultiVector {
3062 MultiVector { groups: MultiVectorGroups { g0: other.group0(), g1: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group1() } }
3063 }
3064}
3065
3066impl Sub<MultiVector> for IdealPoint {
3067 type Output = MultiVector;
3068
3069 fn sub(self, other: MultiVector) -> MultiVector {
3070 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group1() } }
3071 }
3072}
3073
3074impl Add<Rotor> for IdealPoint {
3075 type Output = Motor;
3076
3077 fn add(self, other: Rotor) -> Motor {
3078 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
3079 }
3080}
3081
3082impl Sub<Rotor> for IdealPoint {
3083 type Output = Motor;
3084
3085 fn sub(self, other: Rotor) -> Motor {
3086 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
3087 }
3088}
3089
3090impl GeometricProduct<Rotor> for IdealPoint {
3091 type Output = IdealPoint;
3092
3093 fn geometric_product(self, other: Rotor) -> IdealPoint {
3094 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() * Simd32x2::from([1.0, -1.0]) + Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) } }
3095 }
3096}
3097
3098impl OuterProduct<Rotor> for IdealPoint {
3099 type Output = IdealPoint;
3100
3101 fn outer_product(self, other: Rotor) -> IdealPoint {
3102 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3103 }
3104}
3105
3106impl InnerProduct<Rotor> for IdealPoint {
3107 type Output = IdealPoint;
3108
3109 fn inner_product(self, other: Rotor) -> IdealPoint {
3110 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3111 }
3112}
3113
3114impl RightContraction<Rotor> for IdealPoint {
3115 type Output = IdealPoint;
3116
3117 fn right_contraction(self, other: Rotor) -> IdealPoint {
3118 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3119 }
3120}
3121
3122impl Add<Point> for IdealPoint {
3123 type Output = Point;
3124
3125 fn add(self, other: Point) -> Point {
3126 Point { groups: PointGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) + other.group0() } }
3127 }
3128}
3129
3130impl Sub<Point> for IdealPoint {
3131 type Output = Point;
3132
3133 fn sub(self, other: Point) -> Point {
3134 Point { groups: PointGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) - other.group0() } }
3135 }
3136}
3137
3138impl GeometricProduct<Point> for IdealPoint {
3139 type Output = IdealPoint;
3140
3141 fn geometric_product(self, other: Point) -> IdealPoint {
3142 IdealPoint { groups: IdealPointGroups { g0: swizzle!(self.group0(), 1, 0) * Simd32x2::from(other.group0()[0]) * Simd32x2::from([1.0, -1.0]) } }
3143 }
3144}
3145
3146impl RegressiveProduct<Point> for IdealPoint {
3147 type Output = Plane;
3148
3149 fn regressive_product(self, other: Point) -> Plane {
3150 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) } }
3151 }
3152}
3153
3154impl Add<IdealPoint> for IdealPoint {
3155 type Output = IdealPoint;
3156
3157 fn add(self, other: IdealPoint) -> IdealPoint {
3158 IdealPoint { groups: IdealPointGroups { g0: self.group0() + other.group0() } }
3159 }
3160}
3161
3162impl AddAssign<IdealPoint> for IdealPoint {
3163 fn add_assign(&mut self, other: IdealPoint) {
3164 *self = (*self).add(other);
3165 }
3166}
3167
3168impl Sub<IdealPoint> for IdealPoint {
3169 type Output = IdealPoint;
3170
3171 fn sub(self, other: IdealPoint) -> IdealPoint {
3172 IdealPoint { groups: IdealPointGroups { g0: self.group0() - other.group0() } }
3173 }
3174}
3175
3176impl SubAssign<IdealPoint> for IdealPoint {
3177 fn sub_assign(&mut self, other: IdealPoint) {
3178 *self = (*self).sub(other);
3179 }
3180}
3181
3182impl Mul<IdealPoint> for IdealPoint {
3183 type Output = IdealPoint;
3184
3185 fn mul(self, other: IdealPoint) -> IdealPoint {
3186 IdealPoint { groups: IdealPointGroups { g0: self.group0() * other.group0() } }
3187 }
3188}
3189
3190impl MulAssign<IdealPoint> for IdealPoint {
3191 fn mul_assign(&mut self, other: IdealPoint) {
3192 *self = (*self).mul(other);
3193 }
3194}
3195
3196impl Div<IdealPoint> for IdealPoint {
3197 type Output = IdealPoint;
3198
3199 fn div(self, other: IdealPoint) -> IdealPoint {
3200 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[0], self.group0()[1]]) * Simd32x2::from([1.0, 1.0]) / Simd32x2::from([other.group0()[0], other.group0()[1]]) * Simd32x2::from([1.0, 1.0]) } }
3201 }
3202}
3203
3204impl DivAssign<IdealPoint> for IdealPoint {
3205 fn div_assign(&mut self, other: IdealPoint) {
3206 *self = (*self).div(other);
3207 }
3208}
3209
3210impl RegressiveProduct<Plane> for IdealPoint {
3211 type Output = f32;
3212
3213 fn regressive_product(self, other: Plane) -> f32 {
3214 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2]
3215 }
3216}
3217
3218impl Add<Translator> for IdealPoint {
3219 type Output = Translator;
3220
3221 fn add(self, other: Translator) -> Translator {
3222 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) + other.group0() } }
3223 }
3224}
3225
3226impl Sub<Translator> for IdealPoint {
3227 type Output = Translator;
3228
3229 fn sub(self, other: Translator) -> Translator {
3230 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) - other.group0() } }
3231 }
3232}
3233
3234impl GeometricProduct<Translator> for IdealPoint {
3235 type Output = IdealPoint;
3236
3237 fn geometric_product(self, other: Translator) -> IdealPoint {
3238 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3239 }
3240}
3241
3242impl OuterProduct<Translator> for IdealPoint {
3243 type Output = IdealPoint;
3244
3245 fn outer_product(self, other: Translator) -> IdealPoint {
3246 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3247 }
3248}
3249
3250impl InnerProduct<Translator> for IdealPoint {
3251 type Output = IdealPoint;
3252
3253 fn inner_product(self, other: Translator) -> IdealPoint {
3254 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3255 }
3256}
3257
3258impl RightContraction<Translator> for IdealPoint {
3259 type Output = IdealPoint;
3260
3261 fn right_contraction(self, other: Translator) -> IdealPoint {
3262 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3263 }
3264}
3265
3266impl Add<Motor> for IdealPoint {
3267 type Output = Motor;
3268
3269 fn add(self, other: Motor) -> Motor {
3270 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group0() } }
3271 }
3272}
3273
3274impl Sub<Motor> for IdealPoint {
3275 type Output = Motor;
3276
3277 fn sub(self, other: Motor) -> Motor {
3278 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[0], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group0() } }
3279 }
3280}
3281
3282impl GeometricProduct<Motor> for IdealPoint {
3283 type Output = IdealPoint;
3284
3285 fn geometric_product(self, other: Motor) -> IdealPoint {
3286 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * Simd32x2::from([other.group0()[0], other.group0()[1]]) * Simd32x2::from([1.0, -1.0]) + Simd32x2::from(self.group0()[1]) * Simd32x2::from([other.group0()[1], other.group0()[0]]) } }
3287 }
3288}
3289
3290impl RegressiveProduct<Motor> for IdealPoint {
3291 type Output = Plane;
3292
3293 fn regressive_product(self, other: Motor) -> Plane {
3294 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x3::from([-1.0, 0.0, 1.0]) } }
3295 }
3296}
3297
3298impl OuterProduct<Motor> for IdealPoint {
3299 type Output = IdealPoint;
3300
3301 fn outer_product(self, other: Motor) -> IdealPoint {
3302 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3303 }
3304}
3305
3306impl InnerProduct<Motor> for IdealPoint {
3307 type Output = IdealPoint;
3308
3309 fn inner_product(self, other: Motor) -> IdealPoint {
3310 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3311 }
3312}
3313
3314impl RightContraction<Motor> for IdealPoint {
3315 type Output = IdealPoint;
3316
3317 fn right_contraction(self, other: Motor) -> IdealPoint {
3318 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3319 }
3320}
3321
3322impl RegressiveProduct<MotorDual> for IdealPoint {
3323 type Output = Translator;
3324
3325 fn regressive_product(self, other: MotorDual) -> Translator {
3326 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x3::from([1.0, 1.0, 0.0]) } }
3327 }
3328}
3329
3330impl Mul<f32> for IdealPoint {
3331 type Output = IdealPoint;
3332
3333 fn mul(self, other: f32) -> IdealPoint {
3334 self.geometric_product(other)
3335 }
3336}
3337
3338impl MulAssign<f32> for IdealPoint {
3339 fn mul_assign(&mut self, other: f32) {
3340 *self = (*self).mul(other);
3341 }
3342}
3343
3344impl Zero for Plane {
3345 fn zero() -> Self {
3346 Plane { groups: PlaneGroups { g0: Simd32x3::from(0.0) } }
3347 }
3348}
3349
3350impl One for Plane {
3351 fn one() -> Self {
3352 Plane { groups: PlaneGroups { g0: Simd32x3::from(0.0) } }
3353 }
3354}
3355
3356impl Neg for Plane {
3357 type Output = Plane;
3358
3359 fn neg(self) -> Plane {
3360 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3361 }
3362}
3363
3364impl Automorphism for Plane {
3365 type Output = Plane;
3366
3367 fn automorphism(self) -> Plane {
3368 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3369 }
3370}
3371
3372impl Reversal for Plane {
3373 type Output = Plane;
3374
3375 fn reversal(self) -> Plane {
3376 Plane { groups: PlaneGroups { g0: self.group0() } }
3377 }
3378}
3379
3380impl Conjugation for Plane {
3381 type Output = Plane;
3382
3383 fn conjugation(self) -> Plane {
3384 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3385 }
3386}
3387
3388impl Dual for Plane {
3389 type Output = Point;
3390
3391 fn dual(self) -> Point {
3392 Point { groups: PointGroups { g0: self.group0() } }
3393 }
3394}
3395
3396impl GeometricProduct<f32> for Plane {
3397 type Output = Plane;
3398
3399 fn geometric_product(self, other: f32) -> Plane {
3400 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3401 }
3402}
3403
3404impl OuterProduct<f32> for Plane {
3405 type Output = Plane;
3406
3407 fn outer_product(self, other: f32) -> Plane {
3408 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3409 }
3410}
3411
3412impl InnerProduct<f32> for Plane {
3413 type Output = Plane;
3414
3415 fn inner_product(self, other: f32) -> Plane {
3416 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3417 }
3418}
3419
3420impl RightContraction<f32> for Plane {
3421 type Output = Plane;
3422
3423 fn right_contraction(self, other: f32) -> Plane {
3424 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3425 }
3426}
3427
3428impl Add<MultiVector> for Plane {
3429 type Output = MultiVector;
3430
3431 fn add(self, other: MultiVector) -> MultiVector {
3432 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[2], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group0(), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group1() } }
3433 }
3434}
3435
3436impl Sub<MultiVector> for Plane {
3437 type Output = MultiVector;
3438
3439 fn sub(self, other: MultiVector) -> MultiVector {
3440 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[2], self.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group0(), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group1() } }
3441 }
3442}
3443
3444impl GeometricProduct<MultiVector> for Plane {
3445 type Output = MultiVector;
3446
3447 fn geometric_product(self, other: MultiVector) -> MultiVector {
3448 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 0, 1), g1: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 3, 2, 1, 0) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
3449 }
3450}
3451
3452impl ScalarProduct<MultiVector> for Plane {
3453 type Output = f32;
3454
3455 fn scalar_product(self, other: MultiVector) -> f32 {
3456 self.group0()[1] * other.group0()[3] + self.group0()[2] * other.group0()[2]
3457 }
3458}
3459
3460impl GeometricProduct<Rotor> for Plane {
3461 type Output = MotorDual;
3462
3463 fn geometric_product(self, other: Rotor) -> MotorDual {
3464 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
3465 }
3466}
3467
3468impl RegressiveProduct<Rotor> for Plane {
3469 type Output = f32;
3470
3471 fn regressive_product(self, other: Rotor) -> f32 {
3472 self.group0()[0] * other.group0()[1]
3473 }
3474}
3475
3476impl OuterProduct<Rotor> for Plane {
3477 type Output = MotorDual;
3478
3479 fn outer_product(self, other: Rotor) -> MotorDual {
3480 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[0], other.group0()[0]]) } }
3481 }
3482}
3483
3484impl InnerProduct<Rotor> for Plane {
3485 type Output = Plane;
3486
3487 fn inner_product(self, other: Rotor) -> Plane {
3488 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x3::from([0.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 1, 1) * Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([1.0, 1.0, -1.0]) } }
3489 }
3490}
3491
3492impl RightContraction<Rotor> for Plane {
3493 type Output = Plane;
3494
3495 fn right_contraction(self, other: Rotor) -> Plane {
3496 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3497 }
3498}
3499
3500impl GeometricProduct<Point> for Plane {
3501 type Output = MotorDual;
3502
3503 fn geometric_product(self, other: Point) -> MotorDual {
3504 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[0], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
3505 }
3506}
3507
3508impl RegressiveProduct<Point> for Plane {
3509 type Output = f32;
3510
3511 fn regressive_product(self, other: Point) -> f32 {
3512 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3513 }
3514}
3515
3516impl InnerProduct<Point> for Plane {
3517 type Output = Plane;
3518
3519 fn inner_product(self, other: Point) -> Plane {
3520 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([-1.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 1) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([1.0, 0.0, -1.0]) } }
3521 }
3522}
3523
3524impl LeftContraction<Point> for Plane {
3525 type Output = Plane;
3526
3527 fn left_contraction(self, other: Point) -> Plane {
3528 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([-1.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 1) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([1.0, 0.0, -1.0]) } }
3529 }
3530}
3531
3532impl RegressiveProduct<IdealPoint> for Plane {
3533 type Output = f32;
3534
3535 fn regressive_product(self, other: IdealPoint) -> f32 {
3536 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1]
3537 }
3538}
3539
3540impl Add<Plane> for Plane {
3541 type Output = Plane;
3542
3543 fn add(self, other: Plane) -> Plane {
3544 Plane { groups: PlaneGroups { g0: self.group0() + other.group0() } }
3545 }
3546}
3547
3548impl AddAssign<Plane> for Plane {
3549 fn add_assign(&mut self, other: Plane) {
3550 *self = (*self).add(other);
3551 }
3552}
3553
3554impl Sub<Plane> for Plane {
3555 type Output = Plane;
3556
3557 fn sub(self, other: Plane) -> Plane {
3558 Plane { groups: PlaneGroups { g0: self.group0() - other.group0() } }
3559 }
3560}
3561
3562impl SubAssign<Plane> for Plane {
3563 fn sub_assign(&mut self, other: Plane) {
3564 *self = (*self).sub(other);
3565 }
3566}
3567
3568impl Mul<Plane> for Plane {
3569 type Output = Plane;
3570
3571 fn mul(self, other: Plane) -> Plane {
3572 Plane { groups: PlaneGroups { g0: self.group0() * other.group0() } }
3573 }
3574}
3575
3576impl MulAssign<Plane> for Plane {
3577 fn mul_assign(&mut self, other: Plane) {
3578 *self = (*self).mul(other);
3579 }
3580}
3581
3582impl Div<Plane> for Plane {
3583 type Output = Plane;
3584
3585 fn div(self, other: Plane) -> Plane {
3586 Plane { groups: PlaneGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) / Simd32x3::from([other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) } }
3587 }
3588}
3589
3590impl DivAssign<Plane> for Plane {
3591 fn div_assign(&mut self, other: Plane) {
3592 *self = (*self).div(other);
3593 }
3594}
3595
3596impl GeometricProduct<Plane> for Plane {
3597 type Output = Motor;
3598
3599 fn geometric_product(self, other: Plane) -> Motor {
3600 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[0], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
3601 }
3602}
3603
3604impl OuterProduct<Plane> for Plane {
3605 type Output = Point;
3606
3607 fn outer_product(self, other: Plane) -> Point {
3608 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([0.0, 1.0, -1.0]) } }
3609 }
3610}
3611
3612impl InnerProduct<Plane> for Plane {
3613 type Output = f32;
3614
3615 fn inner_product(self, other: Plane) -> f32 {
3616 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3617 }
3618}
3619
3620impl LeftContraction<Plane> for Plane {
3621 type Output = f32;
3622
3623 fn left_contraction(self, other: Plane) -> f32 {
3624 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3625 }
3626}
3627
3628impl RightContraction<Plane> for Plane {
3629 type Output = f32;
3630
3631 fn right_contraction(self, other: Plane) -> f32 {
3632 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3633 }
3634}
3635
3636impl ScalarProduct<Plane> for Plane {
3637 type Output = f32;
3638
3639 fn scalar_product(self, other: Plane) -> f32 {
3640 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3641 }
3642}
3643
3644impl GeometricProduct<Translator> for Plane {
3645 type Output = MotorDual;
3646
3647 fn geometric_product(self, other: Translator) -> MotorDual {
3648 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) } }
3649 }
3650}
3651
3652impl RegressiveProduct<Translator> for Plane {
3653 type Output = f32;
3654
3655 fn regressive_product(self, other: Translator) -> f32 {
3656 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3657 }
3658}
3659
3660impl OuterProduct<Translator> for Plane {
3661 type Output = MotorDual;
3662
3663 fn outer_product(self, other: Translator) -> MotorDual {
3664 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[0]]) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[1], self.group0()[0]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 1.0, 0.0]) } }
3665 }
3666}
3667
3668impl InnerProduct<Translator> for Plane {
3669 type Output = Plane;
3670
3671 fn inner_product(self, other: Translator) -> Plane {
3672 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 2, 0, 2) * Simd32x3::from([1.0, 1.0, 0.0]) + Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 1, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([1.0, 0.0, 0.0]) } }
3673 }
3674}
3675
3676impl RightContraction<Translator> for Plane {
3677 type Output = Plane;
3678
3679 fn right_contraction(self, other: Translator) -> Plane {
3680 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3681 }
3682}
3683
3684impl GeometricProduct<Motor> for Plane {
3685 type Output = MotorDual;
3686
3687 fn geometric_product(self, other: Motor) -> MotorDual {
3688 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
3689 }
3690}
3691
3692impl RegressiveProduct<Motor> for Plane {
3693 type Output = f32;
3694
3695 fn regressive_product(self, other: Motor) -> f32 {
3696 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
3697 }
3698}
3699
3700impl OuterProduct<Motor> for Plane {
3701 type Output = MotorDual;
3702
3703 fn outer_product(self, other: Motor) -> MotorDual {
3704 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
3705 }
3706}
3707
3708impl InnerProduct<Motor> for Plane {
3709 type Output = Plane;
3710
3711 fn inner_product(self, other: Motor) -> Plane {
3712 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x3::from([1.0, 1.0, -1.0]) + Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x3::from([-1.0, 1.0, 1.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([1.0, 0.0, 0.0]) } }
3713 }
3714}
3715
3716impl LeftContraction<Motor> for Plane {
3717 type Output = Plane;
3718
3719 fn left_contraction(self, other: Motor) -> Plane {
3720 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([-1.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 1) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x3::from([1.0, 0.0, -1.0]) } }
3721 }
3722}
3723
3724impl RightContraction<Motor> for Plane {
3725 type Output = Plane;
3726
3727 fn right_contraction(self, other: Motor) -> Plane {
3728 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3729 }
3730}
3731
3732impl Add<MotorDual> for Plane {
3733 type Output = MotorDual;
3734
3735 fn add(self, other: MotorDual) -> MotorDual {
3736 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group0() } }
3737 }
3738}
3739
3740impl Sub<MotorDual> for Plane {
3741 type Output = MotorDual;
3742
3743 fn sub(self, other: MotorDual) -> MotorDual {
3744 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group0() } }
3745 }
3746}
3747
3748impl GeometricProduct<MotorDual> for Plane {
3749 type Output = Motor;
3750
3751 fn geometric_product(self, other: MotorDual) -> Motor {
3752 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
3753 }
3754}
3755
3756impl RegressiveProduct<MotorDual> for Plane {
3757 type Output = Plane;
3758
3759 fn regressive_product(self, other: MotorDual) -> Plane {
3760 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3761 }
3762}
3763
3764impl OuterProduct<MotorDual> for Plane {
3765 type Output = Point;
3766
3767 fn outer_product(self, other: MotorDual) -> Point {
3768 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[1]]) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x3::from([0.0, 1.0, -1.0]) } }
3769 }
3770}
3771
3772impl InnerProduct<MotorDual> for Plane {
3773 type Output = Translator;
3774
3775 fn inner_product(self, other: MotorDual) -> Translator {
3776 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0) * Simd32x3::from([other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x3::from([1.0, 1.0, 0.0]) } }
3777 }
3778}
3779
3780impl LeftContraction<MotorDual> for Plane {
3781 type Output = Translator;
3782
3783 fn left_contraction(self, other: MotorDual) -> Translator {
3784 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0) * Simd32x3::from([other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x3::from([1.0, 1.0, 0.0]) } }
3785 }
3786}
3787
3788impl RightContraction<MotorDual> for Plane {
3789 type Output = f32;
3790
3791 fn right_contraction(self, other: MotorDual) -> f32 {
3792 self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
3793 }
3794}
3795
3796impl ScalarProduct<MotorDual> for Plane {
3797 type Output = f32;
3798
3799 fn scalar_product(self, other: MotorDual) -> f32 {
3800 self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
3801 }
3802}
3803
3804impl SquaredMagnitude for Plane {
3805 type Output = f32;
3806
3807 fn squared_magnitude(self) -> f32 {
3808 self.scalar_product(self.reversal())
3809 }
3810}
3811
3812impl Magnitude for Plane {
3813 type Output = f32;
3814
3815 fn magnitude(self) -> f32 {
3816 self.squared_magnitude().sqrt()
3817 }
3818}
3819
3820impl Mul<f32> for Plane {
3821 type Output = Plane;
3822
3823 fn mul(self, other: f32) -> Plane {
3824 self.geometric_product(other)
3825 }
3826}
3827
3828impl MulAssign<f32> for Plane {
3829 fn mul_assign(&mut self, other: f32) {
3830 *self = (*self).mul(other);
3831 }
3832}
3833
3834impl Signum for Plane {
3835 type Output = Plane;
3836
3837 fn signum(self) -> Plane {
3838 self.geometric_product(1.0 / self.magnitude())
3839 }
3840}
3841
3842impl Inverse for Plane {
3843 type Output = Plane;
3844
3845 fn inverse(self) -> Plane {
3846 self.reversal().geometric_product(1.0 / self.squared_magnitude())
3847 }
3848}
3849
3850impl Zero for Translator {
3851 fn zero() -> Self {
3852 Translator { groups: TranslatorGroups { g0: Simd32x3::from(0.0) } }
3853 }
3854}
3855
3856impl One for Translator {
3857 fn one() -> Self {
3858 Translator { groups: TranslatorGroups { g0: Simd32x3::from([1.0, 0.0, 0.0]) } }
3859 }
3860}
3861
3862impl Neg for Translator {
3863 type Output = Translator;
3864
3865 fn neg(self) -> Translator {
3866 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3867 }
3868}
3869
3870impl Automorphism for Translator {
3871 type Output = Translator;
3872
3873 fn automorphism(self) -> Translator {
3874 Translator { groups: TranslatorGroups { g0: self.group0() } }
3875 }
3876}
3877
3878impl Reversal for Translator {
3879 type Output = Translator;
3880
3881 fn reversal(self) -> Translator {
3882 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from([1.0, -1.0, -1.0]) } }
3883 }
3884}
3885
3886impl Conjugation for Translator {
3887 type Output = Translator;
3888
3889 fn conjugation(self) -> Translator {
3890 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from([1.0, -1.0, -1.0]) } }
3891 }
3892}
3893
3894impl Into<f32> for Translator {
3895 fn into(self) -> f32 {
3896 self.group0()[0]
3897 }
3898}
3899
3900impl Add<f32> for Translator {
3901 type Output = Translator;
3902
3903 fn add(self, other: f32) -> Translator {
3904 Translator { groups: TranslatorGroups { g0: self.group0() + Simd32x3::from(other) * Simd32x3::from([1.0, 0.0, 0.0]) } }
3905 }
3906}
3907
3908impl AddAssign<f32> for Translator {
3909 fn add_assign(&mut self, other: f32) {
3910 *self = (*self).add(other);
3911 }
3912}
3913
3914impl Sub<f32> for Translator {
3915 type Output = Translator;
3916
3917 fn sub(self, other: f32) -> Translator {
3918 Translator { groups: TranslatorGroups { g0: self.group0() - Simd32x3::from(other) * Simd32x3::from([1.0, 0.0, 0.0]) } }
3919 }
3920}
3921
3922impl SubAssign<f32> for Translator {
3923 fn sub_assign(&mut self, other: f32) {
3924 *self = (*self).sub(other);
3925 }
3926}
3927
3928impl GeometricProduct<f32> for Translator {
3929 type Output = Translator;
3930
3931 fn geometric_product(self, other: f32) -> Translator {
3932 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
3933 }
3934}
3935
3936impl OuterProduct<f32> for Translator {
3937 type Output = Translator;
3938
3939 fn outer_product(self, other: f32) -> Translator {
3940 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
3941 }
3942}
3943
3944impl InnerProduct<f32> for Translator {
3945 type Output = Translator;
3946
3947 fn inner_product(self, other: f32) -> Translator {
3948 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
3949 }
3950}
3951
3952impl LeftContraction<f32> for Translator {
3953 type Output = f32;
3954
3955 fn left_contraction(self, other: f32) -> f32 {
3956 self.group0()[0] * other
3957 }
3958}
3959
3960impl RightContraction<f32> for Translator {
3961 type Output = Translator;
3962
3963 fn right_contraction(self, other: f32) -> Translator {
3964 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
3965 }
3966}
3967
3968impl ScalarProduct<f32> for Translator {
3969 type Output = f32;
3970
3971 fn scalar_product(self, other: f32) -> f32 {
3972 self.group0()[0] * other
3973 }
3974}
3975
3976impl Add<MultiVector> for Translator {
3977 type Output = MultiVector;
3978
3979 fn add(self, other: MultiVector) -> MultiVector {
3980 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0(), g1: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group1() } }
3981 }
3982}
3983
3984impl Sub<MultiVector> for Translator {
3985 type Output = MultiVector;
3986
3987 fn sub(self, other: MultiVector) -> MultiVector {
3988 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0(), g1: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group1() } }
3989 }
3990}
3991
3992impl GeometricProduct<MultiVector> for Translator {
3993 type Output = MultiVector;
3994
3995 fn geometric_product(self, other: MultiVector) -> MultiVector {
3996 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
3997 }
3998}
3999
4000impl OuterProduct<MultiVector> for Translator {
4001 type Output = MultiVector;
4002
4003 fn outer_product(self, other: MultiVector) -> MultiVector {
4004 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 2, 0) * Simd32x4::from([0.0, 1.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[1], self.group0()[0]]) * swizzle!(other.group0(), 0, 3, 0, 0) * Simd32x4::from([0.0, 1.0, 1.0, 0.0]) } }
4005 }
4006}
4007
4008impl InnerProduct<MultiVector> for Translator {
4009 type Output = MultiVector;
4010
4011 fn inner_product(self, other: MultiVector) -> MultiVector {
4012 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[1], self.group0()[0]]) * swizzle!(other.group0(), 2, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) } }
4013 }
4014}
4015
4016impl LeftContraction<MultiVector> for Translator {
4017 type Output = MultiVector;
4018
4019 fn left_contraction(self, other: MultiVector) -> MultiVector {
4020 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() } }
4021 }
4022}
4023
4024impl ScalarProduct<MultiVector> for Translator {
4025 type Output = f32;
4026
4027 fn scalar_product(self, other: MultiVector) -> f32 {
4028 self.group0()[0] * other.group0()[0]
4029 }
4030}
4031
4032impl Add<Rotor> for Translator {
4033 type Output = Motor;
4034
4035 fn add(self, other: Rotor) -> Motor {
4036 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) + Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
4037 }
4038}
4039
4040impl Sub<Rotor> for Translator {
4041 type Output = Motor;
4042
4043 fn sub(self, other: Rotor) -> Motor {
4044 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) - Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
4045 }
4046}
4047
4048impl GeometricProduct<Rotor> for Translator {
4049 type Output = Motor;
4050
4051 fn geometric_product(self, other: Rotor) -> Motor {
4052 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
4053 }
4054}
4055
4056impl OuterProduct<Rotor> for Translator {
4057 type Output = Motor;
4058
4059 fn outer_product(self, other: Rotor) -> Motor {
4060 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) } }
4061 }
4062}
4063
4064impl InnerProduct<Rotor> for Translator {
4065 type Output = Motor;
4066
4067 fn inner_product(self, other: Rotor) -> Motor {
4068 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) } }
4069 }
4070}
4071
4072impl LeftContraction<Rotor> for Translator {
4073 type Output = Rotor;
4074
4075 fn left_contraction(self, other: Rotor) -> Rotor {
4076 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4077 }
4078}
4079
4080impl RightContraction<Rotor> for Translator {
4081 type Output = Translator;
4082
4083 fn right_contraction(self, other: Rotor) -> Translator {
4084 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4085 }
4086}
4087
4088impl ScalarProduct<Rotor> for Translator {
4089 type Output = f32;
4090
4091 fn scalar_product(self, other: Rotor) -> f32 {
4092 self.group0()[0] * other.group0()[0]
4093 }
4094}
4095
4096impl Add<Point> for Translator {
4097 type Output = Motor;
4098
4099 fn add(self, other: Point) -> Motor {
4100 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4101 }
4102}
4103
4104impl Sub<Point> for Translator {
4105 type Output = Motor;
4106
4107 fn sub(self, other: Point) -> Motor {
4108 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4109 }
4110}
4111
4112impl GeometricProduct<Point> for Translator {
4113 type Output = Point;
4114
4115 fn geometric_product(self, other: Point) -> Point {
4116 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 0, 2, 1) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([0.0, 1.0, -1.0]) } }
4117 }
4118}
4119
4120impl RegressiveProduct<Point> for Translator {
4121 type Output = Plane;
4122
4123 fn regressive_product(self, other: Point) -> Plane {
4124 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([1.0, -1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 1) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) } }
4125 }
4126}
4127
4128impl OuterProduct<Point> for Translator {
4129 type Output = Point;
4130
4131 fn outer_product(self, other: Point) -> Point {
4132 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4133 }
4134}
4135
4136impl InnerProduct<Point> for Translator {
4137 type Output = Point;
4138
4139 fn inner_product(self, other: Point) -> Point {
4140 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4141 }
4142}
4143
4144impl LeftContraction<Point> for Translator {
4145 type Output = Point;
4146
4147 fn left_contraction(self, other: Point) -> Point {
4148 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4149 }
4150}
4151
4152impl Into<IdealPoint> for Translator {
4153 fn into(self) -> IdealPoint {
4154 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[1], self.group0()[2]]) } }
4155 }
4156}
4157
4158impl Add<IdealPoint> for Translator {
4159 type Output = Translator;
4160
4161 fn add(self, other: IdealPoint) -> Translator {
4162 Translator { groups: TranslatorGroups { g0: self.group0() + Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
4163 }
4164}
4165
4166impl AddAssign<IdealPoint> for Translator {
4167 fn add_assign(&mut self, other: IdealPoint) {
4168 *self = (*self).add(other);
4169 }
4170}
4171
4172impl Sub<IdealPoint> for Translator {
4173 type Output = Translator;
4174
4175 fn sub(self, other: IdealPoint) -> Translator {
4176 Translator { groups: TranslatorGroups { g0: self.group0() - Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
4177 }
4178}
4179
4180impl SubAssign<IdealPoint> for Translator {
4181 fn sub_assign(&mut self, other: IdealPoint) {
4182 *self = (*self).sub(other);
4183 }
4184}
4185
4186impl GeometricProduct<IdealPoint> for Translator {
4187 type Output = IdealPoint;
4188
4189 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
4190 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4191 }
4192}
4193
4194impl OuterProduct<IdealPoint> for Translator {
4195 type Output = IdealPoint;
4196
4197 fn outer_product(self, other: IdealPoint) -> IdealPoint {
4198 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4199 }
4200}
4201
4202impl InnerProduct<IdealPoint> for Translator {
4203 type Output = IdealPoint;
4204
4205 fn inner_product(self, other: IdealPoint) -> IdealPoint {
4206 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4207 }
4208}
4209
4210impl LeftContraction<IdealPoint> for Translator {
4211 type Output = IdealPoint;
4212
4213 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
4214 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4215 }
4216}
4217
4218impl GeometricProduct<Plane> for Translator {
4219 type Output = MotorDual;
4220
4221 fn geometric_product(self, other: Plane) -> MotorDual {
4222 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4223 }
4224}
4225
4226impl RegressiveProduct<Plane> for Translator {
4227 type Output = f32;
4228
4229 fn regressive_product(self, other: Plane) -> f32 {
4230 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
4231 }
4232}
4233
4234impl OuterProduct<Plane> for Translator {
4235 type Output = MotorDual;
4236
4237 fn outer_product(self, other: Plane) -> MotorDual {
4238 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
4239 }
4240}
4241
4242impl InnerProduct<Plane> for Translator {
4243 type Output = Plane;
4244
4245 fn inner_product(self, other: Plane) -> Plane {
4246 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([-1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([1.0, 0.0, 0.0]) } }
4247 }
4248}
4249
4250impl LeftContraction<Plane> for Translator {
4251 type Output = Plane;
4252
4253 fn left_contraction(self, other: Plane) -> Plane {
4254 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4255 }
4256}
4257
4258impl Add<Translator> for Translator {
4259 type Output = Translator;
4260
4261 fn add(self, other: Translator) -> Translator {
4262 Translator { groups: TranslatorGroups { g0: self.group0() + other.group0() } }
4263 }
4264}
4265
4266impl AddAssign<Translator> for Translator {
4267 fn add_assign(&mut self, other: Translator) {
4268 *self = (*self).add(other);
4269 }
4270}
4271
4272impl Sub<Translator> for Translator {
4273 type Output = Translator;
4274
4275 fn sub(self, other: Translator) -> Translator {
4276 Translator { groups: TranslatorGroups { g0: self.group0() - other.group0() } }
4277 }
4278}
4279
4280impl SubAssign<Translator> for Translator {
4281 fn sub_assign(&mut self, other: Translator) {
4282 *self = (*self).sub(other);
4283 }
4284}
4285
4286impl Mul<Translator> for Translator {
4287 type Output = Translator;
4288
4289 fn mul(self, other: Translator) -> Translator {
4290 Translator { groups: TranslatorGroups { g0: self.group0() * other.group0() } }
4291 }
4292}
4293
4294impl MulAssign<Translator> for Translator {
4295 fn mul_assign(&mut self, other: Translator) {
4296 *self = (*self).mul(other);
4297 }
4298}
4299
4300impl Div<Translator> for Translator {
4301 type Output = Translator;
4302
4303 fn div(self, other: Translator) -> Translator {
4304 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) / Simd32x3::from([other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) } }
4305 }
4306}
4307
4308impl DivAssign<Translator> for Translator {
4309 fn div_assign(&mut self, other: Translator) {
4310 *self = (*self).div(other);
4311 }
4312}
4313
4314impl GeometricProduct<Translator> for Translator {
4315 type Output = Translator;
4316
4317 fn geometric_product(self, other: Translator) -> Translator {
4318 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x3::from(other.group0()[0]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
4319 }
4320}
4321
4322impl OuterProduct<Translator> for Translator {
4323 type Output = Translator;
4324
4325 fn outer_product(self, other: Translator) -> Translator {
4326 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x3::from(other.group0()[0]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
4327 }
4328}
4329
4330impl InnerProduct<Translator> for Translator {
4331 type Output = Translator;
4332
4333 fn inner_product(self, other: Translator) -> Translator {
4334 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x3::from(other.group0()[0]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
4335 }
4336}
4337
4338impl LeftContraction<Translator> for Translator {
4339 type Output = Translator;
4340
4341 fn left_contraction(self, other: Translator) -> Translator {
4342 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4343 }
4344}
4345
4346impl RightContraction<Translator> for Translator {
4347 type Output = Translator;
4348
4349 fn right_contraction(self, other: Translator) -> Translator {
4350 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4351 }
4352}
4353
4354impl ScalarProduct<Translator> for Translator {
4355 type Output = f32;
4356
4357 fn scalar_product(self, other: Translator) -> f32 {
4358 self.group0()[0] * other.group0()[0]
4359 }
4360}
4361
4362impl Add<Motor> for Translator {
4363 type Output = Motor;
4364
4365 fn add(self, other: Motor) -> Motor {
4366 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) + other.group0() } }
4367 }
4368}
4369
4370impl Sub<Motor> for Translator {
4371 type Output = Motor;
4372
4373 fn sub(self, other: Motor) -> Motor {
4374 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) - other.group0() } }
4375 }
4376}
4377
4378impl GeometricProduct<Motor> for Translator {
4379 type Output = Motor;
4380
4381 fn geometric_product(self, other: Motor) -> Motor {
4382 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
4383 }
4384}
4385
4386impl RegressiveProduct<Motor> for Translator {
4387 type Output = Plane;
4388
4389 fn regressive_product(self, other: Motor) -> Plane {
4390 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 1) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x3::from([-1.0, 0.0, 1.0]) } }
4391 }
4392}
4393
4394impl OuterProduct<Motor> for Translator {
4395 type Output = Motor;
4396
4397 fn outer_product(self, other: Motor) -> Motor {
4398 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
4399 }
4400}
4401
4402impl InnerProduct<Motor> for Translator {
4403 type Output = Motor;
4404
4405 fn inner_product(self, other: Motor) -> Motor {
4406 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
4407 }
4408}
4409
4410impl LeftContraction<Motor> for Translator {
4411 type Output = Motor;
4412
4413 fn left_contraction(self, other: Motor) -> Motor {
4414 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
4415 }
4416}
4417
4418impl RightContraction<Motor> for Translator {
4419 type Output = Translator;
4420
4421 fn right_contraction(self, other: Motor) -> Translator {
4422 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4423 }
4424}
4425
4426impl ScalarProduct<Motor> for Translator {
4427 type Output = f32;
4428
4429 fn scalar_product(self, other: Motor) -> f32 {
4430 self.group0()[0] * other.group0()[0]
4431 }
4432}
4433
4434impl GeometricProduct<MotorDual> for Translator {
4435 type Output = MotorDual;
4436
4437 fn geometric_product(self, other: MotorDual) -> MotorDual {
4438 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 3, 3) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 2, 3, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
4439 }
4440}
4441
4442impl RegressiveProduct<MotorDual> for Translator {
4443 type Output = Translator;
4444
4445 fn regressive_product(self, other: MotorDual) -> Translator {
4446 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[2], other.group0()[0], other.group0()[2]]) * Simd32x3::from([1.0, 1.0, 0.0]) + Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([1.0, 0.0, 0.0]) } }
4447 }
4448}
4449
4450impl OuterProduct<MotorDual> for Translator {
4451 type Output = MotorDual;
4452
4453 fn outer_product(self, other: MotorDual) -> MotorDual {
4454 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 2, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4455 }
4456}
4457
4458impl InnerProduct<MotorDual> for Translator {
4459 type Output = MotorDual;
4460
4461 fn inner_product(self, other: MotorDual) -> MotorDual {
4462 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 0, 3, 0, 0) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) } }
4463 }
4464}
4465
4466impl LeftContraction<MotorDual> for Translator {
4467 type Output = MotorDual;
4468
4469 fn left_contraction(self, other: MotorDual) -> MotorDual {
4470 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
4471 }
4472}
4473
4474impl SquaredMagnitude for Translator {
4475 type Output = f32;
4476
4477 fn squared_magnitude(self) -> f32 {
4478 self.scalar_product(self.reversal())
4479 }
4480}
4481
4482impl Magnitude for Translator {
4483 type Output = f32;
4484
4485 fn magnitude(self) -> f32 {
4486 self.squared_magnitude().sqrt()
4487 }
4488}
4489
4490impl Mul<f32> for Translator {
4491 type Output = Translator;
4492
4493 fn mul(self, other: f32) -> Translator {
4494 self.geometric_product(other)
4495 }
4496}
4497
4498impl MulAssign<f32> for Translator {
4499 fn mul_assign(&mut self, other: f32) {
4500 *self = (*self).mul(other);
4501 }
4502}
4503
4504impl Signum for Translator {
4505 type Output = Translator;
4506
4507 fn signum(self) -> Translator {
4508 self.geometric_product(1.0 / self.magnitude())
4509 }
4510}
4511
4512impl Inverse for Translator {
4513 type Output = Translator;
4514
4515 fn inverse(self) -> Translator {
4516 self.reversal().geometric_product(1.0 / self.squared_magnitude())
4517 }
4518}
4519
4520impl Zero for Motor {
4521 fn zero() -> Self {
4522 Motor { groups: MotorGroups { g0: Simd32x4::from(0.0) } }
4523 }
4524}
4525
4526impl One for Motor {
4527 fn one() -> Self {
4528 Motor { groups: MotorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4529 }
4530}
4531
4532impl Neg for Motor {
4533 type Output = Motor;
4534
4535 fn neg(self) -> Motor {
4536 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
4537 }
4538}
4539
4540impl Automorphism for Motor {
4541 type Output = Motor;
4542
4543 fn automorphism(self) -> Motor {
4544 Motor { groups: MotorGroups { g0: self.group0() } }
4545 }
4546}
4547
4548impl Reversal for Motor {
4549 type Output = Motor;
4550
4551 fn reversal(self) -> Motor {
4552 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
4553 }
4554}
4555
4556impl Conjugation for Motor {
4557 type Output = Motor;
4558
4559 fn conjugation(self) -> Motor {
4560 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
4561 }
4562}
4563
4564impl Dual for Motor {
4565 type Output = MotorDual;
4566
4567 fn dual(self) -> MotorDual {
4568 MotorDual { groups: MotorDualGroups { g0: self.group0() } }
4569 }
4570}
4571
4572impl Into<f32> for Motor {
4573 fn into(self) -> f32 {
4574 self.group0()[0]
4575 }
4576}
4577
4578impl Add<f32> for Motor {
4579 type Output = Motor;
4580
4581 fn add(self, other: f32) -> Motor {
4582 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4583 }
4584}
4585
4586impl AddAssign<f32> for Motor {
4587 fn add_assign(&mut self, other: f32) {
4588 *self = (*self).add(other);
4589 }
4590}
4591
4592impl Sub<f32> for Motor {
4593 type Output = Motor;
4594
4595 fn sub(self, other: f32) -> Motor {
4596 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4597 }
4598}
4599
4600impl SubAssign<f32> for Motor {
4601 fn sub_assign(&mut self, other: f32) {
4602 *self = (*self).sub(other);
4603 }
4604}
4605
4606impl GeometricProduct<f32> for Motor {
4607 type Output = Motor;
4608
4609 fn geometric_product(self, other: f32) -> Motor {
4610 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4611 }
4612}
4613
4614impl OuterProduct<f32> for Motor {
4615 type Output = Motor;
4616
4617 fn outer_product(self, other: f32) -> Motor {
4618 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4619 }
4620}
4621
4622impl InnerProduct<f32> for Motor {
4623 type Output = Motor;
4624
4625 fn inner_product(self, other: f32) -> Motor {
4626 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4627 }
4628}
4629
4630impl LeftContraction<f32> for Motor {
4631 type Output = f32;
4632
4633 fn left_contraction(self, other: f32) -> f32 {
4634 self.group0()[0] * other
4635 }
4636}
4637
4638impl RightContraction<f32> for Motor {
4639 type Output = Motor;
4640
4641 fn right_contraction(self, other: f32) -> Motor {
4642 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4643 }
4644}
4645
4646impl ScalarProduct<f32> for Motor {
4647 type Output = f32;
4648
4649 fn scalar_product(self, other: f32) -> f32 {
4650 self.group0()[0] * other
4651 }
4652}
4653
4654impl Add<MultiVector> for Motor {
4655 type Output = MultiVector;
4656
4657 fn add(self, other: MultiVector) -> MultiVector {
4658 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + other.group0(), g1: swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group1() } }
4659 }
4660}
4661
4662impl Sub<MultiVector> for Motor {
4663 type Output = MultiVector;
4664
4665 fn sub(self, other: MultiVector) -> MultiVector {
4666 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - other.group0(), g1: swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group1() } }
4667 }
4668}
4669
4670impl GeometricProduct<MultiVector> for Motor {
4671 type Output = MultiVector;
4672
4673 fn geometric_product(self, other: MultiVector) -> MultiVector {
4674 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
4675 }
4676}
4677
4678impl OuterProduct<MultiVector> for Motor {
4679 type Output = MultiVector;
4680
4681 fn outer_product(self, other: MultiVector) -> MultiVector {
4682 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 0, 3) * Simd32x4::from([0.0, 1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 2, 0) * Simd32x4::from([0.0, 1.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) } }
4683 }
4684}
4685
4686impl InnerProduct<MultiVector> for Motor {
4687 type Output = MultiVector;
4688
4689 fn inner_product(self, other: MultiVector) -> MultiVector {
4690 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
4691 }
4692}
4693
4694impl LeftContraction<MultiVector> for Motor {
4695 type Output = MultiVector;
4696
4697 fn left_contraction(self, other: MultiVector) -> MultiVector {
4698 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
4699 }
4700}
4701
4702impl ScalarProduct<MultiVector> for Motor {
4703 type Output = f32;
4704
4705 fn scalar_product(self, other: MultiVector) -> f32 {
4706 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
4707 }
4708}
4709
4710impl Into<Rotor> for Motor {
4711 fn into(self) -> Rotor {
4712 Rotor { groups: RotorGroups { g0: Simd32x2::from([self.group0()[0], self.group0()[1]]) } }
4713 }
4714}
4715
4716impl Add<Rotor> for Motor {
4717 type Output = Motor;
4718
4719 fn add(self, other: Rotor) -> Motor {
4720 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
4721 }
4722}
4723
4724impl AddAssign<Rotor> for Motor {
4725 fn add_assign(&mut self, other: Rotor) {
4726 *self = (*self).add(other);
4727 }
4728}
4729
4730impl Sub<Rotor> for Motor {
4731 type Output = Motor;
4732
4733 fn sub(self, other: Rotor) -> Motor {
4734 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
4735 }
4736}
4737
4738impl SubAssign<Rotor> for Motor {
4739 fn sub_assign(&mut self, other: Rotor) {
4740 *self = (*self).sub(other);
4741 }
4742}
4743
4744impl GeometricProduct<Rotor> for Motor {
4745 type Output = Motor;
4746
4747 fn geometric_product(self, other: Rotor) -> Motor {
4748 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
4749 }
4750}
4751
4752impl OuterProduct<Rotor> for Motor {
4753 type Output = Motor;
4754
4755 fn outer_product(self, other: Rotor) -> Motor {
4756 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) } }
4757 }
4758}
4759
4760impl InnerProduct<Rotor> for Motor {
4761 type Output = Motor;
4762
4763 fn inner_product(self, other: Rotor) -> Motor {
4764 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) } }
4765 }
4766}
4767
4768impl LeftContraction<Rotor> for Motor {
4769 type Output = Rotor;
4770
4771 fn left_contraction(self, other: Rotor) -> Rotor {
4772 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + Simd32x2::from([self.group0()[1], self.group0()[0]]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 0.0]) } }
4773 }
4774}
4775
4776impl RightContraction<Rotor> for Motor {
4777 type Output = Motor;
4778
4779 fn right_contraction(self, other: Rotor) -> Motor {
4780 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
4781 }
4782}
4783
4784impl ScalarProduct<Rotor> for Motor {
4785 type Output = f32;
4786
4787 fn scalar_product(self, other: Rotor) -> f32 {
4788 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
4789 }
4790}
4791
4792impl Into<Point> for Motor {
4793 fn into(self) -> Point {
4794 Point { groups: PointGroups { g0: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
4795 }
4796}
4797
4798impl Add<Point> for Motor {
4799 type Output = Motor;
4800
4801 fn add(self, other: Point) -> Motor {
4802 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4803 }
4804}
4805
4806impl AddAssign<Point> for Motor {
4807 fn add_assign(&mut self, other: Point) {
4808 *self = (*self).add(other);
4809 }
4810}
4811
4812impl Sub<Point> for Motor {
4813 type Output = Motor;
4814
4815 fn sub(self, other: Point) -> Motor {
4816 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4817 }
4818}
4819
4820impl SubAssign<Point> for Motor {
4821 fn sub_assign(&mut self, other: Point) {
4822 *self = (*self).sub(other);
4823 }
4824}
4825
4826impl GeometricProduct<Point> for Motor {
4827 type Output = Motor;
4828
4829 fn geometric_product(self, other: Point) -> Motor {
4830 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4831 }
4832}
4833
4834impl RegressiveProduct<Point> for Motor {
4835 type Output = Plane;
4836
4837 fn regressive_product(self, other: Point) -> Plane {
4838 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[3]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([0.0, 1.0, -1.0]) } }
4839 }
4840}
4841
4842impl OuterProduct<Point> for Motor {
4843 type Output = Point;
4844
4845 fn outer_product(self, other: Point) -> Point {
4846 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4847 }
4848}
4849
4850impl InnerProduct<Point> for Motor {
4851 type Output = Motor;
4852
4853 fn inner_product(self, other: Point) -> Motor {
4854 Motor { groups: MotorGroups { g0: swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
4855 }
4856}
4857
4858impl LeftContraction<Point> for Motor {
4859 type Output = Motor;
4860
4861 fn left_contraction(self, other: Point) -> Motor {
4862 Motor { groups: MotorGroups { g0: swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
4863 }
4864}
4865
4866impl RightContraction<Point> for Motor {
4867 type Output = f32;
4868
4869 fn right_contraction(self, other: Point) -> f32 {
4870 0.0 - self.group0()[1] * other.group0()[0]
4871 }
4872}
4873
4874impl ScalarProduct<Point> for Motor {
4875 type Output = f32;
4876
4877 fn scalar_product(self, other: Point) -> f32 {
4878 0.0 - self.group0()[1] * other.group0()[0]
4879 }
4880}
4881
4882impl Into<IdealPoint> for Motor {
4883 fn into(self) -> IdealPoint {
4884 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[2], self.group0()[3]]) } }
4885 }
4886}
4887
4888impl Add<IdealPoint> for Motor {
4889 type Output = Motor;
4890
4891 fn add(self, other: IdealPoint) -> Motor {
4892 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
4893 }
4894}
4895
4896impl AddAssign<IdealPoint> for Motor {
4897 fn add_assign(&mut self, other: IdealPoint) {
4898 *self = (*self).add(other);
4899 }
4900}
4901
4902impl Sub<IdealPoint> for Motor {
4903 type Output = Motor;
4904
4905 fn sub(self, other: IdealPoint) -> Motor {
4906 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
4907 }
4908}
4909
4910impl SubAssign<IdealPoint> for Motor {
4911 fn sub_assign(&mut self, other: IdealPoint) {
4912 *self = (*self).sub(other);
4913 }
4914}
4915
4916impl GeometricProduct<IdealPoint> for Motor {
4917 type Output = IdealPoint;
4918
4919 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
4920 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([-1.0, 1.0]) } }
4921 }
4922}
4923
4924impl RegressiveProduct<IdealPoint> for Motor {
4925 type Output = Plane;
4926
4927 fn regressive_product(self, other: IdealPoint) -> Plane {
4928 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[1], self.group0()[1]]) * Simd32x3::from([other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x3::from([-1.0, 1.0, -1.0]) } }
4929 }
4930}
4931
4932impl OuterProduct<IdealPoint> for Motor {
4933 type Output = IdealPoint;
4934
4935 fn outer_product(self, other: IdealPoint) -> IdealPoint {
4936 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4937 }
4938}
4939
4940impl InnerProduct<IdealPoint> for Motor {
4941 type Output = IdealPoint;
4942
4943 fn inner_product(self, other: IdealPoint) -> IdealPoint {
4944 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4945 }
4946}
4947
4948impl LeftContraction<IdealPoint> for Motor {
4949 type Output = IdealPoint;
4950
4951 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
4952 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4953 }
4954}
4955
4956impl GeometricProduct<Plane> for Motor {
4957 type Output = MotorDual;
4958
4959 fn geometric_product(self, other: Plane) -> MotorDual {
4960 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4961 }
4962}
4963
4964impl RegressiveProduct<Plane> for Motor {
4965 type Output = f32;
4966
4967 fn regressive_product(self, other: Plane) -> f32 {
4968 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
4969 }
4970}
4971
4972impl OuterProduct<Plane> for Motor {
4973 type Output = MotorDual;
4974
4975 fn outer_product(self, other: Plane) -> MotorDual {
4976 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
4977 }
4978}
4979
4980impl InnerProduct<Plane> for Motor {
4981 type Output = Plane;
4982
4983 fn inner_product(self, other: Plane) -> Plane {
4984 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([-1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 2, 2, 1) * Simd32x3::from([1.0, -1.0, 1.0]) } }
4985 }
4986}
4987
4988impl LeftContraction<Plane> for Motor {
4989 type Output = Plane;
4990
4991 fn left_contraction(self, other: Plane) -> Plane {
4992 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4993 }
4994}
4995
4996impl RightContraction<Plane> for Motor {
4997 type Output = Plane;
4998
4999 fn right_contraction(self, other: Plane) -> Plane {
5000 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([-1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 2, 2, 1) * Simd32x3::from([1.0, -1.0, 1.0]) } }
5001 }
5002}
5003
5004impl Into<Translator> for Motor {
5005 fn into(self) -> Translator {
5006 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[2], self.group0()[3]]) } }
5007 }
5008}
5009
5010impl Add<Translator> for Motor {
5011 type Output = Motor;
5012
5013 fn add(self, other: Translator) -> Motor {
5014 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
5015 }
5016}
5017
5018impl AddAssign<Translator> for Motor {
5019 fn add_assign(&mut self, other: Translator) {
5020 *self = (*self).add(other);
5021 }
5022}
5023
5024impl Sub<Translator> for Motor {
5025 type Output = Motor;
5026
5027 fn sub(self, other: Translator) -> Motor {
5028 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
5029 }
5030}
5031
5032impl SubAssign<Translator> for Motor {
5033 fn sub_assign(&mut self, other: Translator) {
5034 *self = (*self).sub(other);
5035 }
5036}
5037
5038impl GeometricProduct<Translator> for Motor {
5039 type Output = Motor;
5040
5041 fn geometric_product(self, other: Translator) -> Motor {
5042 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
5043 }
5044}
5045
5046impl RegressiveProduct<Translator> for Motor {
5047 type Output = Plane;
5048
5049 fn regressive_product(self, other: Translator) -> Plane {
5050 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 2, 2, 1) * Simd32x3::from([-1.0, 1.0, -1.0]) } }
5051 }
5052}
5053
5054impl OuterProduct<Translator> for Motor {
5055 type Output = Motor;
5056
5057 fn outer_product(self, other: Translator) -> Motor {
5058 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5059 }
5060}
5061
5062impl InnerProduct<Translator> for Motor {
5063 type Output = Motor;
5064
5065 fn inner_product(self, other: Translator) -> Motor {
5066 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5067 }
5068}
5069
5070impl LeftContraction<Translator> for Motor {
5071 type Output = Translator;
5072
5073 fn left_contraction(self, other: Translator) -> Translator {
5074 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
5075 }
5076}
5077
5078impl RightContraction<Translator> for Motor {
5079 type Output = Motor;
5080
5081 fn right_contraction(self, other: Translator) -> Motor {
5082 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
5083 }
5084}
5085
5086impl ScalarProduct<Translator> for Motor {
5087 type Output = f32;
5088
5089 fn scalar_product(self, other: Translator) -> f32 {
5090 self.group0()[0] * other.group0()[0]
5091 }
5092}
5093
5094impl Add<Motor> for Motor {
5095 type Output = Motor;
5096
5097 fn add(self, other: Motor) -> Motor {
5098 Motor { groups: MotorGroups { g0: self.group0() + other.group0() } }
5099 }
5100}
5101
5102impl AddAssign<Motor> for Motor {
5103 fn add_assign(&mut self, other: Motor) {
5104 *self = (*self).add(other);
5105 }
5106}
5107
5108impl Sub<Motor> for Motor {
5109 type Output = Motor;
5110
5111 fn sub(self, other: Motor) -> Motor {
5112 Motor { groups: MotorGroups { g0: self.group0() - other.group0() } }
5113 }
5114}
5115
5116impl SubAssign<Motor> for Motor {
5117 fn sub_assign(&mut self, other: Motor) {
5118 *self = (*self).sub(other);
5119 }
5120}
5121
5122impl Mul<Motor> for Motor {
5123 type Output = Motor;
5124
5125 fn mul(self, other: Motor) -> Motor {
5126 Motor { groups: MotorGroups { g0: self.group0() * other.group0() } }
5127 }
5128}
5129
5130impl MulAssign<Motor> for Motor {
5131 fn mul_assign(&mut self, other: Motor) {
5132 *self = (*self).mul(other);
5133 }
5134}
5135
5136impl Div<Motor> for Motor {
5137 type Output = Motor;
5138
5139 fn div(self, other: Motor) -> Motor {
5140 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) / Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) } }
5141 }
5142}
5143
5144impl DivAssign<Motor> for Motor {
5145 fn div_assign(&mut self, other: Motor) {
5146 *self = (*self).div(other);
5147 }
5148}
5149
5150impl GeometricProduct<Motor> for Motor {
5151 type Output = Motor;
5152
5153 fn geometric_product(self, other: Motor) -> Motor {
5154 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
5155 }
5156}
5157
5158impl RegressiveProduct<Motor> for Motor {
5159 type Output = Plane;
5160
5161 fn regressive_product(self, other: Motor) -> Plane {
5162 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[1]]) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[3]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[1]]) * Simd32x3::from([other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x3::from([0.0, 1.0, -1.0]) } }
5163 }
5164}
5165
5166impl OuterProduct<Motor> for Motor {
5167 type Output = Motor;
5168
5169 fn outer_product(self, other: Motor) -> Motor {
5170 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5171 }
5172}
5173
5174impl InnerProduct<Motor> for Motor {
5175 type Output = Motor;
5176
5177 fn inner_product(self, other: Motor) -> Motor {
5178 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 1, 1, 2, 3) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5179 }
5180}
5181
5182impl LeftContraction<Motor> for Motor {
5183 type Output = Motor;
5184
5185 fn left_contraction(self, other: Motor) -> Motor {
5186 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) } }
5187 }
5188}
5189
5190impl RightContraction<Motor> for Motor {
5191 type Output = Motor;
5192
5193 fn right_contraction(self, other: Motor) -> Motor {
5194 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
5195 }
5196}
5197
5198impl ScalarProduct<Motor> for Motor {
5199 type Output = f32;
5200
5201 fn scalar_product(self, other: Motor) -> f32 {
5202 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
5203 }
5204}
5205
5206impl Add<MotorDual> for Motor {
5207 type Output = MultiVector;
5208
5209 fn add(self, other: MotorDual) -> MultiVector {
5210 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]), g1: swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5211 }
5212}
5213
5214impl Sub<MotorDual> for Motor {
5215 type Output = MultiVector;
5216
5217 fn sub(self, other: MotorDual) -> MultiVector {
5218 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]), g1: swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5219 }
5220}
5221
5222impl GeometricProduct<MotorDual> for Motor {
5223 type Output = MotorDual;
5224
5225 fn geometric_product(self, other: MotorDual) -> MotorDual {
5226 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 3, 3) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + swizzle!(self.group0(), 2, 2, 0, 0) * swizzle!(other.group0(), 2, 3, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5227 }
5228}
5229
5230impl RegressiveProduct<MotorDual> for Motor {
5231 type Output = Motor;
5232
5233 fn regressive_product(self, other: MotorDual) -> Motor {
5234 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5235 }
5236}
5237
5238impl OuterProduct<MotorDual> for Motor {
5239 type Output = MotorDual;
5240
5241 fn outer_product(self, other: MotorDual) -> MotorDual {
5242 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5243 }
5244}
5245
5246impl InnerProduct<MotorDual> for Motor {
5247 type Output = MotorDual;
5248
5249 fn inner_product(self, other: MotorDual) -> MotorDual {
5250 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) } }
5251 }
5252}
5253
5254impl LeftContraction<MotorDual> for Motor {
5255 type Output = MotorDual;
5256
5257 fn left_contraction(self, other: MotorDual) -> MotorDual {
5258 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) } }
5259 }
5260}
5261
5262impl RightContraction<MotorDual> for Motor {
5263 type Output = Plane;
5264
5265 fn right_contraction(self, other: MotorDual) -> Plane {
5266 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([-1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[1], self.group0()[1]]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 1.0]) } }
5267 }
5268}
5269
5270impl SquaredMagnitude for Motor {
5271 type Output = f32;
5272
5273 fn squared_magnitude(self) -> f32 {
5274 self.scalar_product(self.reversal())
5275 }
5276}
5277
5278impl Magnitude for Motor {
5279 type Output = f32;
5280
5281 fn magnitude(self) -> f32 {
5282 self.squared_magnitude().sqrt()
5283 }
5284}
5285
5286impl Mul<f32> for Motor {
5287 type Output = Motor;
5288
5289 fn mul(self, other: f32) -> Motor {
5290 self.geometric_product(other)
5291 }
5292}
5293
5294impl MulAssign<f32> for Motor {
5295 fn mul_assign(&mut self, other: f32) {
5296 *self = (*self).mul(other);
5297 }
5298}
5299
5300impl Signum for Motor {
5301 type Output = Motor;
5302
5303 fn signum(self) -> Motor {
5304 self.geometric_product(1.0 / self.magnitude())
5305 }
5306}
5307
5308impl Inverse for Motor {
5309 type Output = Motor;
5310
5311 fn inverse(self) -> Motor {
5312 self.reversal().geometric_product(1.0 / self.squared_magnitude())
5313 }
5314}
5315
5316impl Zero for MotorDual {
5317 fn zero() -> Self {
5318 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(0.0) } }
5319 }
5320}
5321
5322impl One for MotorDual {
5323 fn one() -> Self {
5324 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(0.0) } }
5325 }
5326}
5327
5328impl Neg for MotorDual {
5329 type Output = MotorDual;
5330
5331 fn neg(self) -> MotorDual {
5332 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
5333 }
5334}
5335
5336impl Automorphism for MotorDual {
5337 type Output = MotorDual;
5338
5339 fn automorphism(self) -> MotorDual {
5340 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
5341 }
5342}
5343
5344impl Reversal for MotorDual {
5345 type Output = MotorDual;
5346
5347 fn reversal(self) -> MotorDual {
5348 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5349 }
5350}
5351
5352impl Conjugation for MotorDual {
5353 type Output = MotorDual;
5354
5355 fn conjugation(self) -> MotorDual {
5356 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
5357 }
5358}
5359
5360impl Dual for MotorDual {
5361 type Output = Motor;
5362
5363 fn dual(self) -> Motor {
5364 Motor { groups: MotorGroups { g0: self.group0() } }
5365 }
5366}
5367
5368impl GeometricProduct<f32> for MotorDual {
5369 type Output = MotorDual;
5370
5371 fn geometric_product(self, other: f32) -> MotorDual {
5372 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5373 }
5374}
5375
5376impl RegressiveProduct<f32> for MotorDual {
5377 type Output = f32;
5378
5379 fn regressive_product(self, other: f32) -> f32 {
5380 self.group0()[0] * other
5381 }
5382}
5383
5384impl OuterProduct<f32> for MotorDual {
5385 type Output = MotorDual;
5386
5387 fn outer_product(self, other: f32) -> MotorDual {
5388 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5389 }
5390}
5391
5392impl InnerProduct<f32> for MotorDual {
5393 type Output = MotorDual;
5394
5395 fn inner_product(self, other: f32) -> MotorDual {
5396 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5397 }
5398}
5399
5400impl RightContraction<f32> for MotorDual {
5401 type Output = MotorDual;
5402
5403 fn right_contraction(self, other: f32) -> MotorDual {
5404 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5405 }
5406}
5407
5408impl Add<MultiVector> for MotorDual {
5409 type Output = MultiVector;
5410
5411 fn add(self, other: MultiVector) -> MultiVector {
5412 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + other.group0(), g1: swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + other.group1() } }
5413 }
5414}
5415
5416impl Sub<MultiVector> for MotorDual {
5417 type Output = MultiVector;
5418
5419 fn sub(self, other: MultiVector) -> MultiVector {
5420 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - other.group0(), g1: swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - other.group1() } }
5421 }
5422}
5423
5424impl GeometricProduct<MultiVector> for MotorDual {
5425 type Output = MultiVector;
5426
5427 fn geometric_product(self, other: MultiVector) -> MultiVector {
5428 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 3, 0, 1), g1: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * other.group0() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 2, 1, 0) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
5429 }
5430}
5431
5432impl RegressiveProduct<MultiVector> for MotorDual {
5433 type Output = MultiVector;
5434
5435 fn regressive_product(self, other: MultiVector) -> MultiVector {
5436 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 2, 1) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 1, 3) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5437 }
5438}
5439
5440impl ScalarProduct<MultiVector> for MotorDual {
5441 type Output = f32;
5442
5443 fn scalar_product(self, other: MultiVector) -> f32 {
5444 self.group0()[2] * other.group0()[3] + self.group0()[3] * other.group0()[2]
5445 }
5446}
5447
5448impl GeometricProduct<Rotor> for MotorDual {
5449 type Output = MotorDual;
5450
5451 fn geometric_product(self, other: Rotor) -> MotorDual {
5452 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) } }
5453 }
5454}
5455
5456impl RegressiveProduct<Rotor> for MotorDual {
5457 type Output = Rotor;
5458
5459 fn regressive_product(self, other: Rotor) -> Rotor {
5460 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + Simd32x2::from([self.group0()[1], self.group0()[0]]) * swizzle!(other.group0(), 1, 0) * Simd32x2::from([1.0, 0.0]) } }
5461 }
5462}
5463
5464impl OuterProduct<Rotor> for MotorDual {
5465 type Output = MotorDual;
5466
5467 fn outer_product(self, other: Rotor) -> MotorDual {
5468 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
5469 }
5470}
5471
5472impl InnerProduct<Rotor> for MotorDual {
5473 type Output = MotorDual;
5474
5475 fn inner_product(self, other: Rotor) -> MotorDual {
5476 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 0, 2, 2) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) } }
5477 }
5478}
5479
5480impl RightContraction<Rotor> for MotorDual {
5481 type Output = MotorDual;
5482
5483 fn right_contraction(self, other: Rotor) -> MotorDual {
5484 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
5485 }
5486}
5487
5488impl GeometricProduct<Point> for MotorDual {
5489 type Output = MotorDual;
5490
5491 fn geometric_product(self, other: Point) -> MotorDual {
5492 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[0], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) } }
5493 }
5494}
5495
5496impl RegressiveProduct<Point> for MotorDual {
5497 type Output = Motor;
5498
5499 fn regressive_product(self, other: Point) -> Motor {
5500 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5501 }
5502}
5503
5504impl InnerProduct<Point> for MotorDual {
5505 type Output = Plane;
5506
5507 fn inner_product(self, other: Point) -> Plane {
5508 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([1.0, 0.0, -1.0]) + Simd32x3::from(self.group0()[3]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([-1.0, 1.0, 0.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from([-1.0, 0.0, 0.0]) } }
5509 }
5510}
5511
5512impl LeftContraction<Point> for MotorDual {
5513 type Output = Plane;
5514
5515 fn left_contraction(self, other: Point) -> Plane {
5516 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[3]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([-1.0, 1.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[2]]) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([1.0, 0.0, -1.0]) } }
5517 }
5518}
5519
5520impl RegressiveProduct<IdealPoint> for MotorDual {
5521 type Output = Translator;
5522
5523 fn regressive_product(self, other: IdealPoint) -> Translator {
5524 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[1]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[0]]) * Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) } }
5525 }
5526}
5527
5528impl Into<Plane> for MotorDual {
5529 fn into(self) -> Plane {
5530 Plane { groups: PlaneGroups { g0: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
5531 }
5532}
5533
5534impl Add<Plane> for MotorDual {
5535 type Output = MotorDual;
5536
5537 fn add(self, other: Plane) -> MotorDual {
5538 MotorDual { groups: MotorDualGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5539 }
5540}
5541
5542impl AddAssign<Plane> for MotorDual {
5543 fn add_assign(&mut self, other: Plane) {
5544 *self = (*self).add(other);
5545 }
5546}
5547
5548impl Sub<Plane> for MotorDual {
5549 type Output = MotorDual;
5550
5551 fn sub(self, other: Plane) -> MotorDual {
5552 MotorDual { groups: MotorDualGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5553 }
5554}
5555
5556impl SubAssign<Plane> for MotorDual {
5557 fn sub_assign(&mut self, other: Plane) {
5558 *self = (*self).sub(other);
5559 }
5560}
5561
5562impl GeometricProduct<Plane> for MotorDual {
5563 type Output = Motor;
5564
5565 fn geometric_product(self, other: Plane) -> Motor {
5566 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[0], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
5567 }
5568}
5569
5570impl RegressiveProduct<Plane> for MotorDual {
5571 type Output = Plane;
5572
5573 fn regressive_product(self, other: Plane) -> Plane {
5574 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
5575 }
5576}
5577
5578impl OuterProduct<Plane> for MotorDual {
5579 type Output = Point;
5580
5581 fn outer_product(self, other: Plane) -> Point {
5582 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[3]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([0.0, 1.0, -1.0]) } }
5583 }
5584}
5585
5586impl InnerProduct<Plane> for MotorDual {
5587 type Output = Translator;
5588
5589 fn inner_product(self, other: Plane) -> Translator {
5590 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 1, 2) } }
5591 }
5592}
5593
5594impl LeftContraction<Plane> for MotorDual {
5595 type Output = f32;
5596
5597 fn left_contraction(self, other: Plane) -> f32 {
5598 self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
5599 }
5600}
5601
5602impl RightContraction<Plane> for MotorDual {
5603 type Output = Translator;
5604
5605 fn right_contraction(self, other: Plane) -> Translator {
5606 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 1, 2) } }
5607 }
5608}
5609
5610impl ScalarProduct<Plane> for MotorDual {
5611 type Output = f32;
5612
5613 fn scalar_product(self, other: Plane) -> f32 {
5614 self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
5615 }
5616}
5617
5618impl GeometricProduct<Translator> for MotorDual {
5619 type Output = MotorDual;
5620
5621 fn geometric_product(self, other: Translator) -> MotorDual {
5622 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[2], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[1], other.group0()[2], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5623 }
5624}
5625
5626impl RegressiveProduct<Translator> for MotorDual {
5627 type Output = Translator;
5628
5629 fn regressive_product(self, other: Translator) -> Translator {
5630 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 0) * Simd32x3::from([1.0, 0.0, 0.0]) } }
5631 }
5632}
5633
5634impl OuterProduct<Translator> for MotorDual {
5635 type Output = MotorDual;
5636
5637 fn outer_product(self, other: Translator) -> MotorDual {
5638 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[0]]) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5639 }
5640}
5641
5642impl InnerProduct<Translator> for MotorDual {
5643 type Output = MotorDual;
5644
5645 fn inner_product(self, other: Translator) -> MotorDual {
5646 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[0], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + swizzle!(self.group0(), 0, 1, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5647 }
5648}
5649
5650impl RightContraction<Translator> for MotorDual {
5651 type Output = MotorDual;
5652
5653 fn right_contraction(self, other: Translator) -> MotorDual {
5654 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
5655 }
5656}
5657
5658impl Add<Motor> for MotorDual {
5659 type Output = MultiVector;
5660
5661 fn add(self, other: Motor) -> MultiVector {
5662 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) + swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + swizzle!(other.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
5663 }
5664}
5665
5666impl Sub<Motor> for MotorDual {
5667 type Output = MultiVector;
5668
5669 fn sub(self, other: Motor) -> MultiVector {
5670 MultiVector { groups: MultiVectorGroups { g0: swizzle!(self.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) - swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) - swizzle!(other.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
5671 }
5672}
5673
5674impl GeometricProduct<Motor> for MotorDual {
5675 type Output = MotorDual;
5676
5677 fn geometric_product(self, other: Motor) -> MotorDual {
5678 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) } }
5679 }
5680}
5681
5682impl RegressiveProduct<Motor> for MotorDual {
5683 type Output = Motor;
5684
5685 fn regressive_product(self, other: Motor) -> Motor {
5686 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5687 }
5688}
5689
5690impl OuterProduct<Motor> for MotorDual {
5691 type Output = MotorDual;
5692
5693 fn outer_product(self, other: Motor) -> MotorDual {
5694 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5695 }
5696}
5697
5698impl InnerProduct<Motor> for MotorDual {
5699 type Output = MotorDual;
5700
5701 fn inner_product(self, other: Motor) -> MotorDual {
5702 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) } }
5703 }
5704}
5705
5706impl LeftContraction<Motor> for MotorDual {
5707 type Output = Plane;
5708
5709 fn left_contraction(self, other: Motor) -> Plane {
5710 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([-1.0, 1.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[2]]) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x3::from([1.0, 0.0, -1.0]) } }
5711 }
5712}
5713
5714impl RightContraction<Motor> for MotorDual {
5715 type Output = MotorDual;
5716
5717 fn right_contraction(self, other: Motor) -> MotorDual {
5718 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 2, 3) * swizzle!(other.group0(), 0, 1, 0, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
5719 }
5720}
5721
5722impl Add<MotorDual> for MotorDual {
5723 type Output = MotorDual;
5724
5725 fn add(self, other: MotorDual) -> MotorDual {
5726 MotorDual { groups: MotorDualGroups { g0: self.group0() + other.group0() } }
5727 }
5728}
5729
5730impl AddAssign<MotorDual> for MotorDual {
5731 fn add_assign(&mut self, other: MotorDual) {
5732 *self = (*self).add(other);
5733 }
5734}
5735
5736impl Sub<MotorDual> for MotorDual {
5737 type Output = MotorDual;
5738
5739 fn sub(self, other: MotorDual) -> MotorDual {
5740 MotorDual { groups: MotorDualGroups { g0: self.group0() - other.group0() } }
5741 }
5742}
5743
5744impl SubAssign<MotorDual> for MotorDual {
5745 fn sub_assign(&mut self, other: MotorDual) {
5746 *self = (*self).sub(other);
5747 }
5748}
5749
5750impl Mul<MotorDual> for MotorDual {
5751 type Output = MotorDual;
5752
5753 fn mul(self, other: MotorDual) -> MotorDual {
5754 MotorDual { groups: MotorDualGroups { g0: self.group0() * other.group0() } }
5755 }
5756}
5757
5758impl MulAssign<MotorDual> for MotorDual {
5759 fn mul_assign(&mut self, other: MotorDual) {
5760 *self = (*self).mul(other);
5761 }
5762}
5763
5764impl Div<MotorDual> for MotorDual {
5765 type Output = MotorDual;
5766
5767 fn div(self, other: MotorDual) -> MotorDual {
5768 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) / Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) } }
5769 }
5770}
5771
5772impl DivAssign<MotorDual> for MotorDual {
5773 fn div_assign(&mut self, other: MotorDual) {
5774 *self = (*self).div(other);
5775 }
5776}
5777
5778impl GeometricProduct<MotorDual> for MotorDual {
5779 type Output = Motor;
5780
5781 fn geometric_product(self, other: MotorDual) -> Motor {
5782 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 0, 0, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, 1.0]) } }
5783 }
5784}
5785
5786impl RegressiveProduct<MotorDual> for MotorDual {
5787 type Output = MotorDual;
5788
5789 fn regressive_product(self, other: MotorDual) -> MotorDual {
5790 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5791 }
5792}
5793
5794impl OuterProduct<MotorDual> for MotorDual {
5795 type Output = Point;
5796
5797 fn outer_product(self, other: MotorDual) -> Point {
5798 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[1]]) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[3]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[2]]) * Simd32x3::from([1.0, -1.0, 0.0]) + Simd32x3::from([self.group0()[0], self.group0()[1], self.group0()[1]]) * Simd32x3::from([other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x3::from([0.0, 1.0, -1.0]) } }
5799 }
5800}
5801
5802impl InnerProduct<MotorDual> for MotorDual {
5803 type Output = Translator;
5804
5805 fn inner_product(self, other: MotorDual) -> Translator {
5806 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[2]) * Simd32x3::from([other.group0()[2], other.group0()[0], other.group0()[2]]) * Simd32x3::from([1.0, 1.0, 0.0]) + Simd32x3::from(self.group0()[3]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[0], other.group0()[2], other.group0()[3]]) * Simd32x3::from([0.0, 1.0, 1.0]) } }
5807 }
5808}
5809
5810impl LeftContraction<MotorDual> for MotorDual {
5811 type Output = Translator;
5812
5813 fn left_contraction(self, other: MotorDual) -> Translator {
5814 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from([other.group0()[3], other.group0()[3], other.group0()[0]]) * Simd32x3::from([1.0, 0.0, 1.0]) + Simd32x3::from([self.group0()[2], self.group0()[2], self.group0()[0]]) * Simd32x3::from([other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x3::from([1.0, 1.0, 0.0]) } }
5815 }
5816}
5817
5818impl RightContraction<MotorDual> for MotorDual {
5819 type Output = Translator;
5820
5821 fn right_contraction(self, other: MotorDual) -> Translator {
5822 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[3]) * Simd32x3::from(other.group0()[3]) * Simd32x3::from([1.0, 0.0, 0.0]) + Simd32x3::from([self.group0()[2], self.group0()[0], self.group0()[0]]) * Simd32x3::from([other.group0()[2], other.group0()[2], other.group0()[3]]) } }
5823 }
5824}
5825
5826impl ScalarProduct<MotorDual> for MotorDual {
5827 type Output = f32;
5828
5829 fn scalar_product(self, other: MotorDual) -> f32 {
5830 self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
5831 }
5832}
5833
5834impl SquaredMagnitude for MotorDual {
5835 type Output = f32;
5836
5837 fn squared_magnitude(self) -> f32 {
5838 self.scalar_product(self.reversal())
5839 }
5840}
5841
5842impl Magnitude for MotorDual {
5843 type Output = f32;
5844
5845 fn magnitude(self) -> f32 {
5846 self.squared_magnitude().sqrt()
5847 }
5848}
5849
5850impl Mul<f32> for MotorDual {
5851 type Output = MotorDual;
5852
5853 fn mul(self, other: f32) -> MotorDual {
5854 self.geometric_product(other)
5855 }
5856}
5857
5858impl MulAssign<f32> for MotorDual {
5859 fn mul_assign(&mut self, other: f32) {
5860 *self = (*self).mul(other);
5861 }
5862}
5863
5864impl Signum for MotorDual {
5865 type Output = MotorDual;
5866
5867 fn signum(self) -> MotorDual {
5868 self.geometric_product(1.0 / self.magnitude())
5869 }
5870}
5871
5872impl Inverse for MotorDual {
5873 type Output = MotorDual;
5874
5875 fn inverse(self) -> MotorDual {
5876 self.reversal().geometric_product(1.0 / self.squared_magnitude())
5877 }
5878}
5879
5880impl GeometricQuotient<Motor> for IdealPoint {
5881 type Output = IdealPoint;
5882
5883 fn geometric_quotient(self, other: Motor) -> IdealPoint {
5884 self.geometric_product(other.inverse())
5885 }
5886}
5887
5888impl GeometricQuotient<Point> for IdealPoint {
5889 type Output = IdealPoint;
5890
5891 fn geometric_quotient(self, other: Point) -> IdealPoint {
5892 self.geometric_product(other.inverse())
5893 }
5894}
5895
5896impl GeometricQuotient<Rotor> for IdealPoint {
5897 type Output = IdealPoint;
5898
5899 fn geometric_quotient(self, other: Rotor) -> IdealPoint {
5900 self.geometric_product(other.inverse())
5901 }
5902}
5903
5904impl GeometricQuotient<f32> for IdealPoint {
5905 type Output = IdealPoint;
5906
5907 fn geometric_quotient(self, other: f32) -> IdealPoint {
5908 self.geometric_product(other.inverse())
5909 }
5910}
5911
5912impl GeometricQuotient<Translator> for IdealPoint {
5913 type Output = IdealPoint;
5914
5915 fn geometric_quotient(self, other: Translator) -> IdealPoint {
5916 self.geometric_product(other.inverse())
5917 }
5918}
5919
5920impl Transformation<IdealPoint> for Motor {
5921 type Output = IdealPoint;
5922
5923 fn transformation(self, other: IdealPoint) -> IdealPoint {
5924 self.geometric_product(other).geometric_product(self.reversal())
5925 }
5926}
5927
5928impl Powi for Motor {
5929 type Output = Motor;
5930
5931 fn powi(self, exponent: isize) -> Motor {
5932 if exponent == 0 {
5933 return Motor::one();
5934 }
5935 let mut x: Motor = if exponent < 0 { self.inverse() } else { self };
5936 let mut y: Motor = Motor::one();
5937 let mut n: isize = exponent.abs();
5938 while 1 < n {
5939 if n & 1 == 1 {
5940 y = x.geometric_product(y);
5941 }
5942 x = x.geometric_product(x);
5943 n = n >> 1;
5944 }
5945 x.geometric_product(y)
5946 }
5947}
5948
5949impl GeometricQuotient<Motor> for Motor {
5950 type Output = Motor;
5951
5952 fn geometric_quotient(self, other: Motor) -> Motor {
5953 self.geometric_product(other.inverse())
5954 }
5955}
5956
5957impl Transformation<Motor> for Motor {
5958 type Output = Motor;
5959
5960 fn transformation(self, other: Motor) -> Motor {
5961 self.geometric_product(other).geometric_product(self.reversal())
5962 }
5963}
5964
5965impl GeometricQuotient<MotorDual> for Motor {
5966 type Output = MotorDual;
5967
5968 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
5969 self.geometric_product(other.inverse())
5970 }
5971}
5972
5973impl Transformation<MotorDual> for Motor {
5974 type Output = MotorDual;
5975
5976 fn transformation(self, other: MotorDual) -> MotorDual {
5977 self.geometric_product(other).geometric_product(self.reversal())
5978 }
5979}
5980
5981impl GeometricQuotient<MultiVector> for Motor {
5982 type Output = MultiVector;
5983
5984 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
5985 self.geometric_product(other.inverse())
5986 }
5987}
5988
5989impl Transformation<MultiVector> for Motor {
5990 type Output = MultiVector;
5991
5992 fn transformation(self, other: MultiVector) -> MultiVector {
5993 self.geometric_product(other).geometric_product(self.reversal())
5994 }
5995}
5996
5997impl GeometricQuotient<Plane> for Motor {
5998 type Output = MotorDual;
5999
6000 fn geometric_quotient(self, other: Plane) -> MotorDual {
6001 self.geometric_product(other.inverse())
6002 }
6003}
6004
6005impl Transformation<Plane> for Motor {
6006 type Output = Plane;
6007
6008 fn transformation(self, other: Plane) -> Plane {
6009 self.geometric_product(other).geometric_product(self.reversal()).into()
6010 }
6011}
6012
6013impl GeometricQuotient<Point> for Motor {
6014 type Output = Motor;
6015
6016 fn geometric_quotient(self, other: Point) -> Motor {
6017 self.geometric_product(other.inverse())
6018 }
6019}
6020
6021impl Transformation<Point> for Motor {
6022 type Output = Point;
6023
6024 fn transformation(self, other: Point) -> Point {
6025 self.geometric_product(other).geometric_product(self.reversal()).into()
6026 }
6027}
6028
6029impl GeometricQuotient<Rotor> for Motor {
6030 type Output = Motor;
6031
6032 fn geometric_quotient(self, other: Rotor) -> Motor {
6033 self.geometric_product(other.inverse())
6034 }
6035}
6036
6037impl Transformation<Rotor> for Motor {
6038 type Output = Rotor;
6039
6040 fn transformation(self, other: Rotor) -> Rotor {
6041 self.geometric_product(other).geometric_product(self.reversal()).into()
6042 }
6043}
6044
6045impl GeometricQuotient<f32> for Motor {
6046 type Output = Motor;
6047
6048 fn geometric_quotient(self, other: f32) -> Motor {
6049 self.geometric_product(other.inverse())
6050 }
6051}
6052
6053impl Transformation<f32> for Motor {
6054 type Output = f32;
6055
6056 fn transformation(self, other: f32) -> f32 {
6057 self.geometric_product(other).geometric_product(self.reversal()).into()
6058 }
6059}
6060
6061impl GeometricQuotient<Translator> for Motor {
6062 type Output = Motor;
6063
6064 fn geometric_quotient(self, other: Translator) -> Motor {
6065 self.geometric_product(other.inverse())
6066 }
6067}
6068
6069impl Transformation<Translator> for Motor {
6070 type Output = Translator;
6071
6072 fn transformation(self, other: Translator) -> Translator {
6073 self.geometric_product(other).geometric_product(self.reversal()).into()
6074 }
6075}
6076
6077impl GeometricQuotient<Motor> for MotorDual {
6078 type Output = MotorDual;
6079
6080 fn geometric_quotient(self, other: Motor) -> MotorDual {
6081 self.geometric_product(other.inverse())
6082 }
6083}
6084
6085impl Transformation<Motor> for MotorDual {
6086 type Output = Motor;
6087
6088 fn transformation(self, other: Motor) -> Motor {
6089 self.geometric_product(other).geometric_product(self.reversal())
6090 }
6091}
6092
6093impl GeometricQuotient<MotorDual> for MotorDual {
6094 type Output = Motor;
6095
6096 fn geometric_quotient(self, other: MotorDual) -> Motor {
6097 self.geometric_product(other.inverse())
6098 }
6099}
6100
6101impl Transformation<MotorDual> for MotorDual {
6102 type Output = MotorDual;
6103
6104 fn transformation(self, other: MotorDual) -> MotorDual {
6105 self.geometric_product(other).geometric_product(self.reversal())
6106 }
6107}
6108
6109impl GeometricQuotient<MultiVector> for MotorDual {
6110 type Output = MultiVector;
6111
6112 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6113 self.geometric_product(other.inverse())
6114 }
6115}
6116
6117impl Transformation<MultiVector> for MotorDual {
6118 type Output = MultiVector;
6119
6120 fn transformation(self, other: MultiVector) -> MultiVector {
6121 self.geometric_product(other).geometric_product(self.reversal())
6122 }
6123}
6124
6125impl GeometricQuotient<Plane> for MotorDual {
6126 type Output = Motor;
6127
6128 fn geometric_quotient(self, other: Plane) -> Motor {
6129 self.geometric_product(other.inverse())
6130 }
6131}
6132
6133impl Transformation<Plane> for MotorDual {
6134 type Output = Plane;
6135
6136 fn transformation(self, other: Plane) -> Plane {
6137 self.geometric_product(other).geometric_product(self.reversal()).into()
6138 }
6139}
6140
6141impl GeometricQuotient<Point> for MotorDual {
6142 type Output = MotorDual;
6143
6144 fn geometric_quotient(self, other: Point) -> MotorDual {
6145 self.geometric_product(other.inverse())
6146 }
6147}
6148
6149impl Transformation<Point> for MotorDual {
6150 type Output = Point;
6151
6152 fn transformation(self, other: Point) -> Point {
6153 self.geometric_product(other).geometric_product(self.reversal()).into()
6154 }
6155}
6156
6157impl GeometricQuotient<Rotor> for MotorDual {
6158 type Output = MotorDual;
6159
6160 fn geometric_quotient(self, other: Rotor) -> MotorDual {
6161 self.geometric_product(other.inverse())
6162 }
6163}
6164
6165impl Transformation<Rotor> for MotorDual {
6166 type Output = Rotor;
6167
6168 fn transformation(self, other: Rotor) -> Rotor {
6169 self.geometric_product(other).geometric_product(self.reversal()).into()
6170 }
6171}
6172
6173impl GeometricQuotient<f32> for MotorDual {
6174 type Output = MotorDual;
6175
6176 fn geometric_quotient(self, other: f32) -> MotorDual {
6177 self.geometric_product(other.inverse())
6178 }
6179}
6180
6181impl Transformation<f32> for MotorDual {
6182 type Output = f32;
6183
6184 fn transformation(self, other: f32) -> f32 {
6185 self.geometric_product(other).geometric_product(self.reversal()).into()
6186 }
6187}
6188
6189impl GeometricQuotient<Translator> for MotorDual {
6190 type Output = MotorDual;
6191
6192 fn geometric_quotient(self, other: Translator) -> MotorDual {
6193 self.geometric_product(other.inverse())
6194 }
6195}
6196
6197impl Transformation<Translator> for MotorDual {
6198 type Output = Translator;
6199
6200 fn transformation(self, other: Translator) -> Translator {
6201 self.geometric_product(other).geometric_product(self.reversal()).into()
6202 }
6203}
6204
6205impl GeometricQuotient<Motor> for MultiVector {
6206 type Output = MultiVector;
6207
6208 fn geometric_quotient(self, other: Motor) -> MultiVector {
6209 self.geometric_product(other.inverse())
6210 }
6211}
6212
6213impl Transformation<Motor> for MultiVector {
6214 type Output = Motor;
6215
6216 fn transformation(self, other: Motor) -> Motor {
6217 self.geometric_product(other).geometric_product(self.reversal()).into()
6218 }
6219}
6220
6221impl GeometricQuotient<MotorDual> for MultiVector {
6222 type Output = MultiVector;
6223
6224 fn geometric_quotient(self, other: MotorDual) -> MultiVector {
6225 self.geometric_product(other.inverse())
6226 }
6227}
6228
6229impl Transformation<MotorDual> for MultiVector {
6230 type Output = MotorDual;
6231
6232 fn transformation(self, other: MotorDual) -> MotorDual {
6233 self.geometric_product(other).geometric_product(self.reversal()).into()
6234 }
6235}
6236
6237impl Powi for MultiVector {
6238 type Output = MultiVector;
6239
6240 fn powi(self, exponent: isize) -> MultiVector {
6241 if exponent == 0 {
6242 return MultiVector::one();
6243 }
6244 let mut x: MultiVector = if exponent < 0 { self.inverse() } else { self };
6245 let mut y: MultiVector = MultiVector::one();
6246 let mut n: isize = exponent.abs();
6247 while 1 < n {
6248 if n & 1 == 1 {
6249 y = x.geometric_product(y);
6250 }
6251 x = x.geometric_product(x);
6252 n = n >> 1;
6253 }
6254 x.geometric_product(y)
6255 }
6256}
6257
6258impl GeometricQuotient<MultiVector> for MultiVector {
6259 type Output = MultiVector;
6260
6261 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6262 self.geometric_product(other.inverse())
6263 }
6264}
6265
6266impl Transformation<MultiVector> for MultiVector {
6267 type Output = MultiVector;
6268
6269 fn transformation(self, other: MultiVector) -> MultiVector {
6270 self.geometric_product(other).geometric_product(self.reversal())
6271 }
6272}
6273
6274impl GeometricQuotient<Plane> for MultiVector {
6275 type Output = MultiVector;
6276
6277 fn geometric_quotient(self, other: Plane) -> MultiVector {
6278 self.geometric_product(other.inverse())
6279 }
6280}
6281
6282impl Transformation<Plane> for MultiVector {
6283 type Output = Plane;
6284
6285 fn transformation(self, other: Plane) -> Plane {
6286 self.geometric_product(other).geometric_product(self.reversal()).into()
6287 }
6288}
6289
6290impl GeometricQuotient<Point> for MultiVector {
6291 type Output = MultiVector;
6292
6293 fn geometric_quotient(self, other: Point) -> MultiVector {
6294 self.geometric_product(other.inverse())
6295 }
6296}
6297
6298impl Transformation<Point> for MultiVector {
6299 type Output = Point;
6300
6301 fn transformation(self, other: Point) -> Point {
6302 self.geometric_product(other).geometric_product(self.reversal()).into()
6303 }
6304}
6305
6306impl GeometricQuotient<Rotor> for MultiVector {
6307 type Output = MultiVector;
6308
6309 fn geometric_quotient(self, other: Rotor) -> MultiVector {
6310 self.geometric_product(other.inverse())
6311 }
6312}
6313
6314impl Transformation<Rotor> for MultiVector {
6315 type Output = Rotor;
6316
6317 fn transformation(self, other: Rotor) -> Rotor {
6318 self.geometric_product(other).geometric_product(self.reversal()).into()
6319 }
6320}
6321
6322impl GeometricQuotient<f32> for MultiVector {
6323 type Output = MultiVector;
6324
6325 fn geometric_quotient(self, other: f32) -> MultiVector {
6326 self.geometric_product(other.inverse())
6327 }
6328}
6329
6330impl Transformation<f32> for MultiVector {
6331 type Output = f32;
6332
6333 fn transformation(self, other: f32) -> f32 {
6334 self.geometric_product(other).geometric_product(self.reversal()).into()
6335 }
6336}
6337
6338impl GeometricQuotient<Translator> for MultiVector {
6339 type Output = MultiVector;
6340
6341 fn geometric_quotient(self, other: Translator) -> MultiVector {
6342 self.geometric_product(other.inverse())
6343 }
6344}
6345
6346impl Transformation<Translator> for MultiVector {
6347 type Output = Translator;
6348
6349 fn transformation(self, other: Translator) -> Translator {
6350 self.geometric_product(other).geometric_product(self.reversal()).into()
6351 }
6352}
6353
6354impl GeometricQuotient<Motor> for Plane {
6355 type Output = MotorDual;
6356
6357 fn geometric_quotient(self, other: Motor) -> MotorDual {
6358 self.geometric_product(other.inverse())
6359 }
6360}
6361
6362impl Transformation<Motor> for Plane {
6363 type Output = Motor;
6364
6365 fn transformation(self, other: Motor) -> Motor {
6366 self.geometric_product(other).geometric_product(self.reversal())
6367 }
6368}
6369
6370impl GeometricQuotient<MotorDual> for Plane {
6371 type Output = Motor;
6372
6373 fn geometric_quotient(self, other: MotorDual) -> Motor {
6374 self.geometric_product(other.inverse())
6375 }
6376}
6377
6378impl Transformation<MotorDual> for Plane {
6379 type Output = MotorDual;
6380
6381 fn transformation(self, other: MotorDual) -> MotorDual {
6382 self.geometric_product(other).geometric_product(self.reversal())
6383 }
6384}
6385
6386impl GeometricQuotient<MultiVector> for Plane {
6387 type Output = MultiVector;
6388
6389 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6390 self.geometric_product(other.inverse())
6391 }
6392}
6393
6394impl Transformation<MultiVector> for Plane {
6395 type Output = MultiVector;
6396
6397 fn transformation(self, other: MultiVector) -> MultiVector {
6398 self.geometric_product(other).geometric_product(self.reversal())
6399 }
6400}
6401
6402impl GeometricQuotient<Plane> for Plane {
6403 type Output = Motor;
6404
6405 fn geometric_quotient(self, other: Plane) -> Motor {
6406 self.geometric_product(other.inverse())
6407 }
6408}
6409
6410impl Transformation<Plane> for Plane {
6411 type Output = Plane;
6412
6413 fn transformation(self, other: Plane) -> Plane {
6414 self.geometric_product(other).geometric_product(self.reversal()).into()
6415 }
6416}
6417
6418impl GeometricQuotient<Point> for Plane {
6419 type Output = MotorDual;
6420
6421 fn geometric_quotient(self, other: Point) -> MotorDual {
6422 self.geometric_product(other.inverse())
6423 }
6424}
6425
6426impl Transformation<Point> for Plane {
6427 type Output = Point;
6428
6429 fn transformation(self, other: Point) -> Point {
6430 self.geometric_product(other).geometric_product(self.reversal()).into()
6431 }
6432}
6433
6434impl GeometricQuotient<Rotor> for Plane {
6435 type Output = MotorDual;
6436
6437 fn geometric_quotient(self, other: Rotor) -> MotorDual {
6438 self.geometric_product(other.inverse())
6439 }
6440}
6441
6442impl Transformation<Rotor> for Plane {
6443 type Output = Rotor;
6444
6445 fn transformation(self, other: Rotor) -> Rotor {
6446 self.geometric_product(other).geometric_product(self.reversal()).into()
6447 }
6448}
6449
6450impl GeometricQuotient<f32> for Plane {
6451 type Output = Plane;
6452
6453 fn geometric_quotient(self, other: f32) -> Plane {
6454 self.geometric_product(other.inverse())
6455 }
6456}
6457
6458impl Transformation<f32> for Plane {
6459 type Output = f32;
6460
6461 fn transformation(self, other: f32) -> f32 {
6462 self.geometric_product(other).geometric_product(self.reversal()).into()
6463 }
6464}
6465
6466impl GeometricQuotient<Translator> for Plane {
6467 type Output = MotorDual;
6468
6469 fn geometric_quotient(self, other: Translator) -> MotorDual {
6470 self.geometric_product(other.inverse())
6471 }
6472}
6473
6474impl Transformation<Translator> for Plane {
6475 type Output = Translator;
6476
6477 fn transformation(self, other: Translator) -> Translator {
6478 self.geometric_product(other).geometric_product(self.reversal()).into()
6479 }
6480}
6481
6482impl Transformation<IdealPoint> for Point {
6483 type Output = IdealPoint;
6484
6485 fn transformation(self, other: IdealPoint) -> IdealPoint {
6486 self.geometric_product(other).geometric_product(self.reversal())
6487 }
6488}
6489
6490impl GeometricQuotient<Motor> for Point {
6491 type Output = Motor;
6492
6493 fn geometric_quotient(self, other: Motor) -> Motor {
6494 self.geometric_product(other.inverse())
6495 }
6496}
6497
6498impl Transformation<Motor> for Point {
6499 type Output = Motor;
6500
6501 fn transformation(self, other: Motor) -> Motor {
6502 self.geometric_product(other).geometric_product(self.reversal())
6503 }
6504}
6505
6506impl GeometricQuotient<MotorDual> for Point {
6507 type Output = MotorDual;
6508
6509 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
6510 self.geometric_product(other.inverse())
6511 }
6512}
6513
6514impl Transformation<MotorDual> for Point {
6515 type Output = MotorDual;
6516
6517 fn transformation(self, other: MotorDual) -> MotorDual {
6518 self.geometric_product(other).geometric_product(self.reversal())
6519 }
6520}
6521
6522impl GeometricQuotient<MultiVector> for Point {
6523 type Output = MultiVector;
6524
6525 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6526 self.geometric_product(other.inverse())
6527 }
6528}
6529
6530impl Transformation<MultiVector> for Point {
6531 type Output = MultiVector;
6532
6533 fn transformation(self, other: MultiVector) -> MultiVector {
6534 self.geometric_product(other).geometric_product(self.reversal())
6535 }
6536}
6537
6538impl GeometricQuotient<Plane> for Point {
6539 type Output = MotorDual;
6540
6541 fn geometric_quotient(self, other: Plane) -> MotorDual {
6542 self.geometric_product(other.inverse())
6543 }
6544}
6545
6546impl Transformation<Plane> for Point {
6547 type Output = Plane;
6548
6549 fn transformation(self, other: Plane) -> Plane {
6550 self.geometric_product(other).geometric_product(self.reversal()).into()
6551 }
6552}
6553
6554impl GeometricQuotient<Point> for Point {
6555 type Output = Translator;
6556
6557 fn geometric_quotient(self, other: Point) -> Translator {
6558 self.geometric_product(other.inverse())
6559 }
6560}
6561
6562impl Transformation<Point> for Point {
6563 type Output = Point;
6564
6565 fn transformation(self, other: Point) -> Point {
6566 self.geometric_product(other).geometric_product(self.reversal())
6567 }
6568}
6569
6570impl GeometricQuotient<Rotor> for Point {
6571 type Output = Motor;
6572
6573 fn geometric_quotient(self, other: Rotor) -> Motor {
6574 self.geometric_product(other.inverse())
6575 }
6576}
6577
6578impl Transformation<Rotor> for Point {
6579 type Output = Rotor;
6580
6581 fn transformation(self, other: Rotor) -> Rotor {
6582 self.geometric_product(other).geometric_product(self.reversal()).into()
6583 }
6584}
6585
6586impl GeometricQuotient<f32> for Point {
6587 type Output = Point;
6588
6589 fn geometric_quotient(self, other: f32) -> Point {
6590 self.geometric_product(other.inverse())
6591 }
6592}
6593
6594impl Transformation<f32> for Point {
6595 type Output = f32;
6596
6597 fn transformation(self, other: f32) -> f32 {
6598 self.geometric_product(other).geometric_product(self.reversal()).into()
6599 }
6600}
6601
6602impl GeometricQuotient<Translator> for Point {
6603 type Output = Point;
6604
6605 fn geometric_quotient(self, other: Translator) -> Point {
6606 self.geometric_product(other.inverse())
6607 }
6608}
6609
6610impl Transformation<Translator> for Point {
6611 type Output = Translator;
6612
6613 fn transformation(self, other: Translator) -> Translator {
6614 self.geometric_product(other).geometric_product(self.reversal())
6615 }
6616}
6617
6618impl Transformation<IdealPoint> for Rotor {
6619 type Output = IdealPoint;
6620
6621 fn transformation(self, other: IdealPoint) -> IdealPoint {
6622 self.geometric_product(other).geometric_product(self.reversal())
6623 }
6624}
6625
6626impl GeometricQuotient<Motor> for Rotor {
6627 type Output = Motor;
6628
6629 fn geometric_quotient(self, other: Motor) -> Motor {
6630 self.geometric_product(other.inverse())
6631 }
6632}
6633
6634impl Transformation<Motor> for Rotor {
6635 type Output = Motor;
6636
6637 fn transformation(self, other: Motor) -> Motor {
6638 self.geometric_product(other).geometric_product(self.reversal())
6639 }
6640}
6641
6642impl GeometricQuotient<MotorDual> for Rotor {
6643 type Output = MotorDual;
6644
6645 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
6646 self.geometric_product(other.inverse())
6647 }
6648}
6649
6650impl Transformation<MotorDual> for Rotor {
6651 type Output = MotorDual;
6652
6653 fn transformation(self, other: MotorDual) -> MotorDual {
6654 self.geometric_product(other).geometric_product(self.reversal())
6655 }
6656}
6657
6658impl GeometricQuotient<MultiVector> for Rotor {
6659 type Output = MultiVector;
6660
6661 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6662 self.geometric_product(other.inverse())
6663 }
6664}
6665
6666impl Transformation<MultiVector> for Rotor {
6667 type Output = MultiVector;
6668
6669 fn transformation(self, other: MultiVector) -> MultiVector {
6670 self.geometric_product(other).geometric_product(self.reversal())
6671 }
6672}
6673
6674impl GeometricQuotient<Plane> for Rotor {
6675 type Output = MotorDual;
6676
6677 fn geometric_quotient(self, other: Plane) -> MotorDual {
6678 self.geometric_product(other.inverse())
6679 }
6680}
6681
6682impl Transformation<Plane> for Rotor {
6683 type Output = Plane;
6684
6685 fn transformation(self, other: Plane) -> Plane {
6686 self.geometric_product(other).geometric_product(self.reversal()).into()
6687 }
6688}
6689
6690impl GeometricQuotient<Point> for Rotor {
6691 type Output = Motor;
6692
6693 fn geometric_quotient(self, other: Point) -> Motor {
6694 self.geometric_product(other.inverse())
6695 }
6696}
6697
6698impl Transformation<Point> for Rotor {
6699 type Output = Point;
6700
6701 fn transformation(self, other: Point) -> Point {
6702 self.geometric_product(other).geometric_product(self.reversal()).into()
6703 }
6704}
6705
6706impl Powi for Rotor {
6707 type Output = Rotor;
6708
6709 fn powi(self, exponent: isize) -> Rotor {
6710 if exponent == 0 {
6711 return Rotor::one();
6712 }
6713 let mut x: Rotor = if exponent < 0 { self.inverse() } else { self };
6714 let mut y: Rotor = Rotor::one();
6715 let mut n: isize = exponent.abs();
6716 while 1 < n {
6717 if n & 1 == 1 {
6718 y = x.geometric_product(y);
6719 }
6720 x = x.geometric_product(x);
6721 n = n >> 1;
6722 }
6723 x.geometric_product(y)
6724 }
6725}
6726
6727impl GeometricQuotient<Rotor> for Rotor {
6728 type Output = Rotor;
6729
6730 fn geometric_quotient(self, other: Rotor) -> Rotor {
6731 self.geometric_product(other.inverse())
6732 }
6733}
6734
6735impl Transformation<Rotor> for Rotor {
6736 type Output = Rotor;
6737
6738 fn transformation(self, other: Rotor) -> Rotor {
6739 self.geometric_product(other).geometric_product(self.reversal())
6740 }
6741}
6742
6743impl GeometricQuotient<f32> for Rotor {
6744 type Output = Rotor;
6745
6746 fn geometric_quotient(self, other: f32) -> Rotor {
6747 self.geometric_product(other.inverse())
6748 }
6749}
6750
6751impl Transformation<f32> for Rotor {
6752 type Output = f32;
6753
6754 fn transformation(self, other: f32) -> f32 {
6755 self.geometric_product(other).geometric_product(self.reversal()).into()
6756 }
6757}
6758
6759impl GeometricQuotient<Translator> for Rotor {
6760 type Output = Motor;
6761
6762 fn geometric_quotient(self, other: Translator) -> Motor {
6763 self.geometric_product(other.inverse())
6764 }
6765}
6766
6767impl Transformation<Translator> for Rotor {
6768 type Output = Translator;
6769
6770 fn transformation(self, other: Translator) -> Translator {
6771 self.geometric_product(other).geometric_product(self.reversal()).into()
6772 }
6773}
6774
6775impl Transformation<IdealPoint> for f32 {
6776 type Output = IdealPoint;
6777
6778 fn transformation(self, other: IdealPoint) -> IdealPoint {
6779 self.geometric_product(other).geometric_product(self.reversal())
6780 }
6781}
6782
6783impl GeometricQuotient<Motor> for f32 {
6784 type Output = Motor;
6785
6786 fn geometric_quotient(self, other: Motor) -> Motor {
6787 self.geometric_product(other.inverse())
6788 }
6789}
6790
6791impl Transformation<Motor> for f32 {
6792 type Output = Motor;
6793
6794 fn transformation(self, other: Motor) -> Motor {
6795 self.geometric_product(other).geometric_product(self.reversal())
6796 }
6797}
6798
6799impl GeometricQuotient<MotorDual> for f32 {
6800 type Output = MotorDual;
6801
6802 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
6803 self.geometric_product(other.inverse())
6804 }
6805}
6806
6807impl Transformation<MotorDual> for f32 {
6808 type Output = MotorDual;
6809
6810 fn transformation(self, other: MotorDual) -> MotorDual {
6811 self.geometric_product(other).geometric_product(self.reversal())
6812 }
6813}
6814
6815impl GeometricQuotient<MultiVector> for f32 {
6816 type Output = MultiVector;
6817
6818 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6819 self.geometric_product(other.inverse())
6820 }
6821}
6822
6823impl Transformation<MultiVector> for f32 {
6824 type Output = MultiVector;
6825
6826 fn transformation(self, other: MultiVector) -> MultiVector {
6827 self.geometric_product(other).geometric_product(self.reversal())
6828 }
6829}
6830
6831impl GeometricQuotient<Plane> for f32 {
6832 type Output = Plane;
6833
6834 fn geometric_quotient(self, other: Plane) -> Plane {
6835 self.geometric_product(other.inverse())
6836 }
6837}
6838
6839impl Transformation<Plane> for f32 {
6840 type Output = Plane;
6841
6842 fn transformation(self, other: Plane) -> Plane {
6843 self.geometric_product(other).geometric_product(self.reversal())
6844 }
6845}
6846
6847impl GeometricQuotient<Point> for f32 {
6848 type Output = Point;
6849
6850 fn geometric_quotient(self, other: Point) -> Point {
6851 self.geometric_product(other.inverse())
6852 }
6853}
6854
6855impl Transformation<Point> for f32 {
6856 type Output = Point;
6857
6858 fn transformation(self, other: Point) -> Point {
6859 self.geometric_product(other).geometric_product(self.reversal())
6860 }
6861}
6862
6863impl GeometricQuotient<Rotor> for f32 {
6864 type Output = Rotor;
6865
6866 fn geometric_quotient(self, other: Rotor) -> Rotor {
6867 self.geometric_product(other.inverse())
6868 }
6869}
6870
6871impl Transformation<Rotor> for f32 {
6872 type Output = Rotor;
6873
6874 fn transformation(self, other: Rotor) -> Rotor {
6875 self.geometric_product(other).geometric_product(self.reversal())
6876 }
6877}
6878
6879impl GeometricQuotient<Translator> for f32 {
6880 type Output = Translator;
6881
6882 fn geometric_quotient(self, other: Translator) -> Translator {
6883 self.geometric_product(other.inverse())
6884 }
6885}
6886
6887impl Transformation<Translator> for f32 {
6888 type Output = Translator;
6889
6890 fn transformation(self, other: Translator) -> Translator {
6891 self.geometric_product(other).geometric_product(self.reversal())
6892 }
6893}
6894
6895impl Transformation<IdealPoint> for Translator {
6896 type Output = IdealPoint;
6897
6898 fn transformation(self, other: IdealPoint) -> IdealPoint {
6899 self.geometric_product(other).geometric_product(self.reversal())
6900 }
6901}
6902
6903impl GeometricQuotient<Motor> for Translator {
6904 type Output = Motor;
6905
6906 fn geometric_quotient(self, other: Motor) -> Motor {
6907 self.geometric_product(other.inverse())
6908 }
6909}
6910
6911impl Transformation<Motor> for Translator {
6912 type Output = Motor;
6913
6914 fn transformation(self, other: Motor) -> Motor {
6915 self.geometric_product(other).geometric_product(self.reversal())
6916 }
6917}
6918
6919impl GeometricQuotient<MotorDual> for Translator {
6920 type Output = MotorDual;
6921
6922 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
6923 self.geometric_product(other.inverse())
6924 }
6925}
6926
6927impl Transformation<MotorDual> for Translator {
6928 type Output = MotorDual;
6929
6930 fn transformation(self, other: MotorDual) -> MotorDual {
6931 self.geometric_product(other).geometric_product(self.reversal())
6932 }
6933}
6934
6935impl GeometricQuotient<MultiVector> for Translator {
6936 type Output = MultiVector;
6937
6938 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6939 self.geometric_product(other.inverse())
6940 }
6941}
6942
6943impl Transformation<MultiVector> for Translator {
6944 type Output = MultiVector;
6945
6946 fn transformation(self, other: MultiVector) -> MultiVector {
6947 self.geometric_product(other).geometric_product(self.reversal())
6948 }
6949}
6950
6951impl GeometricQuotient<Plane> for Translator {
6952 type Output = MotorDual;
6953
6954 fn geometric_quotient(self, other: Plane) -> MotorDual {
6955 self.geometric_product(other.inverse())
6956 }
6957}
6958
6959impl Transformation<Plane> for Translator {
6960 type Output = Plane;
6961
6962 fn transformation(self, other: Plane) -> Plane {
6963 self.geometric_product(other).geometric_product(self.reversal()).into()
6964 }
6965}
6966
6967impl GeometricQuotient<Point> for Translator {
6968 type Output = Point;
6969
6970 fn geometric_quotient(self, other: Point) -> Point {
6971 self.geometric_product(other.inverse())
6972 }
6973}
6974
6975impl Transformation<Point> for Translator {
6976 type Output = Point;
6977
6978 fn transformation(self, other: Point) -> Point {
6979 self.geometric_product(other).geometric_product(self.reversal())
6980 }
6981}
6982
6983impl GeometricQuotient<Rotor> for Translator {
6984 type Output = Motor;
6985
6986 fn geometric_quotient(self, other: Rotor) -> Motor {
6987 self.geometric_product(other.inverse())
6988 }
6989}
6990
6991impl Transformation<Rotor> for Translator {
6992 type Output = Rotor;
6993
6994 fn transformation(self, other: Rotor) -> Rotor {
6995 self.geometric_product(other).geometric_product(self.reversal()).into()
6996 }
6997}
6998
6999impl GeometricQuotient<f32> for Translator {
7000 type Output = Translator;
7001
7002 fn geometric_quotient(self, other: f32) -> Translator {
7003 self.geometric_product(other.inverse())
7004 }
7005}
7006
7007impl Transformation<f32> for Translator {
7008 type Output = f32;
7009
7010 fn transformation(self, other: f32) -> f32 {
7011 self.geometric_product(other).geometric_product(self.reversal()).into()
7012 }
7013}
7014
7015impl Powi for Translator {
7016 type Output = Translator;
7017
7018 fn powi(self, exponent: isize) -> Translator {
7019 if exponent == 0 {
7020 return Translator::one();
7021 }
7022 let mut x: Translator = if exponent < 0 { self.inverse() } else { self };
7023 let mut y: Translator = Translator::one();
7024 let mut n: isize = exponent.abs();
7025 while 1 < n {
7026 if n & 1 == 1 {
7027 y = x.geometric_product(y);
7028 }
7029 x = x.geometric_product(x);
7030 n = n >> 1;
7031 }
7032 x.geometric_product(y)
7033 }
7034}
7035
7036impl GeometricQuotient<Translator> for Translator {
7037 type Output = Translator;
7038
7039 fn geometric_quotient(self, other: Translator) -> Translator {
7040 self.geometric_product(other.inverse())
7041 }
7042}
7043
7044impl Transformation<Translator> for Translator {
7045 type Output = Translator;
7046
7047 fn transformation(self, other: Translator) -> Translator {
7048 self.geometric_product(other).geometric_product(self.reversal())
7049 }
7050}
7051