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]) + Simd32x4::from(self.group1()[0]) * other.group1() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 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]) + Simd32x4::from(self.group1()[0]) * other.group1() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 2, 2, 0, 1) * Simd32x4::from([-1.0, 0.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 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]) + Simd32x4::from(self.group1()[0]) * other.group1() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group1()[1]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 2, 2, 2, 1) * Simd32x4::from([-1.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[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() + 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.group1()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 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] + self.group1()[0] * other.group1()[0] - self.group1()[1] * other.group1()[1] - self.group1()[2] * other.group1()[2] - self.group1()[3] * other.group1()[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: Simd32x4::from(self.group1()[0]) * 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()[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.group1()[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.group1()[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]) + 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] - self.group1()[2] * other.group0()[1] - self.group1()[3] * other.group0()[2]
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 GeometricProduct<IdealPoint> for MultiVector {
1425 type Output = MultiVector;
1426
1427 fn geometric_product(self, other: IdealPoint) -> MultiVector {
1428 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group1()[1]) * 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.group1()[3]) * 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(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[1]) * 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()[3]) * 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(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1429 }
1430}
1431
1432impl ScalarProduct<IdealPoint> for MultiVector {
1433 type Output = f32;
1434
1435 fn scalar_product(self, other: IdealPoint) -> f32 {
1436 0.0 - self.group1()[2] * other.group0()[0] - self.group1()[3] * other.group0()[1]
1437 }
1438}
1439
1440impl Into<Plane> for MultiVector {
1441 fn into(self) -> Plane {
1442 Plane { groups: PlaneGroups { g0: Simd32x3::from([self.group1()[0], self.group0()[3], self.group0()[2]]) } }
1443 }
1444}
1445
1446impl Add<Plane> for MultiVector {
1447 type Output = MultiVector;
1448
1449 fn add(self, other: Plane) -> MultiVector {
1450 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]) } }
1451 }
1452}
1453
1454impl AddAssign<Plane> for MultiVector {
1455 fn add_assign(&mut self, other: Plane) {
1456 *self = (*self).add(other);
1457 }
1458}
1459
1460impl Sub<Plane> for MultiVector {
1461 type Output = MultiVector;
1462
1463 fn sub(self, other: Plane) -> MultiVector {
1464 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]) } }
1465 }
1466}
1467
1468impl SubAssign<Plane> for MultiVector {
1469 fn sub_assign(&mut self, other: Plane) {
1470 *self = (*self).sub(other);
1471 }
1472}
1473
1474impl GeometricProduct<Plane> for MultiVector {
1475 type Output = MultiVector;
1476
1477 fn geometric_product(self, other: Plane) -> MultiVector {
1478 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]) + 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()[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]) } }
1479 }
1480}
1481
1482impl ScalarProduct<Plane> for MultiVector {
1483 type Output = f32;
1484
1485 fn scalar_product(self, other: Plane) -> f32 {
1486 self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[1] + self.group1()[0] * other.group0()[0]
1487 }
1488}
1489
1490impl Into<Translator> for MultiVector {
1491 fn into(self) -> Translator {
1492 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group1()[2], self.group1()[3]]) } }
1493 }
1494}
1495
1496impl Add<Translator> for MultiVector {
1497 type Output = MultiVector;
1498
1499 fn add(self, other: Translator) -> MultiVector {
1500 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]) } }
1501 }
1502}
1503
1504impl AddAssign<Translator> for MultiVector {
1505 fn add_assign(&mut self, other: Translator) {
1506 *self = (*self).add(other);
1507 }
1508}
1509
1510impl Sub<Translator> for MultiVector {
1511 type Output = MultiVector;
1512
1513 fn sub(self, other: Translator) -> MultiVector {
1514 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]) } }
1515 }
1516}
1517
1518impl SubAssign<Translator> for MultiVector {
1519 fn sub_assign(&mut self, other: Translator) {
1520 *self = (*self).sub(other);
1521 }
1522}
1523
1524impl GeometricProduct<Translator> for MultiVector {
1525 type Output = MultiVector;
1526
1527 fn geometric_product(self, other: Translator) -> MultiVector {
1528 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group1()[0]) * 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()[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.group1()[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.group1()[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]) + 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]) } }
1529 }
1530}
1531
1532impl OuterProduct<Translator> for MultiVector {
1533 type Output = MultiVector;
1534
1535 fn outer_product(self, other: Translator) -> MultiVector {
1536 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]]) } }
1537 }
1538}
1539
1540impl InnerProduct<Translator> for MultiVector {
1541 type Output = MultiVector;
1542
1543 fn inner_product(self, other: Translator) -> MultiVector {
1544 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group1()[0]) * 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()[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.group1()[2]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + 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]) } }
1545 }
1546}
1547
1548impl RightContraction<Translator> for MultiVector {
1549 type Output = MultiVector;
1550
1551 fn right_contraction(self, other: Translator) -> MultiVector {
1552 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group1()[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.group1()[2]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: self.group1() * Simd32x4::from(other.group0()[0]) } }
1553 }
1554}
1555
1556impl ScalarProduct<Translator> for MultiVector {
1557 type Output = f32;
1558
1559 fn scalar_product(self, other: Translator) -> f32 {
1560 self.group0()[0] * other.group0()[0] - self.group1()[2] * other.group0()[1] - self.group1()[3] * other.group0()[2]
1561 }
1562}
1563
1564impl Into<Motor> for MultiVector {
1565 fn into(self) -> Motor {
1566 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group0()[1], self.group1()[2], self.group1()[3]]) } }
1567 }
1568}
1569
1570impl Add<Motor> for MultiVector {
1571 type Output = MultiVector;
1572
1573 fn add(self, other: Motor) -> MultiVector {
1574 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]) } }
1575 }
1576}
1577
1578impl AddAssign<Motor> for MultiVector {
1579 fn add_assign(&mut self, other: Motor) {
1580 *self = (*self).add(other);
1581 }
1582}
1583
1584impl Sub<Motor> for MultiVector {
1585 type Output = MultiVector;
1586
1587 fn sub(self, other: Motor) -> MultiVector {
1588 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]) } }
1589 }
1590}
1591
1592impl SubAssign<Motor> for MultiVector {
1593 fn sub_assign(&mut self, other: Motor) {
1594 *self = (*self).sub(other);
1595 }
1596}
1597
1598impl GeometricProduct<Motor> for MultiVector {
1599 type Output = MultiVector;
1600
1601 fn geometric_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]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 2, 2, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, -1.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]) * swizzle!(other.group0(), 2, 3, 2, 2) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 3, 3) * Simd32x4::from([-1.0, -1.0, 0.0, 0.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]) } }
1603 }
1604}
1605
1606impl OuterProduct<Motor> for MultiVector {
1607 type Output = MultiVector;
1608
1609 fn outer_product(self, other: Motor) -> MultiVector {
1610 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]) } }
1611 }
1612}
1613
1614impl InnerProduct<Motor> for MultiVector {
1615 type Output = MultiVector;
1616
1617 fn inner_product(self, other: Motor) -> MultiVector {
1618 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]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 2, 2, 2, 3) * Simd32x4::from([0.0, 0.0, 1.0, -1.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, 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]) } }
1619 }
1620}
1621
1622impl RightContraction<Motor> for MultiVector {
1623 type Output = MultiVector;
1624
1625 fn right_contraction(self, other: Motor) -> MultiVector {
1626 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]) } }
1627 }
1628}
1629
1630impl ScalarProduct<Motor> for MultiVector {
1631 type Output = f32;
1632
1633 fn scalar_product(self, other: Motor) -> f32 {
1634 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group1()[2] * other.group0()[2] - self.group1()[3] * other.group0()[3]
1635 }
1636}
1637
1638impl Into<MotorDual> for MultiVector {
1639 fn into(self) -> MotorDual {
1640 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from([self.group1()[1], self.group1()[0], self.group0()[3], self.group0()[2]]) } }
1641 }
1642}
1643
1644impl Add<MotorDual> for MultiVector {
1645 type Output = MultiVector;
1646
1647 fn add(self, other: MotorDual) -> MultiVector {
1648 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]) } }
1649 }
1650}
1651
1652impl AddAssign<MotorDual> for MultiVector {
1653 fn add_assign(&mut self, other: MotorDual) {
1654 *self = (*self).add(other);
1655 }
1656}
1657
1658impl Sub<MotorDual> for MultiVector {
1659 type Output = MultiVector;
1660
1661 fn sub(self, other: MotorDual) -> MultiVector {
1662 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]) } }
1663 }
1664}
1665
1666impl SubAssign<MotorDual> for MultiVector {
1667 fn sub_assign(&mut self, other: MotorDual) {
1668 *self = (*self).sub(other);
1669 }
1670}
1671
1672impl GeometricProduct<MotorDual> for MultiVector {
1673 type Output = MultiVector;
1674
1675 fn geometric_product(self, other: MotorDual) -> MultiVector {
1676 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]) + Simd32x4::from(self.group1()[0]) * 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(), 0, 1, 0, 0) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, -1.0, 1.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]) } }
1677 }
1678}
1679
1680impl RegressiveProduct<MotorDual> for MultiVector {
1681 type Output = MultiVector;
1682
1683 fn regressive_product(self, other: MotorDual) -> MultiVector {
1684 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]) } }
1685 }
1686}
1687
1688impl InnerProduct<MotorDual> for MultiVector {
1689 type Output = MultiVector;
1690
1691 fn inner_product(self, other: MotorDual) -> MultiVector {
1692 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]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * 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(), 0, 1, 0, 0) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 1, 1, 1, 0) * Simd32x4::from([0.0, 0.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 0, 0, 0, 1) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 2, 0, 0, 0) * swizzle!(other.group0(), 3, 0, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.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]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 3, 2) * swizzle!(other.group0(), 1, 0, 0, 0) } }
1693 }
1694}
1695
1696impl LeftContraction<MotorDual> for MultiVector {
1697 type Output = MultiVector;
1698
1699 fn left_contraction(self, other: MotorDual) -> MultiVector {
1700 MultiVector { groups: MultiVectorGroups { g0: 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]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.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, 0, 0, 0) * swizzle!(other.group0(), 3, 0, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 0, 0, 3, 2) * swizzle!(other.group0(), 1, 0, 0, 0) } }
1701 }
1702}
1703
1704impl ScalarProduct<MotorDual> for MultiVector {
1705 type Output = f32;
1706
1707 fn scalar_product(self, other: MotorDual) -> f32 {
1708 self.group0()[2] * other.group0()[3] + self.group0()[3] * other.group0()[2] + self.group1()[0] * other.group0()[1] - self.group1()[1] * other.group0()[0]
1709 }
1710}
1711
1712impl SquaredMagnitude for MultiVector {
1713 type Output = f32;
1714
1715 fn squared_magnitude(self) -> f32 {
1716 self.scalar_product(self.reversal())
1717 }
1718}
1719
1720impl Magnitude for MultiVector {
1721 type Output = f32;
1722
1723 fn magnitude(self) -> f32 {
1724 self.squared_magnitude().sqrt()
1725 }
1726}
1727
1728impl Mul<f32> for MultiVector {
1729 type Output = MultiVector;
1730
1731 fn mul(self, other: f32) -> MultiVector {
1732 self.geometric_product(other)
1733 }
1734}
1735
1736impl MulAssign<f32> for MultiVector {
1737 fn mul_assign(&mut self, other: f32) {
1738 *self = (*self).mul(other);
1739 }
1740}
1741
1742impl Signum for MultiVector {
1743 type Output = MultiVector;
1744
1745 fn signum(self) -> MultiVector {
1746 self.geometric_product(1.0 / self.magnitude())
1747 }
1748}
1749
1750impl Inverse for MultiVector {
1751 type Output = MultiVector;
1752
1753 fn inverse(self) -> MultiVector {
1754 self.reversal().geometric_product(1.0 / self.squared_magnitude())
1755 }
1756}
1757
1758impl Zero for Rotor {
1759 fn zero() -> Self {
1760 Rotor { groups: RotorGroups { g0: Simd32x2::from(0.0) } }
1761 }
1762}
1763
1764impl One for Rotor {
1765 fn one() -> Self {
1766 Rotor { groups: RotorGroups { g0: Simd32x2::from([1.0, 0.0]) } }
1767 }
1768}
1769
1770impl Neg for Rotor {
1771 type Output = Rotor;
1772
1773 fn neg(self) -> Rotor {
1774 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
1775 }
1776}
1777
1778impl Automorphism for Rotor {
1779 type Output = Rotor;
1780
1781 fn automorphism(self) -> Rotor {
1782 Rotor { groups: RotorGroups { g0: self.group0() } }
1783 }
1784}
1785
1786impl Reversal for Rotor {
1787 type Output = Rotor;
1788
1789 fn reversal(self) -> Rotor {
1790 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from([1.0, -1.0]) } }
1791 }
1792}
1793
1794impl Conjugation for Rotor {
1795 type Output = Rotor;
1796
1797 fn conjugation(self) -> Rotor {
1798 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from([1.0, -1.0]) } }
1799 }
1800}
1801
1802impl Into<f32> for Rotor {
1803 fn into(self) -> f32 {
1804 self.group0()[0]
1805 }
1806}
1807
1808impl Add<f32> for Rotor {
1809 type Output = Rotor;
1810
1811 fn add(self, other: f32) -> Rotor {
1812 Rotor { groups: RotorGroups { g0: self.group0() + Simd32x2::from(other) * Simd32x2::from([1.0, 0.0]) } }
1813 }
1814}
1815
1816impl AddAssign<f32> for Rotor {
1817 fn add_assign(&mut self, other: f32) {
1818 *self = (*self).add(other);
1819 }
1820}
1821
1822impl Sub<f32> for Rotor {
1823 type Output = Rotor;
1824
1825 fn sub(self, other: f32) -> Rotor {
1826 Rotor { groups: RotorGroups { g0: self.group0() - Simd32x2::from(other) * Simd32x2::from([1.0, 0.0]) } }
1827 }
1828}
1829
1830impl SubAssign<f32> for Rotor {
1831 fn sub_assign(&mut self, other: f32) {
1832 *self = (*self).sub(other);
1833 }
1834}
1835
1836impl GeometricProduct<f32> for Rotor {
1837 type Output = Rotor;
1838
1839 fn geometric_product(self, other: f32) -> Rotor {
1840 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1841 }
1842}
1843
1844impl OuterProduct<f32> for Rotor {
1845 type Output = Rotor;
1846
1847 fn outer_product(self, other: f32) -> Rotor {
1848 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1849 }
1850}
1851
1852impl InnerProduct<f32> for Rotor {
1853 type Output = Rotor;
1854
1855 fn inner_product(self, other: f32) -> Rotor {
1856 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1857 }
1858}
1859
1860impl LeftContraction<f32> for Rotor {
1861 type Output = f32;
1862
1863 fn left_contraction(self, other: f32) -> f32 {
1864 self.group0()[0] * other
1865 }
1866}
1867
1868impl RightContraction<f32> for Rotor {
1869 type Output = Rotor;
1870
1871 fn right_contraction(self, other: f32) -> Rotor {
1872 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other) } }
1873 }
1874}
1875
1876impl ScalarProduct<f32> for Rotor {
1877 type Output = f32;
1878
1879 fn scalar_product(self, other: f32) -> f32 {
1880 self.group0()[0] * other
1881 }
1882}
1883
1884impl Add<MultiVector> for Rotor {
1885 type Output = MultiVector;
1886
1887 fn add(self, other: MultiVector) -> MultiVector {
1888 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() } }
1889 }
1890}
1891
1892impl Sub<MultiVector> for Rotor {
1893 type Output = MultiVector;
1894
1895 fn sub(self, other: MultiVector) -> MultiVector {
1896 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() } }
1897 }
1898}
1899
1900impl GeometricProduct<MultiVector> for Rotor {
1901 type Output = MultiVector;
1902
1903 fn geometric_product(self, other: MultiVector) -> MultiVector {
1904 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]) } }
1905 }
1906}
1907
1908impl OuterProduct<MultiVector> for Rotor {
1909 type Output = MultiVector;
1910
1911 fn outer_product(self, other: MultiVector) -> MultiVector {
1912 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]) } }
1913 }
1914}
1915
1916impl InnerProduct<MultiVector> for Rotor {
1917 type Output = MultiVector;
1918
1919 fn inner_product(self, other: MultiVector) -> MultiVector {
1920 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]) } }
1921 }
1922}
1923
1924impl LeftContraction<MultiVector> for Rotor {
1925 type Output = MultiVector;
1926
1927 fn left_contraction(self, other: MultiVector) -> MultiVector {
1928 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]) } }
1929 }
1930}
1931
1932impl ScalarProduct<MultiVector> for Rotor {
1933 type Output = f32;
1934
1935 fn scalar_product(self, other: MultiVector) -> f32 {
1936 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
1937 }
1938}
1939
1940impl Add<Rotor> for Rotor {
1941 type Output = Rotor;
1942
1943 fn add(self, other: Rotor) -> Rotor {
1944 Rotor { groups: RotorGroups { g0: self.group0() + other.group0() } }
1945 }
1946}
1947
1948impl AddAssign<Rotor> for Rotor {
1949 fn add_assign(&mut self, other: Rotor) {
1950 *self = (*self).add(other);
1951 }
1952}
1953
1954impl Sub<Rotor> for Rotor {
1955 type Output = Rotor;
1956
1957 fn sub(self, other: Rotor) -> Rotor {
1958 Rotor { groups: RotorGroups { g0: self.group0() - other.group0() } }
1959 }
1960}
1961
1962impl SubAssign<Rotor> for Rotor {
1963 fn sub_assign(&mut self, other: Rotor) {
1964 *self = (*self).sub(other);
1965 }
1966}
1967
1968impl Mul<Rotor> for Rotor {
1969 type Output = Rotor;
1970
1971 fn mul(self, other: Rotor) -> Rotor {
1972 Rotor { groups: RotorGroups { g0: self.group0() * other.group0() } }
1973 }
1974}
1975
1976impl MulAssign<Rotor> for Rotor {
1977 fn mul_assign(&mut self, other: Rotor) {
1978 *self = (*self).mul(other);
1979 }
1980}
1981
1982impl Div<Rotor> for Rotor {
1983 type Output = Rotor;
1984
1985 fn div(self, other: Rotor) -> Rotor {
1986 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]) } }
1987 }
1988}
1989
1990impl DivAssign<Rotor> for Rotor {
1991 fn div_assign(&mut self, other: Rotor) {
1992 *self = (*self).div(other);
1993 }
1994}
1995
1996impl GeometricProduct<Rotor> for Rotor {
1997 type Output = Rotor;
1998
1999 fn geometric_product(self, other: Rotor) -> Rotor {
2000 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]) } }
2001 }
2002}
2003
2004impl OuterProduct<Rotor> for Rotor {
2005 type Output = Rotor;
2006
2007 fn outer_product(self, other: Rotor) -> Rotor {
2008 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() + self.group0() * Simd32x2::from(other.group0()[0]) * Simd32x2::from([0.0, 1.0]) } }
2009 }
2010}
2011
2012impl InnerProduct<Rotor> for Rotor {
2013 type Output = Rotor;
2014
2015 fn inner_product(self, other: Rotor) -> Rotor {
2016 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]) } }
2017 }
2018}
2019
2020impl LeftContraction<Rotor> for Rotor {
2021 type Output = Rotor;
2022
2023 fn left_contraction(self, other: Rotor) -> Rotor {
2024 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]) } }
2025 }
2026}
2027
2028impl RightContraction<Rotor> for Rotor {
2029 type Output = Rotor;
2030
2031 fn right_contraction(self, other: Rotor) -> Rotor {
2032 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]) } }
2033 }
2034}
2035
2036impl ScalarProduct<Rotor> for Rotor {
2037 type Output = f32;
2038
2039 fn scalar_product(self, other: Rotor) -> f32 {
2040 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
2041 }
2042}
2043
2044impl Add<Point> for Rotor {
2045 type Output = Motor;
2046
2047 fn add(self, other: Point) -> Motor {
2048 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]) } }
2049 }
2050}
2051
2052impl Sub<Point> for Rotor {
2053 type Output = Motor;
2054
2055 fn sub(self, other: Point) -> Motor {
2056 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]) } }
2057 }
2058}
2059
2060impl GeometricProduct<Point> for Rotor {
2061 type Output = Motor;
2062
2063 fn geometric_product(self, other: Point) -> Motor {
2064 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]) } }
2065 }
2066}
2067
2068impl OuterProduct<Point> for Rotor {
2069 type Output = Point;
2070
2071 fn outer_product(self, other: Point) -> Point {
2072 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2073 }
2074}
2075
2076impl InnerProduct<Point> for Rotor {
2077 type Output = Motor;
2078
2079 fn inner_product(self, other: Point) -> Motor {
2080 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]) } }
2081 }
2082}
2083
2084impl LeftContraction<Point> for Rotor {
2085 type Output = Motor;
2086
2087 fn left_contraction(self, other: Point) -> Motor {
2088 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]) } }
2089 }
2090}
2091
2092impl RightContraction<Point> for Rotor {
2093 type Output = f32;
2094
2095 fn right_contraction(self, other: Point) -> f32 {
2096 0.0 - self.group0()[1] * other.group0()[0]
2097 }
2098}
2099
2100impl ScalarProduct<Point> for Rotor {
2101 type Output = f32;
2102
2103 fn scalar_product(self, other: Point) -> f32 {
2104 0.0 - self.group0()[1] * other.group0()[0]
2105 }
2106}
2107
2108impl Add<IdealPoint> for Rotor {
2109 type Output = Motor;
2110
2111 fn add(self, other: IdealPoint) -> Motor {
2112 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]) } }
2113 }
2114}
2115
2116impl Sub<IdealPoint> for Rotor {
2117 type Output = Motor;
2118
2119 fn sub(self, other: IdealPoint) -> Motor {
2120 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]) } }
2121 }
2122}
2123
2124impl GeometricProduct<IdealPoint> for Rotor {
2125 type Output = IdealPoint;
2126
2127 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
2128 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]) } }
2129 }
2130}
2131
2132impl OuterProduct<IdealPoint> for Rotor {
2133 type Output = IdealPoint;
2134
2135 fn outer_product(self, other: IdealPoint) -> IdealPoint {
2136 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
2137 }
2138}
2139
2140impl InnerProduct<IdealPoint> for Rotor {
2141 type Output = IdealPoint;
2142
2143 fn inner_product(self, other: IdealPoint) -> IdealPoint {
2144 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
2145 }
2146}
2147
2148impl LeftContraction<IdealPoint> for Rotor {
2149 type Output = IdealPoint;
2150
2151 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
2152 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
2153 }
2154}
2155
2156impl GeometricProduct<Plane> for Rotor {
2157 type Output = MotorDual;
2158
2159 fn geometric_product(self, other: Plane) -> MotorDual {
2160 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]) } }
2161 }
2162}
2163
2164impl RegressiveProduct<Plane> for Rotor {
2165 type Output = f32;
2166
2167 fn regressive_product(self, other: Plane) -> f32 {
2168 self.group0()[1] * other.group0()[0]
2169 }
2170}
2171
2172impl OuterProduct<Plane> for Rotor {
2173 type Output = MotorDual;
2174
2175 fn outer_product(self, other: Plane) -> MotorDual {
2176 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]]) } }
2177 }
2178}
2179
2180impl InnerProduct<Plane> for Rotor {
2181 type Output = Plane;
2182
2183 fn inner_product(self, other: Plane) -> Plane {
2184 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]) } }
2185 }
2186}
2187
2188impl LeftContraction<Plane> for Rotor {
2189 type Output = Plane;
2190
2191 fn left_contraction(self, other: Plane) -> Plane {
2192 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2193 }
2194}
2195
2196impl Add<Translator> for Rotor {
2197 type Output = Motor;
2198
2199 fn add(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([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]) } }
2201 }
2202}
2203
2204impl Sub<Translator> for Rotor {
2205 type Output = Motor;
2206
2207 fn sub(self, other: Translator) -> Motor {
2208 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]) } }
2209 }
2210}
2211
2212impl GeometricProduct<Translator> for Rotor {
2213 type Output = Motor;
2214
2215 fn geometric_product(self, other: Translator) -> Motor {
2216 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]) } }
2217 }
2218}
2219
2220impl OuterProduct<Translator> for Rotor {
2221 type Output = Motor;
2222
2223 fn outer_product(self, other: Translator) -> Motor {
2224 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]]) } }
2225 }
2226}
2227
2228impl InnerProduct<Translator> for Rotor {
2229 type Output = Motor;
2230
2231 fn inner_product(self, other: Translator) -> Motor {
2232 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]]) } }
2233 }
2234}
2235
2236impl LeftContraction<Translator> for Rotor {
2237 type Output = Translator;
2238
2239 fn left_contraction(self, other: Translator) -> Translator {
2240 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2241 }
2242}
2243
2244impl RightContraction<Translator> for Rotor {
2245 type Output = Rotor;
2246
2247 fn right_contraction(self, other: Translator) -> Rotor {
2248 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
2249 }
2250}
2251
2252impl ScalarProduct<Translator> for Rotor {
2253 type Output = f32;
2254
2255 fn scalar_product(self, other: Translator) -> f32 {
2256 self.group0()[0] * other.group0()[0]
2257 }
2258}
2259
2260impl Add<Motor> for Rotor {
2261 type Output = Motor;
2262
2263 fn add(self, other: Motor) -> Motor {
2264 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() } }
2265 }
2266}
2267
2268impl Sub<Motor> for Rotor {
2269 type Output = Motor;
2270
2271 fn sub(self, other: Motor) -> Motor {
2272 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() } }
2273 }
2274}
2275
2276impl GeometricProduct<Motor> for Rotor {
2277 type Output = Motor;
2278
2279 fn geometric_product(self, other: Motor) -> Motor {
2280 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]) } }
2281 }
2282}
2283
2284impl OuterProduct<Motor> for Rotor {
2285 type Output = Motor;
2286
2287 fn outer_product(self, other: Motor) -> Motor {
2288 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]) } }
2289 }
2290}
2291
2292impl InnerProduct<Motor> for Rotor {
2293 type Output = Motor;
2294
2295 fn inner_product(self, other: Motor) -> Motor {
2296 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]) } }
2297 }
2298}
2299
2300impl LeftContraction<Motor> for Rotor {
2301 type Output = Motor;
2302
2303 fn left_contraction(self, other: Motor) -> Motor {
2304 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]) } }
2305 }
2306}
2307
2308impl RightContraction<Motor> for Rotor {
2309 type Output = Rotor;
2310
2311 fn right_contraction(self, other: Motor) -> Rotor {
2312 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]) } }
2313 }
2314}
2315
2316impl ScalarProduct<Motor> for Rotor {
2317 type Output = f32;
2318
2319 fn scalar_product(self, other: Motor) -> f32 {
2320 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
2321 }
2322}
2323
2324impl GeometricProduct<MotorDual> for Rotor {
2325 type Output = MotorDual;
2326
2327 fn geometric_product(self, other: MotorDual) -> MotorDual {
2328 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]) } }
2329 }
2330}
2331
2332impl RegressiveProduct<MotorDual> for Rotor {
2333 type Output = Rotor;
2334
2335 fn regressive_product(self, other: MotorDual) -> Rotor {
2336 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]) } }
2337 }
2338}
2339
2340impl OuterProduct<MotorDual> for Rotor {
2341 type Output = MotorDual;
2342
2343 fn outer_product(self, other: MotorDual) -> MotorDual {
2344 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]) } }
2345 }
2346}
2347
2348impl InnerProduct<MotorDual> for Rotor {
2349 type Output = MotorDual;
2350
2351 fn inner_product(self, other: MotorDual) -> MotorDual {
2352 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]) } }
2353 }
2354}
2355
2356impl LeftContraction<MotorDual> for Rotor {
2357 type Output = MotorDual;
2358
2359 fn left_contraction(self, other: MotorDual) -> MotorDual {
2360 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]) } }
2361 }
2362}
2363
2364impl SquaredMagnitude for Rotor {
2365 type Output = f32;
2366
2367 fn squared_magnitude(self) -> f32 {
2368 self.scalar_product(self.reversal())
2369 }
2370}
2371
2372impl Magnitude for Rotor {
2373 type Output = f32;
2374
2375 fn magnitude(self) -> f32 {
2376 self.squared_magnitude().sqrt()
2377 }
2378}
2379
2380impl Mul<f32> for Rotor {
2381 type Output = Rotor;
2382
2383 fn mul(self, other: f32) -> Rotor {
2384 self.geometric_product(other)
2385 }
2386}
2387
2388impl MulAssign<f32> for Rotor {
2389 fn mul_assign(&mut self, other: f32) {
2390 *self = (*self).mul(other);
2391 }
2392}
2393
2394impl Signum for Rotor {
2395 type Output = Rotor;
2396
2397 fn signum(self) -> Rotor {
2398 self.geometric_product(1.0 / self.magnitude())
2399 }
2400}
2401
2402impl Inverse for Rotor {
2403 type Output = Rotor;
2404
2405 fn inverse(self) -> Rotor {
2406 self.reversal().geometric_product(1.0 / self.squared_magnitude())
2407 }
2408}
2409
2410impl Zero for Point {
2411 fn zero() -> Self {
2412 Point { groups: PointGroups { g0: Simd32x3::from(0.0) } }
2413 }
2414}
2415
2416impl One for Point {
2417 fn one() -> Self {
2418 Point { groups: PointGroups { g0: Simd32x3::from(0.0) } }
2419 }
2420}
2421
2422impl Neg for Point {
2423 type Output = Point;
2424
2425 fn neg(self) -> Point {
2426 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
2427 }
2428}
2429
2430impl Automorphism for Point {
2431 type Output = Point;
2432
2433 fn automorphism(self) -> Point {
2434 Point { groups: PointGroups { g0: self.group0() } }
2435 }
2436}
2437
2438impl Reversal for Point {
2439 type Output = Point;
2440
2441 fn reversal(self) -> Point {
2442 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
2443 }
2444}
2445
2446impl Conjugation for Point {
2447 type Output = Point;
2448
2449 fn conjugation(self) -> Point {
2450 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
2451 }
2452}
2453
2454impl Dual for Point {
2455 type Output = Plane;
2456
2457 fn dual(self) -> Plane {
2458 Plane { groups: PlaneGroups { g0: self.group0() } }
2459 }
2460}
2461
2462impl Add<f32> for Point {
2463 type Output = Motor;
2464
2465 fn add(self, other: f32) -> Motor {
2466 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]) } }
2467 }
2468}
2469
2470impl Sub<f32> for Point {
2471 type Output = Motor;
2472
2473 fn sub(self, other: f32) -> Motor {
2474 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]) } }
2475 }
2476}
2477
2478impl GeometricProduct<f32> for Point {
2479 type Output = Point;
2480
2481 fn geometric_product(self, other: f32) -> Point {
2482 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2483 }
2484}
2485
2486impl OuterProduct<f32> for Point {
2487 type Output = Point;
2488
2489 fn outer_product(self, other: f32) -> Point {
2490 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2491 }
2492}
2493
2494impl InnerProduct<f32> for Point {
2495 type Output = Point;
2496
2497 fn inner_product(self, other: f32) -> Point {
2498 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2499 }
2500}
2501
2502impl RightContraction<f32> for Point {
2503 type Output = Point;
2504
2505 fn right_contraction(self, other: f32) -> Point {
2506 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other) } }
2507 }
2508}
2509
2510impl Add<MultiVector> for Point {
2511 type Output = MultiVector;
2512
2513 fn add(self, other: MultiVector) -> MultiVector {
2514 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() } }
2515 }
2516}
2517
2518impl Sub<MultiVector> for Point {
2519 type Output = MultiVector;
2520
2521 fn sub(self, other: MultiVector) -> MultiVector {
2522 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() } }
2523 }
2524}
2525
2526impl GeometricProduct<MultiVector> for Point {
2527 type Output = MultiVector;
2528
2529 fn geometric_product(self, other: MultiVector) -> MultiVector {
2530 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]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 2, 1, 0) * 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]) } }
2531 }
2532}
2533
2534impl ScalarProduct<MultiVector> for Point {
2535 type Output = f32;
2536
2537 fn scalar_product(self, other: MultiVector) -> f32 {
2538 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group1()[2] - self.group0()[2] * other.group1()[3]
2539 }
2540}
2541
2542impl Add<Rotor> for Point {
2543 type Output = Motor;
2544
2545 fn add(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([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]) } }
2547 }
2548}
2549
2550impl Sub<Rotor> for Point {
2551 type Output = Motor;
2552
2553 fn sub(self, other: Rotor) -> Motor {
2554 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]) } }
2555 }
2556}
2557
2558impl GeometricProduct<Rotor> for Point {
2559 type Output = Motor;
2560
2561 fn geometric_product(self, other: Rotor) -> Motor {
2562 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]) } }
2563 }
2564}
2565
2566impl OuterProduct<Rotor> for Point {
2567 type Output = Point;
2568
2569 fn outer_product(self, other: Rotor) -> Point {
2570 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2571 }
2572}
2573
2574impl InnerProduct<Rotor> for Point {
2575 type Output = Motor;
2576
2577 fn inner_product(self, other: Rotor) -> Motor {
2578 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]) } }
2579 }
2580}
2581
2582impl LeftContraction<Rotor> for Point {
2583 type Output = f32;
2584
2585 fn left_contraction(self, other: Rotor) -> f32 {
2586 0.0 - self.group0()[0] * other.group0()[1]
2587 }
2588}
2589
2590impl RightContraction<Rotor> for Point {
2591 type Output = Motor;
2592
2593 fn right_contraction(self, other: Rotor) -> Motor {
2594 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]) } }
2595 }
2596}
2597
2598impl ScalarProduct<Rotor> for Point {
2599 type Output = f32;
2600
2601 fn scalar_product(self, other: Rotor) -> f32 {
2602 0.0 - self.group0()[0] * other.group0()[1]
2603 }
2604}
2605
2606impl Add<Point> for Point {
2607 type Output = Point;
2608
2609 fn add(self, other: Point) -> Point {
2610 Point { groups: PointGroups { g0: self.group0() + other.group0() } }
2611 }
2612}
2613
2614impl AddAssign<Point> for Point {
2615 fn add_assign(&mut self, other: Point) {
2616 *self = (*self).add(other);
2617 }
2618}
2619
2620impl Sub<Point> for Point {
2621 type Output = Point;
2622
2623 fn sub(self, other: Point) -> Point {
2624 Point { groups: PointGroups { g0: self.group0() - other.group0() } }
2625 }
2626}
2627
2628impl SubAssign<Point> for Point {
2629 fn sub_assign(&mut self, other: Point) {
2630 *self = (*self).sub(other);
2631 }
2632}
2633
2634impl Mul<Point> for Point {
2635 type Output = Point;
2636
2637 fn mul(self, other: Point) -> Point {
2638 Point { groups: PointGroups { g0: self.group0() * other.group0() } }
2639 }
2640}
2641
2642impl MulAssign<Point> for Point {
2643 fn mul_assign(&mut self, other: Point) {
2644 *self = (*self).mul(other);
2645 }
2646}
2647
2648impl Div<Point> for Point {
2649 type Output = Point;
2650
2651 fn div(self, other: Point) -> Point {
2652 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]) } }
2653 }
2654}
2655
2656impl DivAssign<Point> for Point {
2657 fn div_assign(&mut self, other: Point) {
2658 *self = (*self).div(other);
2659 }
2660}
2661
2662impl GeometricProduct<Point> for Point {
2663 type Output = Motor;
2664
2665 fn geometric_product(self, other: Point) -> Motor {
2666 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([-1.0, 0.0, -1.0, 1.0]) } }
2667 }
2668}
2669
2670impl RegressiveProduct<Point> for Point {
2671 type Output = Plane;
2672
2673 fn regressive_product(self, other: Point) -> Plane {
2674 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]) } }
2675 }
2676}
2677
2678impl InnerProduct<Point> for Point {
2679 type Output = f32;
2680
2681 fn inner_product(self, other: Point) -> f32 {
2682 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
2683 }
2684}
2685
2686impl LeftContraction<Point> for Point {
2687 type Output = f32;
2688
2689 fn left_contraction(self, other: Point) -> f32 {
2690 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
2691 }
2692}
2693
2694impl RightContraction<Point> for Point {
2695 type Output = f32;
2696
2697 fn right_contraction(self, other: Point) -> f32 {
2698 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
2699 }
2700}
2701
2702impl ScalarProduct<Point> for Point {
2703 type Output = f32;
2704
2705 fn scalar_product(self, other: Point) -> f32 {
2706 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
2707 }
2708}
2709
2710impl Into<IdealPoint> for Point {
2711 fn into(self) -> IdealPoint {
2712 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[1], self.group0()[2]]) } }
2713 }
2714}
2715
2716impl Add<IdealPoint> for Point {
2717 type Output = Point;
2718
2719 fn add(self, other: IdealPoint) -> Point {
2720 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]) } }
2721 }
2722}
2723
2724impl AddAssign<IdealPoint> for Point {
2725 fn add_assign(&mut self, other: IdealPoint) {
2726 *self = (*self).add(other);
2727 }
2728}
2729
2730impl Sub<IdealPoint> for Point {
2731 type Output = Point;
2732
2733 fn sub(self, other: IdealPoint) -> Point {
2734 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]) } }
2735 }
2736}
2737
2738impl SubAssign<IdealPoint> for Point {
2739 fn sub_assign(&mut self, other: IdealPoint) {
2740 *self = (*self).sub(other);
2741 }
2742}
2743
2744impl GeometricProduct<IdealPoint> for Point {
2745 type Output = Motor;
2746
2747 fn geometric_product(self, other: IdealPoint) -> Motor {
2748 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * 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()[1], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
2749 }
2750}
2751
2752impl RegressiveProduct<IdealPoint> for Point {
2753 type Output = Plane;
2754
2755 fn regressive_product(self, other: IdealPoint) -> Plane {
2756 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]) } }
2757 }
2758}
2759
2760impl InnerProduct<IdealPoint> for Point {
2761 type Output = f32;
2762
2763 fn inner_product(self, other: IdealPoint) -> f32 {
2764 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1]
2765 }
2766}
2767
2768impl LeftContraction<IdealPoint> for Point {
2769 type Output = f32;
2770
2771 fn left_contraction(self, other: IdealPoint) -> f32 {
2772 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1]
2773 }
2774}
2775
2776impl RightContraction<IdealPoint> for Point {
2777 type Output = f32;
2778
2779 fn right_contraction(self, other: IdealPoint) -> f32 {
2780 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1]
2781 }
2782}
2783
2784impl ScalarProduct<IdealPoint> for Point {
2785 type Output = f32;
2786
2787 fn scalar_product(self, other: IdealPoint) -> f32 {
2788 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1]
2789 }
2790}
2791
2792impl GeometricProduct<Plane> for Point {
2793 type Output = MotorDual;
2794
2795 fn geometric_product(self, other: Plane) -> MotorDual {
2796 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], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) } }
2797 }
2798}
2799
2800impl RegressiveProduct<Plane> for Point {
2801 type Output = f32;
2802
2803 fn regressive_product(self, other: Plane) -> f32 {
2804 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
2805 }
2806}
2807
2808impl InnerProduct<Plane> for Point {
2809 type Output = Plane;
2810
2811 fn inner_product(self, other: Plane) -> Plane {
2812 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]) } }
2813 }
2814}
2815
2816impl RightContraction<Plane> for Point {
2817 type Output = Plane;
2818
2819 fn right_contraction(self, other: Plane) -> Plane {
2820 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]) } }
2821 }
2822}
2823
2824impl Add<Translator> for Point {
2825 type Output = Motor;
2826
2827 fn add(self, other: Translator) -> 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]) + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
2829 }
2830}
2831
2832impl Sub<Translator> for Point {
2833 type Output = Motor;
2834
2835 fn sub(self, other: Translator) -> Motor {
2836 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]) } }
2837 }
2838}
2839
2840impl GeometricProduct<Translator> for Point {
2841 type Output = Motor;
2842
2843 fn geometric_product(self, other: Translator) -> Motor {
2844 Motor { groups: MotorGroups { 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], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) } }
2845 }
2846}
2847
2848impl RegressiveProduct<Translator> for Point {
2849 type Output = Plane;
2850
2851 fn regressive_product(self, other: Translator) -> Plane {
2852 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]) } }
2853 }
2854}
2855
2856impl OuterProduct<Translator> for Point {
2857 type Output = Point;
2858
2859 fn outer_product(self, other: Translator) -> Point {
2860 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2861 }
2862}
2863
2864impl InnerProduct<Translator> for Point {
2865 type Output = Motor;
2866
2867 fn inner_product(self, other: Translator) -> Motor {
2868 Motor { groups: MotorGroups { 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]) } }
2869 }
2870}
2871
2872impl LeftContraction<Translator> for Point {
2873 type Output = f32;
2874
2875 fn left_contraction(self, other: Translator) -> f32 {
2876 0.0 - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
2877 }
2878}
2879
2880impl RightContraction<Translator> for Point {
2881 type Output = Motor;
2882
2883 fn right_contraction(self, other: Translator) -> Motor {
2884 Motor { groups: MotorGroups { 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]) } }
2885 }
2886}
2887
2888impl ScalarProduct<Translator> for Point {
2889 type Output = f32;
2890
2891 fn scalar_product(self, other: Translator) -> f32 {
2892 0.0 - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
2893 }
2894}
2895
2896impl Add<Motor> for Point {
2897 type Output = Motor;
2898
2899 fn add(self, other: Motor) -> Motor {
2900 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() } }
2901 }
2902}
2903
2904impl Sub<Motor> for Point {
2905 type Output = Motor;
2906
2907 fn sub(self, other: Motor) -> Motor {
2908 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() } }
2909 }
2910}
2911
2912impl GeometricProduct<Motor> for Point {
2913 type Output = Motor;
2914
2915 fn geometric_product(self, other: Motor) -> Motor {
2916 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()[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]) } }
2917 }
2918}
2919
2920impl RegressiveProduct<Motor> for Point {
2921 type Output = Plane;
2922
2923 fn regressive_product(self, other: Motor) -> Plane {
2924 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]) } }
2925 }
2926}
2927
2928impl OuterProduct<Motor> for Point {
2929 type Output = Point;
2930
2931 fn outer_product(self, other: Motor) -> Point {
2932 Point { groups: PointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
2933 }
2934}
2935
2936impl InnerProduct<Motor> for Point {
2937 type Output = Motor;
2938
2939 fn inner_product(self, other: Motor) -> Motor {
2940 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]) } }
2941 }
2942}
2943
2944impl LeftContraction<Motor> for Point {
2945 type Output = f32;
2946
2947 fn left_contraction(self, other: Motor) -> f32 {
2948 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2] - self.group0()[2] * other.group0()[3]
2949 }
2950}
2951
2952impl RightContraction<Motor> for Point {
2953 type Output = Motor;
2954
2955 fn right_contraction(self, other: Motor) -> Motor {
2956 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]) } }
2957 }
2958}
2959
2960impl ScalarProduct<Motor> for Point {
2961 type Output = f32;
2962
2963 fn scalar_product(self, other: Motor) -> f32 {
2964 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2] - self.group0()[2] * other.group0()[3]
2965 }
2966}
2967
2968impl GeometricProduct<MotorDual> for Point {
2969 type Output = MotorDual;
2970
2971 fn geometric_product(self, other: MotorDual) -> MotorDual {
2972 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()[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]) } }
2973 }
2974}
2975
2976impl RegressiveProduct<MotorDual> for Point {
2977 type Output = Motor;
2978
2979 fn regressive_product(self, other: MotorDual) -> Motor {
2980 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]) } }
2981 }
2982}
2983
2984impl InnerProduct<MotorDual> for Point {
2985 type Output = Plane;
2986
2987 fn inner_product(self, other: MotorDual) -> Plane {
2988 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()[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]) } }
2989 }
2990}
2991
2992impl LeftContraction<MotorDual> for Point {
2993 type Output = Plane;
2994
2995 fn left_contraction(self, other: MotorDual) -> Plane {
2996 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) * Simd32x3::from(-1.0) } }
2997 }
2998}
2999
3000impl RightContraction<MotorDual> for Point {
3001 type Output = Plane;
3002
3003 fn right_contraction(self, other: MotorDual) -> Plane {
3004 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]) } }
3005 }
3006}
3007
3008impl SquaredMagnitude for Point {
3009 type Output = f32;
3010
3011 fn squared_magnitude(self) -> f32 {
3012 self.scalar_product(self.reversal())
3013 }
3014}
3015
3016impl Magnitude for Point {
3017 type Output = f32;
3018
3019 fn magnitude(self) -> f32 {
3020 self.squared_magnitude().sqrt()
3021 }
3022}
3023
3024impl Mul<f32> for Point {
3025 type Output = Point;
3026
3027 fn mul(self, other: f32) -> Point {
3028 self.geometric_product(other)
3029 }
3030}
3031
3032impl MulAssign<f32> for Point {
3033 fn mul_assign(&mut self, other: f32) {
3034 *self = (*self).mul(other);
3035 }
3036}
3037
3038impl Signum for Point {
3039 type Output = Point;
3040
3041 fn signum(self) -> Point {
3042 self.geometric_product(1.0 / self.magnitude())
3043 }
3044}
3045
3046impl Inverse for Point {
3047 type Output = Point;
3048
3049 fn inverse(self) -> Point {
3050 self.reversal().geometric_product(1.0 / self.squared_magnitude())
3051 }
3052}
3053
3054impl Zero for IdealPoint {
3055 fn zero() -> Self {
3056 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(0.0) } }
3057 }
3058}
3059
3060impl One for IdealPoint {
3061 fn one() -> Self {
3062 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(0.0) } }
3063 }
3064}
3065
3066impl Neg for IdealPoint {
3067 type Output = IdealPoint;
3068
3069 fn neg(self) -> IdealPoint {
3070 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
3071 }
3072}
3073
3074impl Automorphism for IdealPoint {
3075 type Output = IdealPoint;
3076
3077 fn automorphism(self) -> IdealPoint {
3078 IdealPoint { groups: IdealPointGroups { g0: self.group0() } }
3079 }
3080}
3081
3082impl Reversal for IdealPoint {
3083 type Output = IdealPoint;
3084
3085 fn reversal(self) -> IdealPoint {
3086 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
3087 }
3088}
3089
3090impl Conjugation for IdealPoint {
3091 type Output = IdealPoint;
3092
3093 fn conjugation(self) -> IdealPoint {
3094 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(-1.0) } }
3095 }
3096}
3097
3098impl Add<f32> for IdealPoint {
3099 type Output = Translator;
3100
3101 fn add(self, other: f32) -> Translator {
3102 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]) } }
3103 }
3104}
3105
3106impl Sub<f32> for IdealPoint {
3107 type Output = Translator;
3108
3109 fn sub(self, other: f32) -> Translator {
3110 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]) } }
3111 }
3112}
3113
3114impl GeometricProduct<f32> for IdealPoint {
3115 type Output = IdealPoint;
3116
3117 fn geometric_product(self, other: f32) -> IdealPoint {
3118 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3119 }
3120}
3121
3122impl OuterProduct<f32> for IdealPoint {
3123 type Output = IdealPoint;
3124
3125 fn outer_product(self, other: f32) -> IdealPoint {
3126 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3127 }
3128}
3129
3130impl InnerProduct<f32> for IdealPoint {
3131 type Output = IdealPoint;
3132
3133 fn inner_product(self, other: f32) -> IdealPoint {
3134 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3135 }
3136}
3137
3138impl RightContraction<f32> for IdealPoint {
3139 type Output = IdealPoint;
3140
3141 fn right_contraction(self, other: f32) -> IdealPoint {
3142 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other) } }
3143 }
3144}
3145
3146impl Add<MultiVector> for IdealPoint {
3147 type Output = MultiVector;
3148
3149 fn add(self, other: MultiVector) -> MultiVector {
3150 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() } }
3151 }
3152}
3153
3154impl Sub<MultiVector> for IdealPoint {
3155 type Output = MultiVector;
3156
3157 fn sub(self, other: MultiVector) -> MultiVector {
3158 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() } }
3159 }
3160}
3161
3162impl GeometricProduct<MultiVector> for IdealPoint {
3163 type Output = MultiVector;
3164
3165 fn geometric_product(self, other: MultiVector) -> MultiVector {
3166 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
3167 }
3168}
3169
3170impl ScalarProduct<MultiVector> for IdealPoint {
3171 type Output = f32;
3172
3173 fn scalar_product(self, other: MultiVector) -> f32 {
3174 0.0 - self.group0()[0] * other.group1()[2] - self.group0()[1] * other.group1()[3]
3175 }
3176}
3177
3178impl Add<Rotor> for IdealPoint {
3179 type Output = Motor;
3180
3181 fn add(self, other: Rotor) -> Motor {
3182 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]) } }
3183 }
3184}
3185
3186impl Sub<Rotor> for IdealPoint {
3187 type Output = Motor;
3188
3189 fn sub(self, other: Rotor) -> Motor {
3190 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]) } }
3191 }
3192}
3193
3194impl GeometricProduct<Rotor> for IdealPoint {
3195 type Output = IdealPoint;
3196
3197 fn geometric_product(self, other: Rotor) -> IdealPoint {
3198 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) } }
3199 }
3200}
3201
3202impl OuterProduct<Rotor> for IdealPoint {
3203 type Output = IdealPoint;
3204
3205 fn outer_product(self, other: Rotor) -> IdealPoint {
3206 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3207 }
3208}
3209
3210impl InnerProduct<Rotor> for IdealPoint {
3211 type Output = IdealPoint;
3212
3213 fn inner_product(self, other: Rotor) -> IdealPoint {
3214 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3215 }
3216}
3217
3218impl RightContraction<Rotor> for IdealPoint {
3219 type Output = IdealPoint;
3220
3221 fn right_contraction(self, other: Rotor) -> IdealPoint {
3222 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3223 }
3224}
3225
3226impl Add<Point> for IdealPoint {
3227 type Output = Point;
3228
3229 fn add(self, other: Point) -> Point {
3230 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() } }
3231 }
3232}
3233
3234impl Sub<Point> for IdealPoint {
3235 type Output = Point;
3236
3237 fn sub(self, other: Point) -> Point {
3238 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() } }
3239 }
3240}
3241
3242impl GeometricProduct<Point> for IdealPoint {
3243 type Output = Motor;
3244
3245 fn geometric_product(self, other: Point) -> Motor {
3246 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * 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()[1], other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, 0.0, -1.0]) } }
3247 }
3248}
3249
3250impl RegressiveProduct<Point> for IdealPoint {
3251 type Output = Plane;
3252
3253 fn regressive_product(self, other: Point) -> Plane {
3254 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]) } }
3255 }
3256}
3257
3258impl InnerProduct<Point> for IdealPoint {
3259 type Output = f32;
3260
3261 fn inner_product(self, other: Point) -> f32 {
3262 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2]
3263 }
3264}
3265
3266impl LeftContraction<Point> for IdealPoint {
3267 type Output = f32;
3268
3269 fn left_contraction(self, other: Point) -> f32 {
3270 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2]
3271 }
3272}
3273
3274impl RightContraction<Point> for IdealPoint {
3275 type Output = f32;
3276
3277 fn right_contraction(self, other: Point) -> f32 {
3278 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2]
3279 }
3280}
3281
3282impl ScalarProduct<Point> for IdealPoint {
3283 type Output = f32;
3284
3285 fn scalar_product(self, other: Point) -> f32 {
3286 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2]
3287 }
3288}
3289
3290impl Add<IdealPoint> for IdealPoint {
3291 type Output = IdealPoint;
3292
3293 fn add(self, other: IdealPoint) -> IdealPoint {
3294 IdealPoint { groups: IdealPointGroups { g0: self.group0() + other.group0() } }
3295 }
3296}
3297
3298impl AddAssign<IdealPoint> for IdealPoint {
3299 fn add_assign(&mut self, other: IdealPoint) {
3300 *self = (*self).add(other);
3301 }
3302}
3303
3304impl Sub<IdealPoint> for IdealPoint {
3305 type Output = IdealPoint;
3306
3307 fn sub(self, other: IdealPoint) -> IdealPoint {
3308 IdealPoint { groups: IdealPointGroups { g0: self.group0() - other.group0() } }
3309 }
3310}
3311
3312impl SubAssign<IdealPoint> for IdealPoint {
3313 fn sub_assign(&mut self, other: IdealPoint) {
3314 *self = (*self).sub(other);
3315 }
3316}
3317
3318impl Mul<IdealPoint> for IdealPoint {
3319 type Output = IdealPoint;
3320
3321 fn mul(self, other: IdealPoint) -> IdealPoint {
3322 IdealPoint { groups: IdealPointGroups { g0: self.group0() * other.group0() } }
3323 }
3324}
3325
3326impl MulAssign<IdealPoint> for IdealPoint {
3327 fn mul_assign(&mut self, other: IdealPoint) {
3328 *self = (*self).mul(other);
3329 }
3330}
3331
3332impl Div<IdealPoint> for IdealPoint {
3333 type Output = IdealPoint;
3334
3335 fn div(self, other: IdealPoint) -> IdealPoint {
3336 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]) } }
3337 }
3338}
3339
3340impl DivAssign<IdealPoint> for IdealPoint {
3341 fn div_assign(&mut self, other: IdealPoint) {
3342 *self = (*self).div(other);
3343 }
3344}
3345
3346impl GeometricProduct<IdealPoint> for IdealPoint {
3347 type Output = Rotor;
3348
3349 fn geometric_product(self, other: IdealPoint) -> Rotor {
3350 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() * Simd32x2::from([-1.0, 1.0]) - Simd32x2::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0) } }
3351 }
3352}
3353
3354impl InnerProduct<IdealPoint> for IdealPoint {
3355 type Output = f32;
3356
3357 fn inner_product(self, other: IdealPoint) -> f32 {
3358 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
3359 }
3360}
3361
3362impl LeftContraction<IdealPoint> for IdealPoint {
3363 type Output = f32;
3364
3365 fn left_contraction(self, other: IdealPoint) -> f32 {
3366 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
3367 }
3368}
3369
3370impl RightContraction<IdealPoint> for IdealPoint {
3371 type Output = f32;
3372
3373 fn right_contraction(self, other: IdealPoint) -> f32 {
3374 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
3375 }
3376}
3377
3378impl ScalarProduct<IdealPoint> for IdealPoint {
3379 type Output = f32;
3380
3381 fn scalar_product(self, other: IdealPoint) -> f32 {
3382 0.0 - self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
3383 }
3384}
3385
3386impl GeometricProduct<Plane> for IdealPoint {
3387 type Output = MotorDual;
3388
3389 fn geometric_product(self, other: Plane) -> MotorDual {
3390 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * 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()[1], other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) } }
3391 }
3392}
3393
3394impl RegressiveProduct<Plane> for IdealPoint {
3395 type Output = f32;
3396
3397 fn regressive_product(self, other: Plane) -> f32 {
3398 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2]
3399 }
3400}
3401
3402impl InnerProduct<Plane> for IdealPoint {
3403 type Output = Plane;
3404
3405 fn inner_product(self, other: Plane) -> Plane {
3406 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]) } }
3407 }
3408}
3409
3410impl RightContraction<Plane> for IdealPoint {
3411 type Output = Plane;
3412
3413 fn right_contraction(self, other: Plane) -> Plane {
3414 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]) } }
3415 }
3416}
3417
3418impl Add<Translator> for IdealPoint {
3419 type Output = Translator;
3420
3421 fn add(self, other: Translator) -> Translator {
3422 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() } }
3423 }
3424}
3425
3426impl Sub<Translator> for IdealPoint {
3427 type Output = Translator;
3428
3429 fn sub(self, other: Translator) -> Translator {
3430 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() } }
3431 }
3432}
3433
3434impl GeometricProduct<Translator> for IdealPoint {
3435 type Output = Motor;
3436
3437 fn geometric_product(self, other: Translator) -> Motor {
3438 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * 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()[1], other.group0()[2], other.group0()[0], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, 1.0, 0.0]) } }
3439 }
3440}
3441
3442impl OuterProduct<Translator> for IdealPoint {
3443 type Output = IdealPoint;
3444
3445 fn outer_product(self, other: Translator) -> IdealPoint {
3446 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3447 }
3448}
3449
3450impl InnerProduct<Translator> for IdealPoint {
3451 type Output = Translator;
3452
3453 fn inner_product(self, other: Translator) -> Translator {
3454 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 0) * Simd32x3::from([-1.0, 1.0, 0.0]) } }
3455 }
3456}
3457
3458impl LeftContraction<Translator> for IdealPoint {
3459 type Output = f32;
3460
3461 fn left_contraction(self, other: Translator) -> f32 {
3462 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2]
3463 }
3464}
3465
3466impl RightContraction<Translator> for IdealPoint {
3467 type Output = Translator;
3468
3469 fn right_contraction(self, other: Translator) -> Translator {
3470 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 0) * Simd32x3::from([-1.0, 1.0, 0.0]) } }
3471 }
3472}
3473
3474impl ScalarProduct<Translator> for IdealPoint {
3475 type Output = f32;
3476
3477 fn scalar_product(self, other: Translator) -> f32 {
3478 0.0 - self.group0()[0] * other.group0()[1] - self.group0()[1] * other.group0()[2]
3479 }
3480}
3481
3482impl Add<Motor> for IdealPoint {
3483 type Output = Motor;
3484
3485 fn add(self, other: Motor) -> Motor {
3486 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() } }
3487 }
3488}
3489
3490impl Sub<Motor> for IdealPoint {
3491 type Output = Motor;
3492
3493 fn sub(self, other: Motor) -> Motor {
3494 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() } }
3495 }
3496}
3497
3498impl GeometricProduct<Motor> for IdealPoint {
3499 type Output = Motor;
3500
3501 fn geometric_product(self, other: Motor) -> Motor {
3502 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) } }
3503 }
3504}
3505
3506impl RegressiveProduct<Motor> for IdealPoint {
3507 type Output = Plane;
3508
3509 fn regressive_product(self, other: Motor) -> Plane {
3510 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]) } }
3511 }
3512}
3513
3514impl OuterProduct<Motor> for IdealPoint {
3515 type Output = IdealPoint;
3516
3517 fn outer_product(self, other: Motor) -> IdealPoint {
3518 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x2::from(other.group0()[0]) } }
3519 }
3520}
3521
3522impl InnerProduct<Motor> for IdealPoint {
3523 type Output = Translator;
3524
3525 fn inner_product(self, other: Motor) -> Translator {
3526 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]) } }
3527 }
3528}
3529
3530impl LeftContraction<Motor> for IdealPoint {
3531 type Output = f32;
3532
3533 fn left_contraction(self, other: Motor) -> f32 {
3534 0.0 - self.group0()[0] * other.group0()[2] - self.group0()[1] * other.group0()[3]
3535 }
3536}
3537
3538impl RightContraction<Motor> for IdealPoint {
3539 type Output = Translator;
3540
3541 fn right_contraction(self, other: Motor) -> Translator {
3542 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]) } }
3543 }
3544}
3545
3546impl ScalarProduct<Motor> for IdealPoint {
3547 type Output = f32;
3548
3549 fn scalar_product(self, other: Motor) -> f32 {
3550 0.0 - self.group0()[0] * other.group0()[2] - self.group0()[1] * other.group0()[3]
3551 }
3552}
3553
3554impl GeometricProduct<MotorDual> for IdealPoint {
3555 type Output = MotorDual;
3556
3557 fn geometric_product(self, other: MotorDual) -> MotorDual {
3558 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) } }
3559 }
3560}
3561
3562impl RegressiveProduct<MotorDual> for IdealPoint {
3563 type Output = Translator;
3564
3565 fn regressive_product(self, other: MotorDual) -> Translator {
3566 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]) } }
3567 }
3568}
3569
3570impl InnerProduct<MotorDual> for IdealPoint {
3571 type Output = Plane;
3572
3573 fn inner_product(self, other: MotorDual) -> Plane {
3574 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x3::from([1.0, -1.0, -1.0]) + Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x3::from([-1.0, 1.0, -1.0]) } }
3575 }
3576}
3577
3578impl RightContraction<MotorDual> for IdealPoint {
3579 type Output = Plane;
3580
3581 fn right_contraction(self, other: MotorDual) -> Plane {
3582 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]) } }
3583 }
3584}
3585
3586impl SquaredMagnitude for IdealPoint {
3587 type Output = f32;
3588
3589 fn squared_magnitude(self) -> f32 {
3590 self.scalar_product(self.reversal())
3591 }
3592}
3593
3594impl Magnitude for IdealPoint {
3595 type Output = f32;
3596
3597 fn magnitude(self) -> f32 {
3598 self.squared_magnitude().sqrt()
3599 }
3600}
3601
3602impl Mul<f32> for IdealPoint {
3603 type Output = IdealPoint;
3604
3605 fn mul(self, other: f32) -> IdealPoint {
3606 self.geometric_product(other)
3607 }
3608}
3609
3610impl MulAssign<f32> for IdealPoint {
3611 fn mul_assign(&mut self, other: f32) {
3612 *self = (*self).mul(other);
3613 }
3614}
3615
3616impl Signum for IdealPoint {
3617 type Output = IdealPoint;
3618
3619 fn signum(self) -> IdealPoint {
3620 self.geometric_product(1.0 / self.magnitude())
3621 }
3622}
3623
3624impl Inverse for IdealPoint {
3625 type Output = IdealPoint;
3626
3627 fn inverse(self) -> IdealPoint {
3628 self.reversal().geometric_product(1.0 / self.squared_magnitude())
3629 }
3630}
3631
3632impl Zero for Plane {
3633 fn zero() -> Self {
3634 Plane { groups: PlaneGroups { g0: Simd32x3::from(0.0) } }
3635 }
3636}
3637
3638impl One for Plane {
3639 fn one() -> Self {
3640 Plane { groups: PlaneGroups { g0: Simd32x3::from(0.0) } }
3641 }
3642}
3643
3644impl Neg for Plane {
3645 type Output = Plane;
3646
3647 fn neg(self) -> Plane {
3648 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3649 }
3650}
3651
3652impl Automorphism for Plane {
3653 type Output = Plane;
3654
3655 fn automorphism(self) -> Plane {
3656 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3657 }
3658}
3659
3660impl Reversal for Plane {
3661 type Output = Plane;
3662
3663 fn reversal(self) -> Plane {
3664 Plane { groups: PlaneGroups { g0: self.group0() } }
3665 }
3666}
3667
3668impl Conjugation for Plane {
3669 type Output = Plane;
3670
3671 fn conjugation(self) -> Plane {
3672 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3673 }
3674}
3675
3676impl Dual for Plane {
3677 type Output = Point;
3678
3679 fn dual(self) -> Point {
3680 Point { groups: PointGroups { g0: self.group0() } }
3681 }
3682}
3683
3684impl GeometricProduct<f32> for Plane {
3685 type Output = Plane;
3686
3687 fn geometric_product(self, other: f32) -> Plane {
3688 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3689 }
3690}
3691
3692impl OuterProduct<f32> for Plane {
3693 type Output = Plane;
3694
3695 fn outer_product(self, other: f32) -> Plane {
3696 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3697 }
3698}
3699
3700impl InnerProduct<f32> for Plane {
3701 type Output = Plane;
3702
3703 fn inner_product(self, other: f32) -> Plane {
3704 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3705 }
3706}
3707
3708impl RightContraction<f32> for Plane {
3709 type Output = Plane;
3710
3711 fn right_contraction(self, other: f32) -> Plane {
3712 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other) } }
3713 }
3714}
3715
3716impl Add<MultiVector> for Plane {
3717 type Output = MultiVector;
3718
3719 fn add(self, other: MultiVector) -> MultiVector {
3720 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() } }
3721 }
3722}
3723
3724impl Sub<MultiVector> for Plane {
3725 type Output = MultiVector;
3726
3727 fn sub(self, other: MultiVector) -> MultiVector {
3728 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() } }
3729 }
3730}
3731
3732impl GeometricProduct<MultiVector> for Plane {
3733 type Output = MultiVector;
3734
3735 fn geometric_product(self, other: MultiVector) -> MultiVector {
3736 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group1() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + 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]) } }
3737 }
3738}
3739
3740impl ScalarProduct<MultiVector> for Plane {
3741 type Output = f32;
3742
3743 fn scalar_product(self, other: MultiVector) -> f32 {
3744 self.group0()[0] * other.group1()[0] + self.group0()[1] * other.group0()[3] + self.group0()[2] * other.group0()[2]
3745 }
3746}
3747
3748impl GeometricProduct<Rotor> for Plane {
3749 type Output = MotorDual;
3750
3751 fn geometric_product(self, other: Rotor) -> MotorDual {
3752 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]) } }
3753 }
3754}
3755
3756impl RegressiveProduct<Rotor> for Plane {
3757 type Output = f32;
3758
3759 fn regressive_product(self, other: Rotor) -> f32 {
3760 self.group0()[0] * other.group0()[1]
3761 }
3762}
3763
3764impl OuterProduct<Rotor> for Plane {
3765 type Output = MotorDual;
3766
3767 fn outer_product(self, other: Rotor) -> MotorDual {
3768 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]]) } }
3769 }
3770}
3771
3772impl InnerProduct<Rotor> for Plane {
3773 type Output = Plane;
3774
3775 fn inner_product(self, other: Rotor) -> Plane {
3776 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]) } }
3777 }
3778}
3779
3780impl RightContraction<Rotor> for Plane {
3781 type Output = Plane;
3782
3783 fn right_contraction(self, other: Rotor) -> Plane {
3784 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3785 }
3786}
3787
3788impl GeometricProduct<Point> for Plane {
3789 type Output = MotorDual;
3790
3791 fn geometric_product(self, other: Point) -> MotorDual {
3792 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], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) } }
3793 }
3794}
3795
3796impl RegressiveProduct<Point> for Plane {
3797 type Output = f32;
3798
3799 fn regressive_product(self, other: Point) -> f32 {
3800 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3801 }
3802}
3803
3804impl InnerProduct<Point> for Plane {
3805 type Output = Plane;
3806
3807 fn inner_product(self, other: Point) -> Plane {
3808 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]) } }
3809 }
3810}
3811
3812impl LeftContraction<Point> for Plane {
3813 type Output = Plane;
3814
3815 fn left_contraction(self, other: Point) -> Plane {
3816 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]) } }
3817 }
3818}
3819
3820impl GeometricProduct<IdealPoint> for Plane {
3821 type Output = MotorDual;
3822
3823 fn geometric_product(self, other: IdealPoint) -> MotorDual {
3824 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[2]) * 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()[1], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) } }
3825 }
3826}
3827
3828impl RegressiveProduct<IdealPoint> for Plane {
3829 type Output = f32;
3830
3831 fn regressive_product(self, other: IdealPoint) -> f32 {
3832 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1]
3833 }
3834}
3835
3836impl InnerProduct<IdealPoint> for Plane {
3837 type Output = Plane;
3838
3839 fn inner_product(self, other: IdealPoint) -> Plane {
3840 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]) } }
3841 }
3842}
3843
3844impl LeftContraction<IdealPoint> for Plane {
3845 type Output = Plane;
3846
3847 fn left_contraction(self, other: IdealPoint) -> Plane {
3848 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]) } }
3849 }
3850}
3851
3852impl Add<Plane> for Plane {
3853 type Output = Plane;
3854
3855 fn add(self, other: Plane) -> Plane {
3856 Plane { groups: PlaneGroups { g0: self.group0() + other.group0() } }
3857 }
3858}
3859
3860impl AddAssign<Plane> for Plane {
3861 fn add_assign(&mut self, other: Plane) {
3862 *self = (*self).add(other);
3863 }
3864}
3865
3866impl Sub<Plane> for Plane {
3867 type Output = Plane;
3868
3869 fn sub(self, other: Plane) -> Plane {
3870 Plane { groups: PlaneGroups { g0: self.group0() - other.group0() } }
3871 }
3872}
3873
3874impl SubAssign<Plane> for Plane {
3875 fn sub_assign(&mut self, other: Plane) {
3876 *self = (*self).sub(other);
3877 }
3878}
3879
3880impl Mul<Plane> for Plane {
3881 type Output = Plane;
3882
3883 fn mul(self, other: Plane) -> Plane {
3884 Plane { groups: PlaneGroups { g0: self.group0() * other.group0() } }
3885 }
3886}
3887
3888impl MulAssign<Plane> for Plane {
3889 fn mul_assign(&mut self, other: Plane) {
3890 *self = (*self).mul(other);
3891 }
3892}
3893
3894impl Div<Plane> for Plane {
3895 type Output = Plane;
3896
3897 fn div(self, other: Plane) -> Plane {
3898 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]) } }
3899 }
3900}
3901
3902impl DivAssign<Plane> for Plane {
3903 fn div_assign(&mut self, other: Plane) {
3904 *self = (*self).div(other);
3905 }
3906}
3907
3908impl GeometricProduct<Plane> for Plane {
3909 type Output = Motor;
3910
3911 fn geometric_product(self, other: Plane) -> Motor {
3912 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([1.0, 0.0, 1.0, -1.0]) } }
3913 }
3914}
3915
3916impl OuterProduct<Plane> for Plane {
3917 type Output = Point;
3918
3919 fn outer_product(self, other: Plane) -> Point {
3920 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]) } }
3921 }
3922}
3923
3924impl InnerProduct<Plane> for Plane {
3925 type Output = f32;
3926
3927 fn inner_product(self, other: Plane) -> f32 {
3928 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3929 }
3930}
3931
3932impl LeftContraction<Plane> for Plane {
3933 type Output = f32;
3934
3935 fn left_contraction(self, other: Plane) -> f32 {
3936 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3937 }
3938}
3939
3940impl RightContraction<Plane> for Plane {
3941 type Output = f32;
3942
3943 fn right_contraction(self, other: Plane) -> f32 {
3944 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3945 }
3946}
3947
3948impl ScalarProduct<Plane> for Plane {
3949 type Output = f32;
3950
3951 fn scalar_product(self, other: Plane) -> f32 {
3952 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3953 }
3954}
3955
3956impl GeometricProduct<Translator> for Plane {
3957 type Output = MotorDual;
3958
3959 fn geometric_product(self, other: Translator) -> MotorDual {
3960 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], other.group0()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) } }
3961 }
3962}
3963
3964impl RegressiveProduct<Translator> for Plane {
3965 type Output = f32;
3966
3967 fn regressive_product(self, other: Translator) -> f32 {
3968 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3969 }
3970}
3971
3972impl OuterProduct<Translator> for Plane {
3973 type Output = MotorDual;
3974
3975 fn outer_product(self, other: Translator) -> MotorDual {
3976 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]) } }
3977 }
3978}
3979
3980impl InnerProduct<Translator> for Plane {
3981 type Output = Plane;
3982
3983 fn inner_product(self, other: Translator) -> Plane {
3984 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * swizzle!(other.group0(), 0, 2, 1) * Simd32x3::from([1.0, -1.0, 1.0]) + Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 1, 1, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0) * swizzle!(other.group0(), 2, 0, 0) * Simd32x3::from([1.0, 1.0, 0.0]) } }
3985 }
3986}
3987
3988impl LeftContraction<Translator> for Plane {
3989 type Output = Plane;
3990
3991 fn left_contraction(self, other: Translator) -> Plane {
3992 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]) } }
3993 }
3994}
3995
3996impl RightContraction<Translator> for Plane {
3997 type Output = Plane;
3998
3999 fn right_contraction(self, other: Translator) -> Plane {
4000 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4001 }
4002}
4003
4004impl GeometricProduct<Motor> for Plane {
4005 type Output = MotorDual;
4006
4007 fn geometric_product(self, other: Motor) -> MotorDual {
4008 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()[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]) } }
4009 }
4010}
4011
4012impl RegressiveProduct<Motor> for Plane {
4013 type Output = f32;
4014
4015 fn regressive_product(self, other: Motor) -> f32 {
4016 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
4017 }
4018}
4019
4020impl OuterProduct<Motor> for Plane {
4021 type Output = MotorDual;
4022
4023 fn outer_product(self, other: Motor) -> MotorDual {
4024 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]) } }
4025 }
4026}
4027
4028impl InnerProduct<Motor> for Plane {
4029 type Output = Plane;
4030
4031 fn inner_product(self, other: Motor) -> Plane {
4032 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()[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]) } }
4033 }
4034}
4035
4036impl LeftContraction<Motor> for Plane {
4037 type Output = Plane;
4038
4039 fn left_contraction(self, other: Motor) -> Plane {
4040 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]) } }
4041 }
4042}
4043
4044impl RightContraction<Motor> for Plane {
4045 type Output = Plane;
4046
4047 fn right_contraction(self, other: Motor) -> Plane {
4048 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4049 }
4050}
4051
4052impl Add<MotorDual> for Plane {
4053 type Output = MotorDual;
4054
4055 fn add(self, other: MotorDual) -> MotorDual {
4056 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() } }
4057 }
4058}
4059
4060impl Sub<MotorDual> for Plane {
4061 type Output = MotorDual;
4062
4063 fn sub(self, other: MotorDual) -> MotorDual {
4064 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() } }
4065 }
4066}
4067
4068impl GeometricProduct<MotorDual> for Plane {
4069 type Output = Motor;
4070
4071 fn geometric_product(self, other: MotorDual) -> Motor {
4072 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()[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]) } }
4073 }
4074}
4075
4076impl RegressiveProduct<MotorDual> for Plane {
4077 type Output = Plane;
4078
4079 fn regressive_product(self, other: MotorDual) -> Plane {
4080 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4081 }
4082}
4083
4084impl OuterProduct<MotorDual> for Plane {
4085 type Output = Point;
4086
4087 fn outer_product(self, other: MotorDual) -> Point {
4088 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]) } }
4089 }
4090}
4091
4092impl InnerProduct<MotorDual> for Plane {
4093 type Output = Motor;
4094
4095 fn inner_product(self, other: MotorDual) -> Motor {
4096 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]) } }
4097 }
4098}
4099
4100impl LeftContraction<MotorDual> for Plane {
4101 type Output = Motor;
4102
4103 fn left_contraction(self, other: MotorDual) -> Motor {
4104 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]) } }
4105 }
4106}
4107
4108impl RightContraction<MotorDual> for Plane {
4109 type Output = f32;
4110
4111 fn right_contraction(self, other: MotorDual) -> f32 {
4112 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
4113 }
4114}
4115
4116impl ScalarProduct<MotorDual> for Plane {
4117 type Output = f32;
4118
4119 fn scalar_product(self, other: MotorDual) -> f32 {
4120 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
4121 }
4122}
4123
4124impl SquaredMagnitude for Plane {
4125 type Output = f32;
4126
4127 fn squared_magnitude(self) -> f32 {
4128 self.scalar_product(self.reversal())
4129 }
4130}
4131
4132impl Magnitude for Plane {
4133 type Output = f32;
4134
4135 fn magnitude(self) -> f32 {
4136 self.squared_magnitude().sqrt()
4137 }
4138}
4139
4140impl Mul<f32> for Plane {
4141 type Output = Plane;
4142
4143 fn mul(self, other: f32) -> Plane {
4144 self.geometric_product(other)
4145 }
4146}
4147
4148impl MulAssign<f32> for Plane {
4149 fn mul_assign(&mut self, other: f32) {
4150 *self = (*self).mul(other);
4151 }
4152}
4153
4154impl Signum for Plane {
4155 type Output = Plane;
4156
4157 fn signum(self) -> Plane {
4158 self.geometric_product(1.0 / self.magnitude())
4159 }
4160}
4161
4162impl Inverse for Plane {
4163 type Output = Plane;
4164
4165 fn inverse(self) -> Plane {
4166 self.reversal().geometric_product(1.0 / self.squared_magnitude())
4167 }
4168}
4169
4170impl Zero for Translator {
4171 fn zero() -> Self {
4172 Translator { groups: TranslatorGroups { g0: Simd32x3::from(0.0) } }
4173 }
4174}
4175
4176impl One for Translator {
4177 fn one() -> Self {
4178 Translator { groups: TranslatorGroups { g0: Simd32x3::from([1.0, 0.0, 0.0]) } }
4179 }
4180}
4181
4182impl Neg for Translator {
4183 type Output = Translator;
4184
4185 fn neg(self) -> Translator {
4186 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
4187 }
4188}
4189
4190impl Automorphism for Translator {
4191 type Output = Translator;
4192
4193 fn automorphism(self) -> Translator {
4194 Translator { groups: TranslatorGroups { g0: self.group0() } }
4195 }
4196}
4197
4198impl Reversal for Translator {
4199 type Output = Translator;
4200
4201 fn reversal(self) -> Translator {
4202 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from([1.0, -1.0, -1.0]) } }
4203 }
4204}
4205
4206impl Conjugation for Translator {
4207 type Output = Translator;
4208
4209 fn conjugation(self) -> Translator {
4210 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from([1.0, -1.0, -1.0]) } }
4211 }
4212}
4213
4214impl Into<f32> for Translator {
4215 fn into(self) -> f32 {
4216 self.group0()[0]
4217 }
4218}
4219
4220impl Add<f32> for Translator {
4221 type Output = Translator;
4222
4223 fn add(self, other: f32) -> Translator {
4224 Translator { groups: TranslatorGroups { g0: self.group0() + Simd32x3::from(other) * Simd32x3::from([1.0, 0.0, 0.0]) } }
4225 }
4226}
4227
4228impl AddAssign<f32> for Translator {
4229 fn add_assign(&mut self, other: f32) {
4230 *self = (*self).add(other);
4231 }
4232}
4233
4234impl Sub<f32> for Translator {
4235 type Output = Translator;
4236
4237 fn sub(self, other: f32) -> Translator {
4238 Translator { groups: TranslatorGroups { g0: self.group0() - Simd32x3::from(other) * Simd32x3::from([1.0, 0.0, 0.0]) } }
4239 }
4240}
4241
4242impl SubAssign<f32> for Translator {
4243 fn sub_assign(&mut self, other: f32) {
4244 *self = (*self).sub(other);
4245 }
4246}
4247
4248impl GeometricProduct<f32> for Translator {
4249 type Output = Translator;
4250
4251 fn geometric_product(self, other: f32) -> Translator {
4252 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
4253 }
4254}
4255
4256impl OuterProduct<f32> for Translator {
4257 type Output = Translator;
4258
4259 fn outer_product(self, other: f32) -> Translator {
4260 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
4261 }
4262}
4263
4264impl InnerProduct<f32> for Translator {
4265 type Output = Translator;
4266
4267 fn inner_product(self, other: f32) -> Translator {
4268 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
4269 }
4270}
4271
4272impl LeftContraction<f32> for Translator {
4273 type Output = f32;
4274
4275 fn left_contraction(self, other: f32) -> f32 {
4276 self.group0()[0] * other
4277 }
4278}
4279
4280impl RightContraction<f32> for Translator {
4281 type Output = Translator;
4282
4283 fn right_contraction(self, other: f32) -> Translator {
4284 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other) } }
4285 }
4286}
4287
4288impl ScalarProduct<f32> for Translator {
4289 type Output = f32;
4290
4291 fn scalar_product(self, other: f32) -> f32 {
4292 self.group0()[0] * other
4293 }
4294}
4295
4296impl Add<MultiVector> for Translator {
4297 type Output = MultiVector;
4298
4299 fn add(self, other: MultiVector) -> MultiVector {
4300 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() } }
4301 }
4302}
4303
4304impl Sub<MultiVector> for Translator {
4305 type Output = MultiVector;
4306
4307 fn sub(self, other: MultiVector) -> MultiVector {
4308 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() } }
4309 }
4310}
4311
4312impl GeometricProduct<MultiVector> for Translator {
4313 type Output = MultiVector;
4314
4315 fn geometric_product(self, other: MultiVector) -> MultiVector {
4316 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 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.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]) } }
4317 }
4318}
4319
4320impl OuterProduct<MultiVector> for Translator {
4321 type Output = MultiVector;
4322
4323 fn outer_product(self, other: MultiVector) -> MultiVector {
4324 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]) } }
4325 }
4326}
4327
4328impl InnerProduct<MultiVector> for Translator {
4329 type Output = MultiVector;
4330
4331 fn inner_product(self, other: MultiVector) -> MultiVector {
4332 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 1, 0) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from([self.group0()[1], self.group0()[0], self.group0()[1], self.group0()[1]]) * swizzle!(other.group1(), 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.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]) } }
4333 }
4334}
4335
4336impl LeftContraction<MultiVector> for Translator {
4337 type Output = MultiVector;
4338
4339 fn left_contraction(self, other: MultiVector) -> MultiVector {
4340 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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()[1], self.group0()[0], self.group0()[0], self.group0()[1]]) * swizzle!(other.group1(), 2, 0, 0, 1) * Simd32x4::from([-1.0, 0.0, 0.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() } }
4341 }
4342}
4343
4344impl ScalarProduct<MultiVector> for Translator {
4345 type Output = f32;
4346
4347 fn scalar_product(self, other: MultiVector) -> f32 {
4348 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group1()[2] - self.group0()[2] * other.group1()[3]
4349 }
4350}
4351
4352impl Add<Rotor> for Translator {
4353 type Output = Motor;
4354
4355 fn add(self, other: Rotor) -> Motor {
4356 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]) } }
4357 }
4358}
4359
4360impl Sub<Rotor> for Translator {
4361 type Output = Motor;
4362
4363 fn sub(self, other: Rotor) -> Motor {
4364 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]) } }
4365 }
4366}
4367
4368impl GeometricProduct<Rotor> for Translator {
4369 type Output = Motor;
4370
4371 fn geometric_product(self, other: Rotor) -> Motor {
4372 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]) } }
4373 }
4374}
4375
4376impl OuterProduct<Rotor> for Translator {
4377 type Output = Motor;
4378
4379 fn outer_product(self, other: Rotor) -> Motor {
4380 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]]) } }
4381 }
4382}
4383
4384impl InnerProduct<Rotor> for Translator {
4385 type Output = Motor;
4386
4387 fn inner_product(self, other: Rotor) -> Motor {
4388 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]]) } }
4389 }
4390}
4391
4392impl LeftContraction<Rotor> for Translator {
4393 type Output = Rotor;
4394
4395 fn left_contraction(self, other: Rotor) -> Rotor {
4396 Rotor { groups: RotorGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4397 }
4398}
4399
4400impl RightContraction<Rotor> for Translator {
4401 type Output = Translator;
4402
4403 fn right_contraction(self, other: Rotor) -> Translator {
4404 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
4405 }
4406}
4407
4408impl ScalarProduct<Rotor> for Translator {
4409 type Output = f32;
4410
4411 fn scalar_product(self, other: Rotor) -> f32 {
4412 self.group0()[0] * other.group0()[0]
4413 }
4414}
4415
4416impl Add<Point> for Translator {
4417 type Output = Motor;
4418
4419 fn add(self, other: Point) -> Motor {
4420 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]) } }
4421 }
4422}
4423
4424impl Sub<Point> for Translator {
4425 type Output = Motor;
4426
4427 fn sub(self, other: Point) -> Motor {
4428 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]) } }
4429 }
4430}
4431
4432impl GeometricProduct<Point> for Translator {
4433 type Output = Motor;
4434
4435 fn geometric_product(self, other: Point) -> Motor {
4436 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()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4437 }
4438}
4439
4440impl RegressiveProduct<Point> for Translator {
4441 type Output = Plane;
4442
4443 fn regressive_product(self, other: Point) -> Plane {
4444 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]) } }
4445 }
4446}
4447
4448impl OuterProduct<Point> for Translator {
4449 type Output = Point;
4450
4451 fn outer_product(self, other: Point) -> Point {
4452 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4453 }
4454}
4455
4456impl InnerProduct<Point> for Translator {
4457 type Output = Motor;
4458
4459 fn inner_product(self, other: Point) -> Motor {
4460 Motor { groups: MotorGroups { 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]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
4461 }
4462}
4463
4464impl LeftContraction<Point> for Translator {
4465 type Output = Motor;
4466
4467 fn left_contraction(self, other: Point) -> Motor {
4468 Motor { groups: MotorGroups { 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]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
4469 }
4470}
4471
4472impl RightContraction<Point> for Translator {
4473 type Output = f32;
4474
4475 fn right_contraction(self, other: Point) -> f32 {
4476 0.0 - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
4477 }
4478}
4479
4480impl ScalarProduct<Point> for Translator {
4481 type Output = f32;
4482
4483 fn scalar_product(self, other: Point) -> f32 {
4484 0.0 - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
4485 }
4486}
4487
4488impl Into<IdealPoint> for Translator {
4489 fn into(self) -> IdealPoint {
4490 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[1], self.group0()[2]]) } }
4491 }
4492}
4493
4494impl Add<IdealPoint> for Translator {
4495 type Output = Translator;
4496
4497 fn add(self, other: IdealPoint) -> Translator {
4498 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]) } }
4499 }
4500}
4501
4502impl AddAssign<IdealPoint> for Translator {
4503 fn add_assign(&mut self, other: IdealPoint) {
4504 *self = (*self).add(other);
4505 }
4506}
4507
4508impl Sub<IdealPoint> for Translator {
4509 type Output = Translator;
4510
4511 fn sub(self, other: IdealPoint) -> Translator {
4512 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]) } }
4513 }
4514}
4515
4516impl SubAssign<IdealPoint> for Translator {
4517 fn sub_assign(&mut self, other: IdealPoint) {
4518 *self = (*self).sub(other);
4519 }
4520}
4521
4522impl GeometricProduct<IdealPoint> for Translator {
4523 type Output = Motor;
4524
4525 fn geometric_product(self, other: IdealPoint) -> Motor {
4526 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[2]) * 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()[1], self.group0()[1], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
4527 }
4528}
4529
4530impl OuterProduct<IdealPoint> for Translator {
4531 type Output = IdealPoint;
4532
4533 fn outer_product(self, other: IdealPoint) -> IdealPoint {
4534 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
4535 }
4536}
4537
4538impl InnerProduct<IdealPoint> for Translator {
4539 type Output = Translator;
4540
4541 fn inner_product(self, other: IdealPoint) -> Translator {
4542 Translator { groups: TranslatorGroups { 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) * Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([-1.0, 1.0, 1.0]) } }
4543 }
4544}
4545
4546impl LeftContraction<IdealPoint> for Translator {
4547 type Output = Translator;
4548
4549 fn left_contraction(self, other: IdealPoint) -> Translator {
4550 Translator { groups: TranslatorGroups { 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) * Simd32x3::from([other.group0()[0], other.group0()[0], other.group0()[1]]) * Simd32x3::from([-1.0, 1.0, 1.0]) } }
4551 }
4552}
4553
4554impl RightContraction<IdealPoint> for Translator {
4555 type Output = f32;
4556
4557 fn right_contraction(self, other: IdealPoint) -> f32 {
4558 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1]
4559 }
4560}
4561
4562impl ScalarProduct<IdealPoint> for Translator {
4563 type Output = f32;
4564
4565 fn scalar_product(self, other: IdealPoint) -> f32 {
4566 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1]
4567 }
4568}
4569
4570impl GeometricProduct<Plane> for Translator {
4571 type Output = MotorDual;
4572
4573 fn geometric_product(self, other: Plane) -> MotorDual {
4574 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], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4575 }
4576}
4577
4578impl RegressiveProduct<Plane> for Translator {
4579 type Output = f32;
4580
4581 fn regressive_product(self, other: Plane) -> f32 {
4582 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
4583 }
4584}
4585
4586impl OuterProduct<Plane> for Translator {
4587 type Output = MotorDual;
4588
4589 fn outer_product(self, other: Plane) -> MotorDual {
4590 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]]) } }
4591 }
4592}
4593
4594impl InnerProduct<Plane> for Translator {
4595 type Output = Plane;
4596
4597 fn inner_product(self, other: Plane) -> Plane {
4598 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + 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]) } }
4599 }
4600}
4601
4602impl LeftContraction<Plane> for Translator {
4603 type Output = Plane;
4604
4605 fn left_contraction(self, other: Plane) -> Plane {
4606 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4607 }
4608}
4609
4610impl RightContraction<Plane> for Translator {
4611 type Output = Plane;
4612
4613 fn right_contraction(self, other: Plane) -> Plane {
4614 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]) } }
4615 }
4616}
4617
4618impl Add<Translator> for Translator {
4619 type Output = Translator;
4620
4621 fn add(self, other: Translator) -> Translator {
4622 Translator { groups: TranslatorGroups { g0: self.group0() + other.group0() } }
4623 }
4624}
4625
4626impl AddAssign<Translator> for Translator {
4627 fn add_assign(&mut self, other: Translator) {
4628 *self = (*self).add(other);
4629 }
4630}
4631
4632impl Sub<Translator> for Translator {
4633 type Output = Translator;
4634
4635 fn sub(self, other: Translator) -> Translator {
4636 Translator { groups: TranslatorGroups { g0: self.group0() - other.group0() } }
4637 }
4638}
4639
4640impl SubAssign<Translator> for Translator {
4641 fn sub_assign(&mut self, other: Translator) {
4642 *self = (*self).sub(other);
4643 }
4644}
4645
4646impl Mul<Translator> for Translator {
4647 type Output = Translator;
4648
4649 fn mul(self, other: Translator) -> Translator {
4650 Translator { groups: TranslatorGroups { g0: self.group0() * other.group0() } }
4651 }
4652}
4653
4654impl MulAssign<Translator> for Translator {
4655 fn mul_assign(&mut self, other: Translator) {
4656 *self = (*self).mul(other);
4657 }
4658}
4659
4660impl Div<Translator> for Translator {
4661 type Output = Translator;
4662
4663 fn div(self, other: Translator) -> Translator {
4664 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]) } }
4665 }
4666}
4667
4668impl DivAssign<Translator> for Translator {
4669 fn div_assign(&mut self, other: Translator) {
4670 *self = (*self).div(other);
4671 }
4672}
4673
4674impl GeometricProduct<Translator> for Translator {
4675 type Output = Motor;
4676
4677 fn geometric_product(self, other: Translator) -> Motor {
4678 Motor { groups: MotorGroups { 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], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) } }
4679 }
4680}
4681
4682impl OuterProduct<Translator> for Translator {
4683 type Output = Translator;
4684
4685 fn outer_product(self, other: Translator) -> Translator {
4686 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]) } }
4687 }
4688}
4689
4690impl InnerProduct<Translator> for Translator {
4691 type Output = Translator;
4692
4693 fn inner_product(self, other: Translator) -> Translator {
4694 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 0) * Simd32x3::from([-1.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0) * swizzle!(other.group0(), 1, 0, 0) * Simd32x3::from([-1.0, 1.0, 0.0]) } }
4695 }
4696}
4697
4698impl LeftContraction<Translator> for Translator {
4699 type Output = Translator;
4700
4701 fn left_contraction(self, other: Translator) -> Translator {
4702 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + Simd32x3::from(self.group0()[2]) * Simd32x3::from(other.group0()[2]) * Simd32x3::from([-1.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0) * swizzle!(other.group0(), 1, 0, 0) * Simd32x3::from([-1.0, 0.0, 0.0]) } }
4703 }
4704}
4705
4706impl RightContraction<Translator> for Translator {
4707 type Output = Translator;
4708
4709 fn right_contraction(self, other: Translator) -> Translator {
4710 Translator { groups: TranslatorGroups { g0: Simd32x3::from(self.group0()[1]) * swizzle!(other.group0(), 1, 0, 1) * Simd32x3::from([-1.0, 1.0, 0.0]) + Simd32x3::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 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]) } }
4711 }
4712}
4713
4714impl ScalarProduct<Translator> for Translator {
4715 type Output = f32;
4716
4717 fn scalar_product(self, other: Translator) -> f32 {
4718 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2]
4719 }
4720}
4721
4722impl Add<Motor> for Translator {
4723 type Output = Motor;
4724
4725 fn add(self, other: Motor) -> Motor {
4726 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() } }
4727 }
4728}
4729
4730impl Sub<Motor> for Translator {
4731 type Output = Motor;
4732
4733 fn sub(self, other: Motor) -> Motor {
4734 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() } }
4735 }
4736}
4737
4738impl GeometricProduct<Motor> for Translator {
4739 type Output = Motor;
4740
4741 fn geometric_product(self, other: Motor) -> Motor {
4742 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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]) } }
4743 }
4744}
4745
4746impl RegressiveProduct<Motor> for Translator {
4747 type Output = Plane;
4748
4749 fn regressive_product(self, other: Motor) -> Plane {
4750 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]) } }
4751 }
4752}
4753
4754impl OuterProduct<Motor> for Translator {
4755 type Output = Motor;
4756
4757 fn outer_product(self, other: Motor) -> Motor {
4758 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]) } }
4759 }
4760}
4761
4762impl InnerProduct<Motor> for Translator {
4763 type Output = Motor;
4764
4765 fn inner_product(self, other: Motor) -> Motor {
4766 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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]) } }
4767 }
4768}
4769
4770impl LeftContraction<Motor> for Translator {
4771 type Output = Motor;
4772
4773 fn left_contraction(self, other: Motor) -> Motor {
4774 Motor { groups: MotorGroups { 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]) } }
4775 }
4776}
4777
4778impl RightContraction<Motor> for Translator {
4779 type Output = Translator;
4780
4781 fn right_contraction(self, other: Motor) -> Translator {
4782 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]) } }
4783 }
4784}
4785
4786impl ScalarProduct<Motor> for Translator {
4787 type Output = f32;
4788
4789 fn scalar_product(self, other: Motor) -> f32 {
4790 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[2] - self.group0()[2] * other.group0()[3]
4791 }
4792}
4793
4794impl GeometricProduct<MotorDual> for Translator {
4795 type Output = MotorDual;
4796
4797 fn geometric_product(self, other: MotorDual) -> MotorDual {
4798 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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]) } }
4799 }
4800}
4801
4802impl RegressiveProduct<MotorDual> for Translator {
4803 type Output = Translator;
4804
4805 fn regressive_product(self, other: MotorDual) -> Translator {
4806 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]) } }
4807 }
4808}
4809
4810impl OuterProduct<MotorDual> for Translator {
4811 type Output = MotorDual;
4812
4813 fn outer_product(self, other: MotorDual) -> MotorDual {
4814 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]) } }
4815 }
4816}
4817
4818impl InnerProduct<MotorDual> for Translator {
4819 type Output = MotorDual;
4820
4821 fn inner_product(self, other: MotorDual) -> MotorDual {
4822 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, -1.0, 1.0, -1.0]) + Simd32x4::from([self.group0()[0], self.group0()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 3, 0, 1) * Simd32x4::from([0.0, 1.0, -1.0, -1.0]) } }
4823 }
4824}
4825
4826impl LeftContraction<MotorDual> for Translator {
4827 type Output = MotorDual;
4828
4829 fn left_contraction(self, other: MotorDual) -> MotorDual {
4830 MotorDual { groups: MotorDualGroups { 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]) } }
4831 }
4832}
4833
4834impl RightContraction<MotorDual> for Translator {
4835 type Output = Plane;
4836
4837 fn right_contraction(self, other: MotorDual) -> Plane {
4838 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]) } }
4839 }
4840}
4841
4842impl SquaredMagnitude for Translator {
4843 type Output = f32;
4844
4845 fn squared_magnitude(self) -> f32 {
4846 self.scalar_product(self.reversal())
4847 }
4848}
4849
4850impl Magnitude for Translator {
4851 type Output = f32;
4852
4853 fn magnitude(self) -> f32 {
4854 self.squared_magnitude().sqrt()
4855 }
4856}
4857
4858impl Mul<f32> for Translator {
4859 type Output = Translator;
4860
4861 fn mul(self, other: f32) -> Translator {
4862 self.geometric_product(other)
4863 }
4864}
4865
4866impl MulAssign<f32> for Translator {
4867 fn mul_assign(&mut self, other: f32) {
4868 *self = (*self).mul(other);
4869 }
4870}
4871
4872impl Signum for Translator {
4873 type Output = Translator;
4874
4875 fn signum(self) -> Translator {
4876 self.geometric_product(1.0 / self.magnitude())
4877 }
4878}
4879
4880impl Inverse for Translator {
4881 type Output = Translator;
4882
4883 fn inverse(self) -> Translator {
4884 self.reversal().geometric_product(1.0 / self.squared_magnitude())
4885 }
4886}
4887
4888impl Zero for Motor {
4889 fn zero() -> Self {
4890 Motor { groups: MotorGroups { g0: Simd32x4::from(0.0) } }
4891 }
4892}
4893
4894impl One for Motor {
4895 fn one() -> Self {
4896 Motor { groups: MotorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4897 }
4898}
4899
4900impl Neg for Motor {
4901 type Output = Motor;
4902
4903 fn neg(self) -> Motor {
4904 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
4905 }
4906}
4907
4908impl Automorphism for Motor {
4909 type Output = Motor;
4910
4911 fn automorphism(self) -> Motor {
4912 Motor { groups: MotorGroups { g0: self.group0() } }
4913 }
4914}
4915
4916impl Reversal for Motor {
4917 type Output = Motor;
4918
4919 fn reversal(self) -> Motor {
4920 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
4921 }
4922}
4923
4924impl Conjugation for Motor {
4925 type Output = Motor;
4926
4927 fn conjugation(self) -> Motor {
4928 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
4929 }
4930}
4931
4932impl Dual for Motor {
4933 type Output = MotorDual;
4934
4935 fn dual(self) -> MotorDual {
4936 MotorDual { groups: MotorDualGroups { g0: self.group0() } }
4937 }
4938}
4939
4940impl Into<f32> for Motor {
4941 fn into(self) -> f32 {
4942 self.group0()[0]
4943 }
4944}
4945
4946impl Add<f32> for Motor {
4947 type Output = Motor;
4948
4949 fn add(self, other: f32) -> Motor {
4950 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4951 }
4952}
4953
4954impl AddAssign<f32> for Motor {
4955 fn add_assign(&mut self, other: f32) {
4956 *self = (*self).add(other);
4957 }
4958}
4959
4960impl Sub<f32> for Motor {
4961 type Output = Motor;
4962
4963 fn sub(self, other: f32) -> Motor {
4964 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4965 }
4966}
4967
4968impl SubAssign<f32> for Motor {
4969 fn sub_assign(&mut self, other: f32) {
4970 *self = (*self).sub(other);
4971 }
4972}
4973
4974impl GeometricProduct<f32> for Motor {
4975 type Output = Motor;
4976
4977 fn geometric_product(self, other: f32) -> Motor {
4978 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4979 }
4980}
4981
4982impl OuterProduct<f32> for Motor {
4983 type Output = Motor;
4984
4985 fn outer_product(self, other: f32) -> Motor {
4986 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4987 }
4988}
4989
4990impl InnerProduct<f32> for Motor {
4991 type Output = Motor;
4992
4993 fn inner_product(self, other: f32) -> Motor {
4994 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
4995 }
4996}
4997
4998impl LeftContraction<f32> for Motor {
4999 type Output = f32;
5000
5001 fn left_contraction(self, other: f32) -> f32 {
5002 self.group0()[0] * other
5003 }
5004}
5005
5006impl RightContraction<f32> for Motor {
5007 type Output = Motor;
5008
5009 fn right_contraction(self, other: f32) -> Motor {
5010 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other) } }
5011 }
5012}
5013
5014impl ScalarProduct<f32> for Motor {
5015 type Output = f32;
5016
5017 fn scalar_product(self, other: f32) -> f32 {
5018 self.group0()[0] * other
5019 }
5020}
5021
5022impl Add<MultiVector> for Motor {
5023 type Output = MultiVector;
5024
5025 fn add(self, other: MultiVector) -> MultiVector {
5026 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() } }
5027 }
5028}
5029
5030impl Sub<MultiVector> for Motor {
5031 type Output = MultiVector;
5032
5033 fn sub(self, other: MultiVector) -> MultiVector {
5034 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() } }
5035 }
5036}
5037
5038impl GeometricProduct<MultiVector> for Motor {
5039 type Output = MultiVector;
5040
5041 fn geometric_product(self, other: MultiVector) -> MultiVector {
5042 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.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([-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]) } }
5043 }
5044}
5045
5046impl OuterProduct<MultiVector> for Motor {
5047 type Output = MultiVector;
5048
5049 fn outer_product(self, other: MultiVector) -> MultiVector {
5050 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]) } }
5051 }
5052}
5053
5054impl InnerProduct<MultiVector> for Motor {
5055 type Output = MultiVector;
5056
5057 fn inner_product(self, other: MultiVector) -> MultiVector {
5058 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.group1(), 3, 3, 1, 0) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + swizzle!(self.group0(), 2, 0, 2, 2) * swizzle!(other.group1(), 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.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]) } }
5059 }
5060}
5061
5062impl LeftContraction<MultiVector> for Motor {
5063 type Output = MultiVector;
5064
5065 fn left_contraction(self, other: MultiVector) -> MultiVector {
5066 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]) } }
5067 }
5068}
5069
5070impl ScalarProduct<MultiVector> for Motor {
5071 type Output = f32;
5072
5073 fn scalar_product(self, other: MultiVector) -> f32 {
5074 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group1()[2] - self.group0()[3] * other.group1()[3]
5075 }
5076}
5077
5078impl Into<Rotor> for Motor {
5079 fn into(self) -> Rotor {
5080 Rotor { groups: RotorGroups { g0: Simd32x2::from([self.group0()[0], self.group0()[1]]) } }
5081 }
5082}
5083
5084impl Add<Rotor> for Motor {
5085 type Output = Motor;
5086
5087 fn add(self, other: Rotor) -> Motor {
5088 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]) } }
5089 }
5090}
5091
5092impl AddAssign<Rotor> for Motor {
5093 fn add_assign(&mut self, other: Rotor) {
5094 *self = (*self).add(other);
5095 }
5096}
5097
5098impl Sub<Rotor> for Motor {
5099 type Output = Motor;
5100
5101 fn sub(self, other: Rotor) -> Motor {
5102 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]) } }
5103 }
5104}
5105
5106impl SubAssign<Rotor> for Motor {
5107 fn sub_assign(&mut self, other: Rotor) {
5108 *self = (*self).sub(other);
5109 }
5110}
5111
5112impl GeometricProduct<Rotor> for Motor {
5113 type Output = Motor;
5114
5115 fn geometric_product(self, other: Rotor) -> Motor {
5116 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]) } }
5117 }
5118}
5119
5120impl OuterProduct<Rotor> for Motor {
5121 type Output = Motor;
5122
5123 fn outer_product(self, other: Rotor) -> Motor {
5124 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]]) } }
5125 }
5126}
5127
5128impl InnerProduct<Rotor> for Motor {
5129 type Output = Motor;
5130
5131 fn inner_product(self, other: Rotor) -> Motor {
5132 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]]) } }
5133 }
5134}
5135
5136impl LeftContraction<Rotor> for Motor {
5137 type Output = Rotor;
5138
5139 fn left_contraction(self, other: Rotor) -> Rotor {
5140 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]) } }
5141 }
5142}
5143
5144impl RightContraction<Rotor> for Motor {
5145 type Output = Motor;
5146
5147 fn right_contraction(self, other: Rotor) -> Motor {
5148 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]) } }
5149 }
5150}
5151
5152impl ScalarProduct<Rotor> for Motor {
5153 type Output = f32;
5154
5155 fn scalar_product(self, other: Rotor) -> f32 {
5156 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1]
5157 }
5158}
5159
5160impl Into<Point> for Motor {
5161 fn into(self) -> Point {
5162 Point { groups: PointGroups { g0: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
5163 }
5164}
5165
5166impl Add<Point> for Motor {
5167 type Output = Motor;
5168
5169 fn add(self, other: Point) -> Motor {
5170 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]) } }
5171 }
5172}
5173
5174impl AddAssign<Point> for Motor {
5175 fn add_assign(&mut self, other: Point) {
5176 *self = (*self).add(other);
5177 }
5178}
5179
5180impl Sub<Point> for Motor {
5181 type Output = Motor;
5182
5183 fn sub(self, other: Point) -> Motor {
5184 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]) } }
5185 }
5186}
5187
5188impl SubAssign<Point> for Motor {
5189 fn sub_assign(&mut self, other: Point) {
5190 *self = (*self).sub(other);
5191 }
5192}
5193
5194impl GeometricProduct<Point> for Motor {
5195 type Output = Motor;
5196
5197 fn geometric_product(self, other: Point) -> Motor {
5198 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()[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, 1.0, 1.0, 1.0]) } }
5199 }
5200}
5201
5202impl RegressiveProduct<Point> for Motor {
5203 type Output = Plane;
5204
5205 fn regressive_product(self, other: Point) -> Plane {
5206 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]) } }
5207 }
5208}
5209
5210impl OuterProduct<Point> for Motor {
5211 type Output = Point;
5212
5213 fn outer_product(self, other: Point) -> Point {
5214 Point { groups: PointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
5215 }
5216}
5217
5218impl InnerProduct<Point> for Motor {
5219 type Output = Motor;
5220
5221 fn inner_product(self, other: Point) -> Motor {
5222 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]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5223 }
5224}
5225
5226impl LeftContraction<Point> for Motor {
5227 type Output = Motor;
5228
5229 fn left_contraction(self, other: Point) -> Motor {
5230 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]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5231 }
5232}
5233
5234impl RightContraction<Point> for Motor {
5235 type Output = f32;
5236
5237 fn right_contraction(self, other: Point) -> f32 {
5238 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1] - self.group0()[3] * other.group0()[2]
5239 }
5240}
5241
5242impl ScalarProduct<Point> for Motor {
5243 type Output = f32;
5244
5245 fn scalar_product(self, other: Point) -> f32 {
5246 0.0 - self.group0()[1] * other.group0()[0] - self.group0()[2] * other.group0()[1] - self.group0()[3] * other.group0()[2]
5247 }
5248}
5249
5250impl Into<IdealPoint> for Motor {
5251 fn into(self) -> IdealPoint {
5252 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from([self.group0()[2], self.group0()[3]]) } }
5253 }
5254}
5255
5256impl Add<IdealPoint> for Motor {
5257 type Output = Motor;
5258
5259 fn add(self, other: IdealPoint) -> Motor {
5260 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]) } }
5261 }
5262}
5263
5264impl AddAssign<IdealPoint> for Motor {
5265 fn add_assign(&mut self, other: IdealPoint) {
5266 *self = (*self).add(other);
5267 }
5268}
5269
5270impl Sub<IdealPoint> for Motor {
5271 type Output = Motor;
5272
5273 fn sub(self, other: IdealPoint) -> Motor {
5274 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]) } }
5275 }
5276}
5277
5278impl SubAssign<IdealPoint> for Motor {
5279 fn sub_assign(&mut self, other: IdealPoint) {
5280 *self = (*self).sub(other);
5281 }
5282}
5283
5284impl GeometricProduct<IdealPoint> for Motor {
5285 type Output = Motor;
5286
5287 fn geometric_product(self, other: IdealPoint) -> Motor {
5288 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * 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()[3]) * 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(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5289 }
5290}
5291
5292impl RegressiveProduct<IdealPoint> for Motor {
5293 type Output = Plane;
5294
5295 fn regressive_product(self, other: IdealPoint) -> Plane {
5296 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]) } }
5297 }
5298}
5299
5300impl OuterProduct<IdealPoint> for Motor {
5301 type Output = IdealPoint;
5302
5303 fn outer_product(self, other: IdealPoint) -> IdealPoint {
5304 IdealPoint { groups: IdealPointGroups { g0: Simd32x2::from(self.group0()[0]) * other.group0() } }
5305 }
5306}
5307
5308impl InnerProduct<IdealPoint> for Motor {
5309 type Output = Translator;
5310
5311 fn inner_product(self, other: IdealPoint) -> Translator {
5312 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]]) * Simd32x3::from([-1.0, 1.0, 1.0]) } }
5313 }
5314}
5315
5316impl LeftContraction<IdealPoint> for Motor {
5317 type Output = Translator;
5318
5319 fn left_contraction(self, other: IdealPoint) -> Translator {
5320 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]]) * Simd32x3::from([-1.0, 1.0, 1.0]) } }
5321 }
5322}
5323
5324impl RightContraction<IdealPoint> for Motor {
5325 type Output = f32;
5326
5327 fn right_contraction(self, other: IdealPoint) -> f32 {
5328 0.0 - self.group0()[2] * other.group0()[0] - self.group0()[3] * other.group0()[1]
5329 }
5330}
5331
5332impl ScalarProduct<IdealPoint> for Motor {
5333 type Output = f32;
5334
5335 fn scalar_product(self, other: IdealPoint) -> f32 {
5336 0.0 - self.group0()[2] * other.group0()[0] - self.group0()[3] * other.group0()[1]
5337 }
5338}
5339
5340impl GeometricProduct<Plane> for Motor {
5341 type Output = MotorDual;
5342
5343 fn geometric_product(self, other: Plane) -> MotorDual {
5344 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()[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, 1.0, 1.0, 1.0]) } }
5345 }
5346}
5347
5348impl RegressiveProduct<Plane> for Motor {
5349 type Output = f32;
5350
5351 fn regressive_product(self, other: Plane) -> f32 {
5352 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
5353 }
5354}
5355
5356impl OuterProduct<Plane> for Motor {
5357 type Output = MotorDual;
5358
5359 fn outer_product(self, other: Plane) -> MotorDual {
5360 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]]) } }
5361 }
5362}
5363
5364impl InnerProduct<Plane> for Motor {
5365 type Output = Plane;
5366
5367 fn inner_product(self, other: Plane) -> Plane {
5368 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() + 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]) } }
5369 }
5370}
5371
5372impl LeftContraction<Plane> for Motor {
5373 type Output = Plane;
5374
5375 fn left_contraction(self, other: Plane) -> Plane {
5376 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
5377 }
5378}
5379
5380impl RightContraction<Plane> for Motor {
5381 type Output = Plane;
5382
5383 fn right_contraction(self, other: Plane) -> Plane {
5384 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]) } }
5385 }
5386}
5387
5388impl Into<Translator> for Motor {
5389 fn into(self) -> Translator {
5390 Translator { groups: TranslatorGroups { g0: Simd32x3::from([self.group0()[0], self.group0()[2], self.group0()[3]]) } }
5391 }
5392}
5393
5394impl Add<Translator> for Motor {
5395 type Output = Motor;
5396
5397 fn add(self, other: Translator) -> Motor {
5398 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]) } }
5399 }
5400}
5401
5402impl AddAssign<Translator> for Motor {
5403 fn add_assign(&mut self, other: Translator) {
5404 *self = (*self).add(other);
5405 }
5406}
5407
5408impl Sub<Translator> for Motor {
5409 type Output = Motor;
5410
5411 fn sub(self, other: Translator) -> Motor {
5412 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]) } }
5413 }
5414}
5415
5416impl SubAssign<Translator> for Motor {
5417 fn sub_assign(&mut self, other: Translator) {
5418 *self = (*self).sub(other);
5419 }
5420}
5421
5422impl GeometricProduct<Translator> for Motor {
5423 type Output = Motor;
5424
5425 fn geometric_product(self, other: Translator) -> Motor {
5426 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()[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]) + 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]) } }
5427 }
5428}
5429
5430impl RegressiveProduct<Translator> for Motor {
5431 type Output = Plane;
5432
5433 fn regressive_product(self, other: Translator) -> Plane {
5434 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]) } }
5435 }
5436}
5437
5438impl OuterProduct<Translator> for Motor {
5439 type Output = Motor;
5440
5441 fn outer_product(self, other: Translator) -> Motor {
5442 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]]) } }
5443 }
5444}
5445
5446impl InnerProduct<Translator> for Motor {
5447 type Output = Motor;
5448
5449 fn inner_product(self, other: Translator) -> Motor {
5450 Motor { groups: MotorGroups { 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], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5451 }
5452}
5453
5454impl LeftContraction<Translator> for Motor {
5455 type Output = Translator;
5456
5457 fn left_contraction(self, other: Translator) -> Translator {
5458 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]) } }
5459 }
5460}
5461
5462impl RightContraction<Translator> for Motor {
5463 type Output = Motor;
5464
5465 fn right_contraction(self, other: Translator) -> Motor {
5466 Motor { groups: MotorGroups { 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]) } }
5467 }
5468}
5469
5470impl ScalarProduct<Translator> for Motor {
5471 type Output = f32;
5472
5473 fn scalar_product(self, other: Translator) -> f32 {
5474 self.group0()[0] * other.group0()[0] - self.group0()[2] * other.group0()[1] - self.group0()[3] * other.group0()[2]
5475 }
5476}
5477
5478impl Add<Motor> for Motor {
5479 type Output = Motor;
5480
5481 fn add(self, other: Motor) -> Motor {
5482 Motor { groups: MotorGroups { g0: self.group0() + other.group0() } }
5483 }
5484}
5485
5486impl AddAssign<Motor> for Motor {
5487 fn add_assign(&mut self, other: Motor) {
5488 *self = (*self).add(other);
5489 }
5490}
5491
5492impl Sub<Motor> for Motor {
5493 type Output = Motor;
5494
5495 fn sub(self, other: Motor) -> Motor {
5496 Motor { groups: MotorGroups { g0: self.group0() - other.group0() } }
5497 }
5498}
5499
5500impl SubAssign<Motor> for Motor {
5501 fn sub_assign(&mut self, other: Motor) {
5502 *self = (*self).sub(other);
5503 }
5504}
5505
5506impl Mul<Motor> for Motor {
5507 type Output = Motor;
5508
5509 fn mul(self, other: Motor) -> Motor {
5510 Motor { groups: MotorGroups { g0: self.group0() * other.group0() } }
5511 }
5512}
5513
5514impl MulAssign<Motor> for Motor {
5515 fn mul_assign(&mut self, other: Motor) {
5516 *self = (*self).mul(other);
5517 }
5518}
5519
5520impl Div<Motor> for Motor {
5521 type Output = Motor;
5522
5523 fn div(self, other: Motor) -> Motor {
5524 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]) } }
5525 }
5526}
5527
5528impl DivAssign<Motor> for Motor {
5529 fn div_assign(&mut self, other: Motor) {
5530 *self = (*self).div(other);
5531 }
5532}
5533
5534impl GeometricProduct<Motor> for Motor {
5535 type Output = Motor;
5536
5537 fn geometric_product(self, other: Motor) -> Motor {
5538 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()[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]) } }
5539 }
5540}
5541
5542impl RegressiveProduct<Motor> for Motor {
5543 type Output = Plane;
5544
5545 fn regressive_product(self, other: Motor) -> Plane {
5546 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]) } }
5547 }
5548}
5549
5550impl OuterProduct<Motor> for Motor {
5551 type Output = Motor;
5552
5553 fn outer_product(self, other: Motor) -> Motor {
5554 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]) } }
5555 }
5556}
5557
5558impl InnerProduct<Motor> for Motor {
5559 type Output = Motor;
5560
5561 fn inner_product(self, other: Motor) -> Motor {
5562 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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, 1, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) } }
5563 }
5564}
5565
5566impl LeftContraction<Motor> for Motor {
5567 type Output = Motor;
5568
5569 fn left_contraction(self, other: Motor) -> Motor {
5570 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]) } }
5571 }
5572}
5573
5574impl RightContraction<Motor> for Motor {
5575 type Output = Motor;
5576
5577 fn right_contraction(self, other: Motor) -> Motor {
5578 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]) } }
5579 }
5580}
5581
5582impl ScalarProduct<Motor> for Motor {
5583 type Output = f32;
5584
5585 fn scalar_product(self, other: Motor) -> f32 {
5586 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2] - self.group0()[3] * other.group0()[3]
5587 }
5588}
5589
5590impl Add<MotorDual> for Motor {
5591 type Output = MultiVector;
5592
5593 fn add(self, other: MotorDual) -> MultiVector {
5594 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]) } }
5595 }
5596}
5597
5598impl Sub<MotorDual> for Motor {
5599 type Output = MultiVector;
5600
5601 fn sub(self, other: MotorDual) -> MultiVector {
5602 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]) } }
5603 }
5604}
5605
5606impl GeometricProduct<MotorDual> for Motor {
5607 type Output = MotorDual;
5608
5609 fn geometric_product(self, other: MotorDual) -> MotorDual {
5610 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()[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]) } }
5611 }
5612}
5613
5614impl RegressiveProduct<MotorDual> for Motor {
5615 type Output = Motor;
5616
5617 fn regressive_product(self, other: MotorDual) -> Motor {
5618 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]) } }
5619 }
5620}
5621
5622impl OuterProduct<MotorDual> for Motor {
5623 type Output = MotorDual;
5624
5625 fn outer_product(self, other: MotorDual) -> MotorDual {
5626 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]) } }
5627 }
5628}
5629
5630impl InnerProduct<MotorDual> for Motor {
5631 type Output = MotorDual;
5632
5633 fn inner_product(self, other: MotorDual) -> MotorDual {
5634 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) } }
5635 }
5636}
5637
5638impl LeftContraction<MotorDual> for Motor {
5639 type Output = MotorDual;
5640
5641 fn left_contraction(self, other: MotorDual) -> MotorDual {
5642 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]) } }
5643 }
5644}
5645
5646impl RightContraction<MotorDual> for Motor {
5647 type Output = Plane;
5648
5649 fn right_contraction(self, other: MotorDual) -> Plane {
5650 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]) } }
5651 }
5652}
5653
5654impl SquaredMagnitude for Motor {
5655 type Output = f32;
5656
5657 fn squared_magnitude(self) -> f32 {
5658 self.scalar_product(self.reversal())
5659 }
5660}
5661
5662impl Magnitude for Motor {
5663 type Output = f32;
5664
5665 fn magnitude(self) -> f32 {
5666 self.squared_magnitude().sqrt()
5667 }
5668}
5669
5670impl Mul<f32> for Motor {
5671 type Output = Motor;
5672
5673 fn mul(self, other: f32) -> Motor {
5674 self.geometric_product(other)
5675 }
5676}
5677
5678impl MulAssign<f32> for Motor {
5679 fn mul_assign(&mut self, other: f32) {
5680 *self = (*self).mul(other);
5681 }
5682}
5683
5684impl Signum for Motor {
5685 type Output = Motor;
5686
5687 fn signum(self) -> Motor {
5688 self.geometric_product(1.0 / self.magnitude())
5689 }
5690}
5691
5692impl Inverse for Motor {
5693 type Output = Motor;
5694
5695 fn inverse(self) -> Motor {
5696 self.reversal().geometric_product(1.0 / self.squared_magnitude())
5697 }
5698}
5699
5700impl Zero for MotorDual {
5701 fn zero() -> Self {
5702 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(0.0) } }
5703 }
5704}
5705
5706impl One for MotorDual {
5707 fn one() -> Self {
5708 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(0.0) } }
5709 }
5710}
5711
5712impl Neg for MotorDual {
5713 type Output = MotorDual;
5714
5715 fn neg(self) -> MotorDual {
5716 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
5717 }
5718}
5719
5720impl Automorphism for MotorDual {
5721 type Output = MotorDual;
5722
5723 fn automorphism(self) -> MotorDual {
5724 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
5725 }
5726}
5727
5728impl Reversal for MotorDual {
5729 type Output = MotorDual;
5730
5731 fn reversal(self) -> MotorDual {
5732 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5733 }
5734}
5735
5736impl Conjugation for MotorDual {
5737 type Output = MotorDual;
5738
5739 fn conjugation(self) -> MotorDual {
5740 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
5741 }
5742}
5743
5744impl Dual for MotorDual {
5745 type Output = Motor;
5746
5747 fn dual(self) -> Motor {
5748 Motor { groups: MotorGroups { g0: self.group0() } }
5749 }
5750}
5751
5752impl GeometricProduct<f32> for MotorDual {
5753 type Output = MotorDual;
5754
5755 fn geometric_product(self, other: f32) -> MotorDual {
5756 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5757 }
5758}
5759
5760impl RegressiveProduct<f32> for MotorDual {
5761 type Output = f32;
5762
5763 fn regressive_product(self, other: f32) -> f32 {
5764 self.group0()[0] * other
5765 }
5766}
5767
5768impl OuterProduct<f32> for MotorDual {
5769 type Output = MotorDual;
5770
5771 fn outer_product(self, other: f32) -> MotorDual {
5772 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5773 }
5774}
5775
5776impl InnerProduct<f32> for MotorDual {
5777 type Output = MotorDual;
5778
5779 fn inner_product(self, other: f32) -> MotorDual {
5780 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5781 }
5782}
5783
5784impl RightContraction<f32> for MotorDual {
5785 type Output = MotorDual;
5786
5787 fn right_contraction(self, other: f32) -> MotorDual {
5788 MotorDual { groups: MotorDualGroups { g0: self.group0() * Simd32x4::from(other) } }
5789 }
5790}
5791
5792impl Add<MultiVector> for MotorDual {
5793 type Output = MultiVector;
5794
5795 fn add(self, other: MultiVector) -> MultiVector {
5796 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() } }
5797 }
5798}
5799
5800impl Sub<MultiVector> for MotorDual {
5801 type Output = MultiVector;
5802
5803 fn sub(self, other: MultiVector) -> MultiVector {
5804 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() } }
5805 }
5806}
5807
5808impl GeometricProduct<MultiVector> for MotorDual {
5809 type Output = MultiVector;
5810
5811 fn geometric_product(self, other: MultiVector) -> MultiVector {
5812 MultiVector { groups: MultiVectorGroups { g0: 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]) * other.group1() * 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()[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]) } }
5813 }
5814}
5815
5816impl RegressiveProduct<MultiVector> for MotorDual {
5817 type Output = MultiVector;
5818
5819 fn regressive_product(self, other: MultiVector) -> MultiVector {
5820 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]) } }
5821 }
5822}
5823
5824impl InnerProduct<MultiVector> for MotorDual {
5825 type Output = MultiVector;
5826
5827 fn inner_product(self, other: MultiVector) -> MultiVector {
5828 MultiVector { groups: MultiVectorGroups { g0: 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]) * other.group1() * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 0, 1) * Simd32x4::from([1.0, 0.0, 1.0, 1.0]) + swizzle!(self.group0(), 2, 0, 2, 2) * swizzle!(other.group0(), 3, 0, 1, 0) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]), 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()[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]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5829 }
5830}
5831
5832impl RightContraction<MultiVector> for MotorDual {
5833 type Output = MultiVector;
5834
5835 fn right_contraction(self, other: MultiVector) -> MultiVector {
5836 MultiVector { groups: MultiVectorGroups { g0: 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()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5837 }
5838}
5839
5840impl ScalarProduct<MultiVector> for MotorDual {
5841 type Output = f32;
5842
5843 fn scalar_product(self, other: MultiVector) -> f32 {
5844 0.0 - self.group0()[0] * other.group1()[1] + self.group0()[1] * other.group1()[0] + self.group0()[2] * other.group0()[3] + self.group0()[3] * other.group0()[2]
5845 }
5846}
5847
5848impl GeometricProduct<Rotor> for MotorDual {
5849 type Output = MotorDual;
5850
5851 fn geometric_product(self, other: Rotor) -> MotorDual {
5852 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]) } }
5853 }
5854}
5855
5856impl RegressiveProduct<Rotor> for MotorDual {
5857 type Output = Rotor;
5858
5859 fn regressive_product(self, other: Rotor) -> Rotor {
5860 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]) } }
5861 }
5862}
5863
5864impl OuterProduct<Rotor> for MotorDual {
5865 type Output = MotorDual;
5866
5867 fn outer_product(self, other: Rotor) -> MotorDual {
5868 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]) } }
5869 }
5870}
5871
5872impl InnerProduct<Rotor> for MotorDual {
5873 type Output = MotorDual;
5874
5875 fn inner_product(self, other: Rotor) -> MotorDual {
5876 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]) } }
5877 }
5878}
5879
5880impl RightContraction<Rotor> for MotorDual {
5881 type Output = MotorDual;
5882
5883 fn right_contraction(self, other: Rotor) -> MotorDual {
5884 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]) } }
5885 }
5886}
5887
5888impl GeometricProduct<Point> for MotorDual {
5889 type Output = MotorDual;
5890
5891 fn geometric_product(self, other: Point) -> MotorDual {
5892 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()[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, -1.0, -1.0, -1.0]) } }
5893 }
5894}
5895
5896impl RegressiveProduct<Point> for MotorDual {
5897 type Output = Motor;
5898
5899 fn regressive_product(self, other: Point) -> Motor {
5900 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]]) } }
5901 }
5902}
5903
5904impl InnerProduct<Point> for MotorDual {
5905 type Output = Plane;
5906
5907 fn inner_product(self, other: Point) -> Plane {
5908 Plane { groups: PlaneGroups { g0: Simd32x3::from(0.0) - Simd32x3::from(self.group0()[0]) * other.group0() + 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]) } }
5909 }
5910}
5911
5912impl LeftContraction<Point> for MotorDual {
5913 type Output = Plane;
5914
5915 fn left_contraction(self, other: Point) -> Plane {
5916 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]) } }
5917 }
5918}
5919
5920impl RightContraction<Point> for MotorDual {
5921 type Output = Plane;
5922
5923 fn right_contraction(self, other: Point) -> Plane {
5924 Plane { groups: PlaneGroups { g0: Simd32x3::from(0.0) - Simd32x3::from(self.group0()[0]) * other.group0() } }
5925 }
5926}
5927
5928impl GeometricProduct<IdealPoint> for MotorDual {
5929 type Output = MotorDual;
5930
5931 fn geometric_product(self, other: IdealPoint) -> MotorDual {
5932 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[1]) * 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()[3]) * 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(), 2, 2, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
5933 }
5934}
5935
5936impl RegressiveProduct<IdealPoint> for MotorDual {
5937 type Output = Translator;
5938
5939 fn regressive_product(self, other: IdealPoint) -> Translator {
5940 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]]) } }
5941 }
5942}
5943
5944impl InnerProduct<IdealPoint> for MotorDual {
5945 type Output = Plane;
5946
5947 fn inner_product(self, other: IdealPoint) -> Plane {
5948 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[1]) * Simd32x3::from([other.group0()[1], other.group0()[1], other.group0()[0]]) * Simd32x3::from([0.0, -1.0, 1.0]) + 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()[0], self.group0()[0]]) * Simd32x3::from([other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x3::from([1.0, -1.0, -1.0]) } }
5949 }
5950}
5951
5952impl LeftContraction<IdealPoint> for MotorDual {
5953 type Output = Plane;
5954
5955 fn left_contraction(self, other: IdealPoint) -> Plane {
5956 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]) } }
5957 }
5958}
5959
5960impl Into<Plane> for MotorDual {
5961 fn into(self) -> Plane {
5962 Plane { groups: PlaneGroups { g0: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
5963 }
5964}
5965
5966impl Add<Plane> for MotorDual {
5967 type Output = MotorDual;
5968
5969 fn add(self, other: Plane) -> MotorDual {
5970 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]) } }
5971 }
5972}
5973
5974impl AddAssign<Plane> for MotorDual {
5975 fn add_assign(&mut self, other: Plane) {
5976 *self = (*self).add(other);
5977 }
5978}
5979
5980impl Sub<Plane> for MotorDual {
5981 type Output = MotorDual;
5982
5983 fn sub(self, other: Plane) -> MotorDual {
5984 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]) } }
5985 }
5986}
5987
5988impl SubAssign<Plane> for MotorDual {
5989 fn sub_assign(&mut self, other: Plane) {
5990 *self = (*self).sub(other);
5991 }
5992}
5993
5994impl GeometricProduct<Plane> for MotorDual {
5995 type Output = Motor;
5996
5997 fn geometric_product(self, other: Plane) -> Motor {
5998 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()[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, 1.0, 1.0, 1.0]) } }
5999 }
6000}
6001
6002impl RegressiveProduct<Plane> for MotorDual {
6003 type Output = Plane;
6004
6005 fn regressive_product(self, other: Plane) -> Plane {
6006 Plane { groups: PlaneGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
6007 }
6008}
6009
6010impl OuterProduct<Plane> for MotorDual {
6011 type Output = Point;
6012
6013 fn outer_product(self, other: Plane) -> Point {
6014 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]) } }
6015 }
6016}
6017
6018impl InnerProduct<Plane> for MotorDual {
6019 type Output = Motor;
6020
6021 fn inner_product(self, other: Plane) -> Motor {
6022 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]]) } }
6023 }
6024}
6025
6026impl LeftContraction<Plane> for MotorDual {
6027 type Output = f32;
6028
6029 fn left_contraction(self, other: Plane) -> f32 {
6030 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
6031 }
6032}
6033
6034impl RightContraction<Plane> for MotorDual {
6035 type Output = Motor;
6036
6037 fn right_contraction(self, other: Plane) -> Motor {
6038 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]]) } }
6039 }
6040}
6041
6042impl ScalarProduct<Plane> for MotorDual {
6043 type Output = f32;
6044
6045 fn scalar_product(self, other: Plane) -> f32 {
6046 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
6047 }
6048}
6049
6050impl GeometricProduct<Translator> for MotorDual {
6051 type Output = MotorDual;
6052
6053 fn geometric_product(self, other: Translator) -> MotorDual {
6054 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([0.0, 1.0, -1.0, 1.0]) + 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]) + 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]) } }
6055 }
6056}
6057
6058impl RegressiveProduct<Translator> for MotorDual {
6059 type Output = Translator;
6060
6061 fn regressive_product(self, other: Translator) -> Translator {
6062 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]) } }
6063 }
6064}
6065
6066impl OuterProduct<Translator> for MotorDual {
6067 type Output = MotorDual;
6068
6069 fn outer_product(self, other: Translator) -> MotorDual {
6070 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]) } }
6071 }
6072}
6073
6074impl InnerProduct<Translator> for MotorDual {
6075 type Output = MotorDual;
6076
6077 fn inner_product(self, other: Translator) -> MotorDual {
6078 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([0.0, 1.0, -1.0, 1.0]) + 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]) + 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]) } }
6079 }
6080}
6081
6082impl LeftContraction<Translator> for MotorDual {
6083 type Output = Plane;
6084
6085 fn left_contraction(self, other: Translator) -> Plane {
6086 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]) } }
6087 }
6088}
6089
6090impl RightContraction<Translator> for MotorDual {
6091 type Output = MotorDual;
6092
6093 fn right_contraction(self, other: Translator) -> MotorDual {
6094 MotorDual { groups: MotorDualGroups { 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]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
6095 }
6096}
6097
6098impl Add<Motor> for MotorDual {
6099 type Output = MultiVector;
6100
6101 fn add(self, other: Motor) -> MultiVector {
6102 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]) } }
6103 }
6104}
6105
6106impl Sub<Motor> for MotorDual {
6107 type Output = MultiVector;
6108
6109 fn sub(self, other: Motor) -> MultiVector {
6110 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]) } }
6111 }
6112}
6113
6114impl GeometricProduct<Motor> for MotorDual {
6115 type Output = MotorDual;
6116
6117 fn geometric_product(self, other: Motor) -> MotorDual {
6118 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + 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([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]) } }
6119 }
6120}
6121
6122impl RegressiveProduct<Motor> for MotorDual {
6123 type Output = Motor;
6124
6125 fn regressive_product(self, other: Motor) -> Motor {
6126 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]) } }
6127 }
6128}
6129
6130impl OuterProduct<Motor> for MotorDual {
6131 type Output = MotorDual;
6132
6133 fn outer_product(self, other: Motor) -> MotorDual {
6134 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]) } }
6135 }
6136}
6137
6138impl InnerProduct<Motor> for MotorDual {
6139 type Output = MotorDual;
6140
6141 fn inner_product(self, other: Motor) -> MotorDual {
6142 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.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]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) } }
6143 }
6144}
6145
6146impl LeftContraction<Motor> for MotorDual {
6147 type Output = Plane;
6148
6149 fn left_contraction(self, other: Motor) -> Plane {
6150 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]) } }
6151 }
6152}
6153
6154impl RightContraction<Motor> for MotorDual {
6155 type Output = MotorDual;
6156
6157 fn right_contraction(self, other: Motor) -> MotorDual {
6158 MotorDual { groups: MotorDualGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
6159 }
6160}
6161
6162impl Add<MotorDual> for MotorDual {
6163 type Output = MotorDual;
6164
6165 fn add(self, other: MotorDual) -> MotorDual {
6166 MotorDual { groups: MotorDualGroups { g0: self.group0() + other.group0() } }
6167 }
6168}
6169
6170impl AddAssign<MotorDual> for MotorDual {
6171 fn add_assign(&mut self, other: MotorDual) {
6172 *self = (*self).add(other);
6173 }
6174}
6175
6176impl Sub<MotorDual> for MotorDual {
6177 type Output = MotorDual;
6178
6179 fn sub(self, other: MotorDual) -> MotorDual {
6180 MotorDual { groups: MotorDualGroups { g0: self.group0() - other.group0() } }
6181 }
6182}
6183
6184impl SubAssign<MotorDual> for MotorDual {
6185 fn sub_assign(&mut self, other: MotorDual) {
6186 *self = (*self).sub(other);
6187 }
6188}
6189
6190impl Mul<MotorDual> for MotorDual {
6191 type Output = MotorDual;
6192
6193 fn mul(self, other: MotorDual) -> MotorDual {
6194 MotorDual { groups: MotorDualGroups { g0: self.group0() * other.group0() } }
6195 }
6196}
6197
6198impl MulAssign<MotorDual> for MotorDual {
6199 fn mul_assign(&mut self, other: MotorDual) {
6200 *self = (*self).mul(other);
6201 }
6202}
6203
6204impl Div<MotorDual> for MotorDual {
6205 type Output = MotorDual;
6206
6207 fn div(self, other: MotorDual) -> MotorDual {
6208 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]) } }
6209 }
6210}
6211
6212impl DivAssign<MotorDual> for MotorDual {
6213 fn div_assign(&mut self, other: MotorDual) {
6214 *self = (*self).div(other);
6215 }
6216}
6217
6218impl GeometricProduct<MotorDual> for MotorDual {
6219 type Output = Motor;
6220
6221 fn geometric_product(self, other: MotorDual) -> Motor {
6222 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + 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([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]) } }
6223 }
6224}
6225
6226impl RegressiveProduct<MotorDual> for MotorDual {
6227 type Output = MotorDual;
6228
6229 fn regressive_product(self, other: MotorDual) -> MotorDual {
6230 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]) } }
6231 }
6232}
6233
6234impl OuterProduct<MotorDual> for MotorDual {
6235 type Output = Point;
6236
6237 fn outer_product(self, other: MotorDual) -> Point {
6238 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]) } }
6239 }
6240}
6241
6242impl InnerProduct<MotorDual> for MotorDual {
6243 type Output = Motor;
6244
6245 fn inner_product(self, other: MotorDual) -> Motor {
6246 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() * 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]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
6247 }
6248}
6249
6250impl LeftContraction<MotorDual> for MotorDual {
6251 type Output = Motor;
6252
6253 fn left_contraction(self, other: MotorDual) -> Motor {
6254 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]) } }
6255 }
6256}
6257
6258impl RightContraction<MotorDual> for MotorDual {
6259 type Output = Motor;
6260
6261 fn right_contraction(self, other: MotorDual) -> Motor {
6262 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + 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]) } }
6263 }
6264}
6265
6266impl ScalarProduct<MotorDual> for MotorDual {
6267 type Output = f32;
6268
6269 fn scalar_product(self, other: MotorDual) -> f32 {
6270 0.0 - self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
6271 }
6272}
6273
6274impl SquaredMagnitude for MotorDual {
6275 type Output = f32;
6276
6277 fn squared_magnitude(self) -> f32 {
6278 self.scalar_product(self.reversal())
6279 }
6280}
6281
6282impl Magnitude for MotorDual {
6283 type Output = f32;
6284
6285 fn magnitude(self) -> f32 {
6286 self.squared_magnitude().sqrt()
6287 }
6288}
6289
6290impl Mul<f32> for MotorDual {
6291 type Output = MotorDual;
6292
6293 fn mul(self, other: f32) -> MotorDual {
6294 self.geometric_product(other)
6295 }
6296}
6297
6298impl MulAssign<f32> for MotorDual {
6299 fn mul_assign(&mut self, other: f32) {
6300 *self = (*self).mul(other);
6301 }
6302}
6303
6304impl Signum for MotorDual {
6305 type Output = MotorDual;
6306
6307 fn signum(self) -> MotorDual {
6308 self.geometric_product(1.0 / self.magnitude())
6309 }
6310}
6311
6312impl Inverse for MotorDual {
6313 type Output = MotorDual;
6314
6315 fn inverse(self) -> MotorDual {
6316 self.reversal().geometric_product(1.0 / self.squared_magnitude())
6317 }
6318}
6319
6320impl GeometricQuotient<IdealPoint> for IdealPoint {
6321 type Output = Rotor;
6322
6323 fn geometric_quotient(self, other: IdealPoint) -> Rotor {
6324 self.geometric_product(other.inverse())
6325 }
6326}
6327
6328impl Transformation<IdealPoint> for IdealPoint {
6329 type Output = IdealPoint;
6330
6331 fn transformation(self, other: IdealPoint) -> IdealPoint {
6332 self.geometric_product(other).geometric_product(self.reversal())
6333 }
6334}
6335
6336impl GeometricQuotient<Motor> for IdealPoint {
6337 type Output = Motor;
6338
6339 fn geometric_quotient(self, other: Motor) -> Motor {
6340 self.geometric_product(other.inverse())
6341 }
6342}
6343
6344impl Transformation<Motor> for IdealPoint {
6345 type Output = Motor;
6346
6347 fn transformation(self, other: Motor) -> Motor {
6348 self.geometric_product(other).geometric_product(self.reversal())
6349 }
6350}
6351
6352impl GeometricQuotient<MotorDual> for IdealPoint {
6353 type Output = MotorDual;
6354
6355 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
6356 self.geometric_product(other.inverse())
6357 }
6358}
6359
6360impl Transformation<MotorDual> for IdealPoint {
6361 type Output = MotorDual;
6362
6363 fn transformation(self, other: MotorDual) -> MotorDual {
6364 self.geometric_product(other).geometric_product(self.reversal())
6365 }
6366}
6367
6368impl GeometricQuotient<MultiVector> for IdealPoint {
6369 type Output = MultiVector;
6370
6371 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6372 self.geometric_product(other.inverse())
6373 }
6374}
6375
6376impl Transformation<MultiVector> for IdealPoint {
6377 type Output = MultiVector;
6378
6379 fn transformation(self, other: MultiVector) -> MultiVector {
6380 self.geometric_product(other).geometric_product(self.reversal())
6381 }
6382}
6383
6384impl GeometricQuotient<Plane> for IdealPoint {
6385 type Output = MotorDual;
6386
6387 fn geometric_quotient(self, other: Plane) -> MotorDual {
6388 self.geometric_product(other.inverse())
6389 }
6390}
6391
6392impl Transformation<Plane> for IdealPoint {
6393 type Output = Plane;
6394
6395 fn transformation(self, other: Plane) -> Plane {
6396 self.geometric_product(other).geometric_product(self.reversal()).into()
6397 }
6398}
6399
6400impl GeometricQuotient<Point> for IdealPoint {
6401 type Output = Motor;
6402
6403 fn geometric_quotient(self, other: Point) -> Motor {
6404 self.geometric_product(other.inverse())
6405 }
6406}
6407
6408impl Transformation<Point> for IdealPoint {
6409 type Output = Point;
6410
6411 fn transformation(self, other: Point) -> Point {
6412 self.geometric_product(other).geometric_product(self.reversal()).into()
6413 }
6414}
6415
6416impl GeometricQuotient<Rotor> for IdealPoint {
6417 type Output = IdealPoint;
6418
6419 fn geometric_quotient(self, other: Rotor) -> IdealPoint {
6420 self.geometric_product(other.inverse())
6421 }
6422}
6423
6424impl Transformation<Rotor> for IdealPoint {
6425 type Output = Rotor;
6426
6427 fn transformation(self, other: Rotor) -> Rotor {
6428 self.geometric_product(other).geometric_product(self.reversal())
6429 }
6430}
6431
6432impl GeometricQuotient<f32> for IdealPoint {
6433 type Output = IdealPoint;
6434
6435 fn geometric_quotient(self, other: f32) -> IdealPoint {
6436 self.geometric_product(other.inverse())
6437 }
6438}
6439
6440impl Transformation<f32> for IdealPoint {
6441 type Output = f32;
6442
6443 fn transformation(self, other: f32) -> f32 {
6444 self.geometric_product(other).geometric_product(self.reversal()).into()
6445 }
6446}
6447
6448impl GeometricQuotient<Translator> for IdealPoint {
6449 type Output = Motor;
6450
6451 fn geometric_quotient(self, other: Translator) -> Motor {
6452 self.geometric_product(other.inverse())
6453 }
6454}
6455
6456impl Transformation<Translator> for IdealPoint {
6457 type Output = Translator;
6458
6459 fn transformation(self, other: Translator) -> Translator {
6460 self.geometric_product(other).geometric_product(self.reversal()).into()
6461 }
6462}
6463
6464impl GeometricQuotient<IdealPoint> for Motor {
6465 type Output = Motor;
6466
6467 fn geometric_quotient(self, other: IdealPoint) -> Motor {
6468 self.geometric_product(other.inverse())
6469 }
6470}
6471
6472impl Transformation<IdealPoint> for Motor {
6473 type Output = IdealPoint;
6474
6475 fn transformation(self, other: IdealPoint) -> IdealPoint {
6476 self.geometric_product(other).geometric_product(self.reversal()).into()
6477 }
6478}
6479
6480impl Powi for Motor {
6481 type Output = Motor;
6482
6483 fn powi(self, exponent: isize) -> Motor {
6484 if exponent == 0 {
6485 return Motor::one();
6486 }
6487 let mut x: Motor = if exponent < 0 { self.inverse() } else { self };
6488 let mut y: Motor = Motor::one();
6489 let mut n: isize = exponent.abs();
6490 while 1 < n {
6491 if n & 1 == 1 {
6492 y = x.geometric_product(y);
6493 }
6494 x = x.geometric_product(x);
6495 n = n >> 1;
6496 }
6497 x.geometric_product(y)
6498 }
6499}
6500
6501impl GeometricQuotient<Motor> for Motor {
6502 type Output = Motor;
6503
6504 fn geometric_quotient(self, other: Motor) -> Motor {
6505 self.geometric_product(other.inverse())
6506 }
6507}
6508
6509impl Transformation<Motor> for Motor {
6510 type Output = Motor;
6511
6512 fn transformation(self, other: Motor) -> Motor {
6513 self.geometric_product(other).geometric_product(self.reversal())
6514 }
6515}
6516
6517impl GeometricQuotient<MotorDual> for Motor {
6518 type Output = MotorDual;
6519
6520 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
6521 self.geometric_product(other.inverse())
6522 }
6523}
6524
6525impl Transformation<MotorDual> for Motor {
6526 type Output = MotorDual;
6527
6528 fn transformation(self, other: MotorDual) -> MotorDual {
6529 self.geometric_product(other).geometric_product(self.reversal())
6530 }
6531}
6532
6533impl GeometricQuotient<MultiVector> for Motor {
6534 type Output = MultiVector;
6535
6536 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6537 self.geometric_product(other.inverse())
6538 }
6539}
6540
6541impl Transformation<MultiVector> for Motor {
6542 type Output = MultiVector;
6543
6544 fn transformation(self, other: MultiVector) -> MultiVector {
6545 self.geometric_product(other).geometric_product(self.reversal())
6546 }
6547}
6548
6549impl GeometricQuotient<Plane> for Motor {
6550 type Output = MotorDual;
6551
6552 fn geometric_quotient(self, other: Plane) -> MotorDual {
6553 self.geometric_product(other.inverse())
6554 }
6555}
6556
6557impl Transformation<Plane> for Motor {
6558 type Output = Plane;
6559
6560 fn transformation(self, other: Plane) -> Plane {
6561 self.geometric_product(other).geometric_product(self.reversal()).into()
6562 }
6563}
6564
6565impl GeometricQuotient<Point> for Motor {
6566 type Output = Motor;
6567
6568 fn geometric_quotient(self, other: Point) -> Motor {
6569 self.geometric_product(other.inverse())
6570 }
6571}
6572
6573impl Transformation<Point> for Motor {
6574 type Output = Point;
6575
6576 fn transformation(self, other: Point) -> Point {
6577 self.geometric_product(other).geometric_product(self.reversal()).into()
6578 }
6579}
6580
6581impl GeometricQuotient<Rotor> for Motor {
6582 type Output = Motor;
6583
6584 fn geometric_quotient(self, other: Rotor) -> Motor {
6585 self.geometric_product(other.inverse())
6586 }
6587}
6588
6589impl Transformation<Rotor> for Motor {
6590 type Output = Rotor;
6591
6592 fn transformation(self, other: Rotor) -> Rotor {
6593 self.geometric_product(other).geometric_product(self.reversal()).into()
6594 }
6595}
6596
6597impl GeometricQuotient<f32> for Motor {
6598 type Output = Motor;
6599
6600 fn geometric_quotient(self, other: f32) -> Motor {
6601 self.geometric_product(other.inverse())
6602 }
6603}
6604
6605impl Transformation<f32> for Motor {
6606 type Output = f32;
6607
6608 fn transformation(self, other: f32) -> f32 {
6609 self.geometric_product(other).geometric_product(self.reversal()).into()
6610 }
6611}
6612
6613impl GeometricQuotient<Translator> for Motor {
6614 type Output = Motor;
6615
6616 fn geometric_quotient(self, other: Translator) -> Motor {
6617 self.geometric_product(other.inverse())
6618 }
6619}
6620
6621impl Transformation<Translator> for Motor {
6622 type Output = Translator;
6623
6624 fn transformation(self, other: Translator) -> Translator {
6625 self.geometric_product(other).geometric_product(self.reversal()).into()
6626 }
6627}
6628
6629impl GeometricQuotient<IdealPoint> for MotorDual {
6630 type Output = MotorDual;
6631
6632 fn geometric_quotient(self, other: IdealPoint) -> MotorDual {
6633 self.geometric_product(other.inverse())
6634 }
6635}
6636
6637impl Transformation<IdealPoint> for MotorDual {
6638 type Output = IdealPoint;
6639
6640 fn transformation(self, other: IdealPoint) -> IdealPoint {
6641 self.geometric_product(other).geometric_product(self.reversal()).into()
6642 }
6643}
6644
6645impl GeometricQuotient<Motor> for MotorDual {
6646 type Output = MotorDual;
6647
6648 fn geometric_quotient(self, other: Motor) -> MotorDual {
6649 self.geometric_product(other.inverse())
6650 }
6651}
6652
6653impl Transformation<Motor> for MotorDual {
6654 type Output = Motor;
6655
6656 fn transformation(self, other: Motor) -> Motor {
6657 self.geometric_product(other).geometric_product(self.reversal())
6658 }
6659}
6660
6661impl GeometricQuotient<MotorDual> for MotorDual {
6662 type Output = Motor;
6663
6664 fn geometric_quotient(self, other: MotorDual) -> Motor {
6665 self.geometric_product(other.inverse())
6666 }
6667}
6668
6669impl Transformation<MotorDual> for MotorDual {
6670 type Output = MotorDual;
6671
6672 fn transformation(self, other: MotorDual) -> MotorDual {
6673 self.geometric_product(other).geometric_product(self.reversal())
6674 }
6675}
6676
6677impl GeometricQuotient<MultiVector> for MotorDual {
6678 type Output = MultiVector;
6679
6680 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6681 self.geometric_product(other.inverse())
6682 }
6683}
6684
6685impl Transformation<MultiVector> for MotorDual {
6686 type Output = MultiVector;
6687
6688 fn transformation(self, other: MultiVector) -> MultiVector {
6689 self.geometric_product(other).geometric_product(self.reversal())
6690 }
6691}
6692
6693impl GeometricQuotient<Plane> for MotorDual {
6694 type Output = Motor;
6695
6696 fn geometric_quotient(self, other: Plane) -> Motor {
6697 self.geometric_product(other.inverse())
6698 }
6699}
6700
6701impl Transformation<Plane> for MotorDual {
6702 type Output = Plane;
6703
6704 fn transformation(self, other: Plane) -> Plane {
6705 self.geometric_product(other).geometric_product(self.reversal()).into()
6706 }
6707}
6708
6709impl GeometricQuotient<Point> for MotorDual {
6710 type Output = MotorDual;
6711
6712 fn geometric_quotient(self, other: Point) -> MotorDual {
6713 self.geometric_product(other.inverse())
6714 }
6715}
6716
6717impl Transformation<Point> for MotorDual {
6718 type Output = Point;
6719
6720 fn transformation(self, other: Point) -> Point {
6721 self.geometric_product(other).geometric_product(self.reversal()).into()
6722 }
6723}
6724
6725impl GeometricQuotient<Rotor> for MotorDual {
6726 type Output = MotorDual;
6727
6728 fn geometric_quotient(self, other: Rotor) -> MotorDual {
6729 self.geometric_product(other.inverse())
6730 }
6731}
6732
6733impl Transformation<Rotor> for MotorDual {
6734 type Output = Rotor;
6735
6736 fn transformation(self, other: Rotor) -> Rotor {
6737 self.geometric_product(other).geometric_product(self.reversal()).into()
6738 }
6739}
6740
6741impl GeometricQuotient<f32> for MotorDual {
6742 type Output = MotorDual;
6743
6744 fn geometric_quotient(self, other: f32) -> MotorDual {
6745 self.geometric_product(other.inverse())
6746 }
6747}
6748
6749impl Transformation<f32> for MotorDual {
6750 type Output = f32;
6751
6752 fn transformation(self, other: f32) -> f32 {
6753 self.geometric_product(other).geometric_product(self.reversal()).into()
6754 }
6755}
6756
6757impl GeometricQuotient<Translator> for MotorDual {
6758 type Output = MotorDual;
6759
6760 fn geometric_quotient(self, other: Translator) -> MotorDual {
6761 self.geometric_product(other.inverse())
6762 }
6763}
6764
6765impl Transformation<Translator> for MotorDual {
6766 type Output = Translator;
6767
6768 fn transformation(self, other: Translator) -> Translator {
6769 self.geometric_product(other).geometric_product(self.reversal()).into()
6770 }
6771}
6772
6773impl GeometricQuotient<IdealPoint> for MultiVector {
6774 type Output = MultiVector;
6775
6776 fn geometric_quotient(self, other: IdealPoint) -> MultiVector {
6777 self.geometric_product(other.inverse())
6778 }
6779}
6780
6781impl Transformation<IdealPoint> for MultiVector {
6782 type Output = IdealPoint;
6783
6784 fn transformation(self, other: IdealPoint) -> IdealPoint {
6785 self.geometric_product(other).geometric_product(self.reversal()).into()
6786 }
6787}
6788
6789impl GeometricQuotient<Motor> for MultiVector {
6790 type Output = MultiVector;
6791
6792 fn geometric_quotient(self, other: Motor) -> MultiVector {
6793 self.geometric_product(other.inverse())
6794 }
6795}
6796
6797impl Transformation<Motor> for MultiVector {
6798 type Output = Motor;
6799
6800 fn transformation(self, other: Motor) -> Motor {
6801 self.geometric_product(other).geometric_product(self.reversal()).into()
6802 }
6803}
6804
6805impl GeometricQuotient<MotorDual> for MultiVector {
6806 type Output = MultiVector;
6807
6808 fn geometric_quotient(self, other: MotorDual) -> MultiVector {
6809 self.geometric_product(other.inverse())
6810 }
6811}
6812
6813impl Transformation<MotorDual> for MultiVector {
6814 type Output = MotorDual;
6815
6816 fn transformation(self, other: MotorDual) -> MotorDual {
6817 self.geometric_product(other).geometric_product(self.reversal()).into()
6818 }
6819}
6820
6821impl Powi for MultiVector {
6822 type Output = MultiVector;
6823
6824 fn powi(self, exponent: isize) -> MultiVector {
6825 if exponent == 0 {
6826 return MultiVector::one();
6827 }
6828 let mut x: MultiVector = if exponent < 0 { self.inverse() } else { self };
6829 let mut y: MultiVector = MultiVector::one();
6830 let mut n: isize = exponent.abs();
6831 while 1 < n {
6832 if n & 1 == 1 {
6833 y = x.geometric_product(y);
6834 }
6835 x = x.geometric_product(x);
6836 n = n >> 1;
6837 }
6838 x.geometric_product(y)
6839 }
6840}
6841
6842impl GeometricQuotient<MultiVector> for MultiVector {
6843 type Output = MultiVector;
6844
6845 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6846 self.geometric_product(other.inverse())
6847 }
6848}
6849
6850impl Transformation<MultiVector> for MultiVector {
6851 type Output = MultiVector;
6852
6853 fn transformation(self, other: MultiVector) -> MultiVector {
6854 self.geometric_product(other).geometric_product(self.reversal())
6855 }
6856}
6857
6858impl GeometricQuotient<Plane> for MultiVector {
6859 type Output = MultiVector;
6860
6861 fn geometric_quotient(self, other: Plane) -> MultiVector {
6862 self.geometric_product(other.inverse())
6863 }
6864}
6865
6866impl Transformation<Plane> for MultiVector {
6867 type Output = Plane;
6868
6869 fn transformation(self, other: Plane) -> Plane {
6870 self.geometric_product(other).geometric_product(self.reversal()).into()
6871 }
6872}
6873
6874impl GeometricQuotient<Point> for MultiVector {
6875 type Output = MultiVector;
6876
6877 fn geometric_quotient(self, other: Point) -> MultiVector {
6878 self.geometric_product(other.inverse())
6879 }
6880}
6881
6882impl Transformation<Point> for MultiVector {
6883 type Output = Point;
6884
6885 fn transformation(self, other: Point) -> Point {
6886 self.geometric_product(other).geometric_product(self.reversal()).into()
6887 }
6888}
6889
6890impl GeometricQuotient<Rotor> for MultiVector {
6891 type Output = MultiVector;
6892
6893 fn geometric_quotient(self, other: Rotor) -> MultiVector {
6894 self.geometric_product(other.inverse())
6895 }
6896}
6897
6898impl Transformation<Rotor> for MultiVector {
6899 type Output = Rotor;
6900
6901 fn transformation(self, other: Rotor) -> Rotor {
6902 self.geometric_product(other).geometric_product(self.reversal()).into()
6903 }
6904}
6905
6906impl GeometricQuotient<f32> for MultiVector {
6907 type Output = MultiVector;
6908
6909 fn geometric_quotient(self, other: f32) -> MultiVector {
6910 self.geometric_product(other.inverse())
6911 }
6912}
6913
6914impl Transformation<f32> for MultiVector {
6915 type Output = f32;
6916
6917 fn transformation(self, other: f32) -> f32 {
6918 self.geometric_product(other).geometric_product(self.reversal()).into()
6919 }
6920}
6921
6922impl GeometricQuotient<Translator> for MultiVector {
6923 type Output = MultiVector;
6924
6925 fn geometric_quotient(self, other: Translator) -> MultiVector {
6926 self.geometric_product(other.inverse())
6927 }
6928}
6929
6930impl Transformation<Translator> for MultiVector {
6931 type Output = Translator;
6932
6933 fn transformation(self, other: Translator) -> Translator {
6934 self.geometric_product(other).geometric_product(self.reversal()).into()
6935 }
6936}
6937
6938impl GeometricQuotient<IdealPoint> for Plane {
6939 type Output = MotorDual;
6940
6941 fn geometric_quotient(self, other: IdealPoint) -> MotorDual {
6942 self.geometric_product(other.inverse())
6943 }
6944}
6945
6946impl Transformation<IdealPoint> for Plane {
6947 type Output = IdealPoint;
6948
6949 fn transformation(self, other: IdealPoint) -> IdealPoint {
6950 self.geometric_product(other).geometric_product(self.reversal()).into()
6951 }
6952}
6953
6954impl GeometricQuotient<Motor> for Plane {
6955 type Output = MotorDual;
6956
6957 fn geometric_quotient(self, other: Motor) -> MotorDual {
6958 self.geometric_product(other.inverse())
6959 }
6960}
6961
6962impl Transformation<Motor> for Plane {
6963 type Output = Motor;
6964
6965 fn transformation(self, other: Motor) -> Motor {
6966 self.geometric_product(other).geometric_product(self.reversal())
6967 }
6968}
6969
6970impl GeometricQuotient<MotorDual> for Plane {
6971 type Output = Motor;
6972
6973 fn geometric_quotient(self, other: MotorDual) -> Motor {
6974 self.geometric_product(other.inverse())
6975 }
6976}
6977
6978impl Transformation<MotorDual> for Plane {
6979 type Output = MotorDual;
6980
6981 fn transformation(self, other: MotorDual) -> MotorDual {
6982 self.geometric_product(other).geometric_product(self.reversal())
6983 }
6984}
6985
6986impl GeometricQuotient<MultiVector> for Plane {
6987 type Output = MultiVector;
6988
6989 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6990 self.geometric_product(other.inverse())
6991 }
6992}
6993
6994impl Transformation<MultiVector> for Plane {
6995 type Output = MultiVector;
6996
6997 fn transformation(self, other: MultiVector) -> MultiVector {
6998 self.geometric_product(other).geometric_product(self.reversal())
6999 }
7000}
7001
7002impl GeometricQuotient<Plane> for Plane {
7003 type Output = Motor;
7004
7005 fn geometric_quotient(self, other: Plane) -> Motor {
7006 self.geometric_product(other.inverse())
7007 }
7008}
7009
7010impl Transformation<Plane> for Plane {
7011 type Output = Plane;
7012
7013 fn transformation(self, other: Plane) -> Plane {
7014 self.geometric_product(other).geometric_product(self.reversal()).into()
7015 }
7016}
7017
7018impl GeometricQuotient<Point> for Plane {
7019 type Output = MotorDual;
7020
7021 fn geometric_quotient(self, other: Point) -> MotorDual {
7022 self.geometric_product(other.inverse())
7023 }
7024}
7025
7026impl Transformation<Point> for Plane {
7027 type Output = Point;
7028
7029 fn transformation(self, other: Point) -> Point {
7030 self.geometric_product(other).geometric_product(self.reversal()).into()
7031 }
7032}
7033
7034impl GeometricQuotient<Rotor> for Plane {
7035 type Output = MotorDual;
7036
7037 fn geometric_quotient(self, other: Rotor) -> MotorDual {
7038 self.geometric_product(other.inverse())
7039 }
7040}
7041
7042impl Transformation<Rotor> for Plane {
7043 type Output = Rotor;
7044
7045 fn transformation(self, other: Rotor) -> Rotor {
7046 self.geometric_product(other).geometric_product(self.reversal()).into()
7047 }
7048}
7049
7050impl GeometricQuotient<f32> for Plane {
7051 type Output = Plane;
7052
7053 fn geometric_quotient(self, other: f32) -> Plane {
7054 self.geometric_product(other.inverse())
7055 }
7056}
7057
7058impl Transformation<f32> for Plane {
7059 type Output = f32;
7060
7061 fn transformation(self, other: f32) -> f32 {
7062 self.geometric_product(other).geometric_product(self.reversal()).into()
7063 }
7064}
7065
7066impl GeometricQuotient<Translator> for Plane {
7067 type Output = MotorDual;
7068
7069 fn geometric_quotient(self, other: Translator) -> MotorDual {
7070 self.geometric_product(other.inverse())
7071 }
7072}
7073
7074impl Transformation<Translator> for Plane {
7075 type Output = Translator;
7076
7077 fn transformation(self, other: Translator) -> Translator {
7078 self.geometric_product(other).geometric_product(self.reversal()).into()
7079 }
7080}
7081
7082impl GeometricQuotient<IdealPoint> for Point {
7083 type Output = Motor;
7084
7085 fn geometric_quotient(self, other: IdealPoint) -> Motor {
7086 self.geometric_product(other.inverse())
7087 }
7088}
7089
7090impl Transformation<IdealPoint> for Point {
7091 type Output = IdealPoint;
7092
7093 fn transformation(self, other: IdealPoint) -> IdealPoint {
7094 self.geometric_product(other).geometric_product(self.reversal()).into()
7095 }
7096}
7097
7098impl GeometricQuotient<Motor> for Point {
7099 type Output = Motor;
7100
7101 fn geometric_quotient(self, other: Motor) -> Motor {
7102 self.geometric_product(other.inverse())
7103 }
7104}
7105
7106impl Transformation<Motor> for Point {
7107 type Output = Motor;
7108
7109 fn transformation(self, other: Motor) -> Motor {
7110 self.geometric_product(other).geometric_product(self.reversal())
7111 }
7112}
7113
7114impl GeometricQuotient<MotorDual> for Point {
7115 type Output = MotorDual;
7116
7117 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
7118 self.geometric_product(other.inverse())
7119 }
7120}
7121
7122impl Transformation<MotorDual> for Point {
7123 type Output = MotorDual;
7124
7125 fn transformation(self, other: MotorDual) -> MotorDual {
7126 self.geometric_product(other).geometric_product(self.reversal())
7127 }
7128}
7129
7130impl GeometricQuotient<MultiVector> for Point {
7131 type Output = MultiVector;
7132
7133 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7134 self.geometric_product(other.inverse())
7135 }
7136}
7137
7138impl Transformation<MultiVector> for Point {
7139 type Output = MultiVector;
7140
7141 fn transformation(self, other: MultiVector) -> MultiVector {
7142 self.geometric_product(other).geometric_product(self.reversal())
7143 }
7144}
7145
7146impl GeometricQuotient<Plane> for Point {
7147 type Output = MotorDual;
7148
7149 fn geometric_quotient(self, other: Plane) -> MotorDual {
7150 self.geometric_product(other.inverse())
7151 }
7152}
7153
7154impl Transformation<Plane> for Point {
7155 type Output = Plane;
7156
7157 fn transformation(self, other: Plane) -> Plane {
7158 self.geometric_product(other).geometric_product(self.reversal()).into()
7159 }
7160}
7161
7162impl GeometricQuotient<Point> for Point {
7163 type Output = Motor;
7164
7165 fn geometric_quotient(self, other: Point) -> Motor {
7166 self.geometric_product(other.inverse())
7167 }
7168}
7169
7170impl Transformation<Point> for Point {
7171 type Output = Point;
7172
7173 fn transformation(self, other: Point) -> Point {
7174 self.geometric_product(other).geometric_product(self.reversal()).into()
7175 }
7176}
7177
7178impl GeometricQuotient<Rotor> for Point {
7179 type Output = Motor;
7180
7181 fn geometric_quotient(self, other: Rotor) -> Motor {
7182 self.geometric_product(other.inverse())
7183 }
7184}
7185
7186impl Transformation<Rotor> for Point {
7187 type Output = Rotor;
7188
7189 fn transformation(self, other: Rotor) -> Rotor {
7190 self.geometric_product(other).geometric_product(self.reversal()).into()
7191 }
7192}
7193
7194impl GeometricQuotient<f32> for Point {
7195 type Output = Point;
7196
7197 fn geometric_quotient(self, other: f32) -> Point {
7198 self.geometric_product(other.inverse())
7199 }
7200}
7201
7202impl Transformation<f32> for Point {
7203 type Output = f32;
7204
7205 fn transformation(self, other: f32) -> f32 {
7206 self.geometric_product(other).geometric_product(self.reversal()).into()
7207 }
7208}
7209
7210impl GeometricQuotient<Translator> for Point {
7211 type Output = Motor;
7212
7213 fn geometric_quotient(self, other: Translator) -> Motor {
7214 self.geometric_product(other.inverse())
7215 }
7216}
7217
7218impl Transformation<Translator> for Point {
7219 type Output = Translator;
7220
7221 fn transformation(self, other: Translator) -> Translator {
7222 self.geometric_product(other).geometric_product(self.reversal()).into()
7223 }
7224}
7225
7226impl GeometricQuotient<IdealPoint> for Rotor {
7227 type Output = IdealPoint;
7228
7229 fn geometric_quotient(self, other: IdealPoint) -> IdealPoint {
7230 self.geometric_product(other.inverse())
7231 }
7232}
7233
7234impl Transformation<IdealPoint> for Rotor {
7235 type Output = IdealPoint;
7236
7237 fn transformation(self, other: IdealPoint) -> IdealPoint {
7238 self.geometric_product(other).geometric_product(self.reversal())
7239 }
7240}
7241
7242impl GeometricQuotient<Motor> for Rotor {
7243 type Output = Motor;
7244
7245 fn geometric_quotient(self, other: Motor) -> Motor {
7246 self.geometric_product(other.inverse())
7247 }
7248}
7249
7250impl Transformation<Motor> for Rotor {
7251 type Output = Motor;
7252
7253 fn transformation(self, other: Motor) -> Motor {
7254 self.geometric_product(other).geometric_product(self.reversal())
7255 }
7256}
7257
7258impl GeometricQuotient<MotorDual> for Rotor {
7259 type Output = MotorDual;
7260
7261 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
7262 self.geometric_product(other.inverse())
7263 }
7264}
7265
7266impl Transformation<MotorDual> for Rotor {
7267 type Output = MotorDual;
7268
7269 fn transformation(self, other: MotorDual) -> MotorDual {
7270 self.geometric_product(other).geometric_product(self.reversal())
7271 }
7272}
7273
7274impl GeometricQuotient<MultiVector> for Rotor {
7275 type Output = MultiVector;
7276
7277 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7278 self.geometric_product(other.inverse())
7279 }
7280}
7281
7282impl Transformation<MultiVector> for Rotor {
7283 type Output = MultiVector;
7284
7285 fn transformation(self, other: MultiVector) -> MultiVector {
7286 self.geometric_product(other).geometric_product(self.reversal())
7287 }
7288}
7289
7290impl GeometricQuotient<Plane> for Rotor {
7291 type Output = MotorDual;
7292
7293 fn geometric_quotient(self, other: Plane) -> MotorDual {
7294 self.geometric_product(other.inverse())
7295 }
7296}
7297
7298impl Transformation<Plane> for Rotor {
7299 type Output = Plane;
7300
7301 fn transformation(self, other: Plane) -> Plane {
7302 self.geometric_product(other).geometric_product(self.reversal()).into()
7303 }
7304}
7305
7306impl GeometricQuotient<Point> for Rotor {
7307 type Output = Motor;
7308
7309 fn geometric_quotient(self, other: Point) -> Motor {
7310 self.geometric_product(other.inverse())
7311 }
7312}
7313
7314impl Transformation<Point> for Rotor {
7315 type Output = Point;
7316
7317 fn transformation(self, other: Point) -> Point {
7318 self.geometric_product(other).geometric_product(self.reversal()).into()
7319 }
7320}
7321
7322impl Powi for Rotor {
7323 type Output = Rotor;
7324
7325 fn powi(self, exponent: isize) -> Rotor {
7326 if exponent == 0 {
7327 return Rotor::one();
7328 }
7329 let mut x: Rotor = if exponent < 0 { self.inverse() } else { self };
7330 let mut y: Rotor = Rotor::one();
7331 let mut n: isize = exponent.abs();
7332 while 1 < n {
7333 if n & 1 == 1 {
7334 y = x.geometric_product(y);
7335 }
7336 x = x.geometric_product(x);
7337 n = n >> 1;
7338 }
7339 x.geometric_product(y)
7340 }
7341}
7342
7343impl GeometricQuotient<Rotor> for Rotor {
7344 type Output = Rotor;
7345
7346 fn geometric_quotient(self, other: Rotor) -> Rotor {
7347 self.geometric_product(other.inverse())
7348 }
7349}
7350
7351impl Transformation<Rotor> for Rotor {
7352 type Output = Rotor;
7353
7354 fn transformation(self, other: Rotor) -> Rotor {
7355 self.geometric_product(other).geometric_product(self.reversal())
7356 }
7357}
7358
7359impl GeometricQuotient<f32> for Rotor {
7360 type Output = Rotor;
7361
7362 fn geometric_quotient(self, other: f32) -> Rotor {
7363 self.geometric_product(other.inverse())
7364 }
7365}
7366
7367impl Transformation<f32> for Rotor {
7368 type Output = f32;
7369
7370 fn transformation(self, other: f32) -> f32 {
7371 self.geometric_product(other).geometric_product(self.reversal()).into()
7372 }
7373}
7374
7375impl GeometricQuotient<Translator> for Rotor {
7376 type Output = Motor;
7377
7378 fn geometric_quotient(self, other: Translator) -> Motor {
7379 self.geometric_product(other.inverse())
7380 }
7381}
7382
7383impl Transformation<Translator> for Rotor {
7384 type Output = Translator;
7385
7386 fn transformation(self, other: Translator) -> Translator {
7387 self.geometric_product(other).geometric_product(self.reversal()).into()
7388 }
7389}
7390
7391impl GeometricQuotient<IdealPoint> for f32 {
7392 type Output = IdealPoint;
7393
7394 fn geometric_quotient(self, other: IdealPoint) -> IdealPoint {
7395 self.geometric_product(other.inverse())
7396 }
7397}
7398
7399impl Transformation<IdealPoint> for f32 {
7400 type Output = IdealPoint;
7401
7402 fn transformation(self, other: IdealPoint) -> IdealPoint {
7403 self.geometric_product(other).geometric_product(self.reversal())
7404 }
7405}
7406
7407impl GeometricQuotient<Motor> for f32 {
7408 type Output = Motor;
7409
7410 fn geometric_quotient(self, other: Motor) -> Motor {
7411 self.geometric_product(other.inverse())
7412 }
7413}
7414
7415impl Transformation<Motor> for f32 {
7416 type Output = Motor;
7417
7418 fn transformation(self, other: Motor) -> Motor {
7419 self.geometric_product(other).geometric_product(self.reversal())
7420 }
7421}
7422
7423impl GeometricQuotient<MotorDual> for f32 {
7424 type Output = MotorDual;
7425
7426 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
7427 self.geometric_product(other.inverse())
7428 }
7429}
7430
7431impl Transformation<MotorDual> for f32 {
7432 type Output = MotorDual;
7433
7434 fn transformation(self, other: MotorDual) -> MotorDual {
7435 self.geometric_product(other).geometric_product(self.reversal())
7436 }
7437}
7438
7439impl GeometricQuotient<MultiVector> for f32 {
7440 type Output = MultiVector;
7441
7442 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7443 self.geometric_product(other.inverse())
7444 }
7445}
7446
7447impl Transformation<MultiVector> for f32 {
7448 type Output = MultiVector;
7449
7450 fn transformation(self, other: MultiVector) -> MultiVector {
7451 self.geometric_product(other).geometric_product(self.reversal())
7452 }
7453}
7454
7455impl GeometricQuotient<Plane> for f32 {
7456 type Output = Plane;
7457
7458 fn geometric_quotient(self, other: Plane) -> Plane {
7459 self.geometric_product(other.inverse())
7460 }
7461}
7462
7463impl Transformation<Plane> for f32 {
7464 type Output = Plane;
7465
7466 fn transformation(self, other: Plane) -> Plane {
7467 self.geometric_product(other).geometric_product(self.reversal())
7468 }
7469}
7470
7471impl GeometricQuotient<Point> for f32 {
7472 type Output = Point;
7473
7474 fn geometric_quotient(self, other: Point) -> Point {
7475 self.geometric_product(other.inverse())
7476 }
7477}
7478
7479impl Transformation<Point> for f32 {
7480 type Output = Point;
7481
7482 fn transformation(self, other: Point) -> Point {
7483 self.geometric_product(other).geometric_product(self.reversal())
7484 }
7485}
7486
7487impl GeometricQuotient<Rotor> for f32 {
7488 type Output = Rotor;
7489
7490 fn geometric_quotient(self, other: Rotor) -> Rotor {
7491 self.geometric_product(other.inverse())
7492 }
7493}
7494
7495impl Transformation<Rotor> for f32 {
7496 type Output = Rotor;
7497
7498 fn transformation(self, other: Rotor) -> Rotor {
7499 self.geometric_product(other).geometric_product(self.reversal())
7500 }
7501}
7502
7503impl GeometricQuotient<Translator> for f32 {
7504 type Output = Translator;
7505
7506 fn geometric_quotient(self, other: Translator) -> Translator {
7507 self.geometric_product(other.inverse())
7508 }
7509}
7510
7511impl Transformation<Translator> for f32 {
7512 type Output = Translator;
7513
7514 fn transformation(self, other: Translator) -> Translator {
7515 self.geometric_product(other).geometric_product(self.reversal())
7516 }
7517}
7518
7519impl GeometricQuotient<IdealPoint> for Translator {
7520 type Output = Motor;
7521
7522 fn geometric_quotient(self, other: IdealPoint) -> Motor {
7523 self.geometric_product(other.inverse())
7524 }
7525}
7526
7527impl Transformation<IdealPoint> for Translator {
7528 type Output = IdealPoint;
7529
7530 fn transformation(self, other: IdealPoint) -> IdealPoint {
7531 self.geometric_product(other).geometric_product(self.reversal()).into()
7532 }
7533}
7534
7535impl GeometricQuotient<Motor> for Translator {
7536 type Output = Motor;
7537
7538 fn geometric_quotient(self, other: Motor) -> Motor {
7539 self.geometric_product(other.inverse())
7540 }
7541}
7542
7543impl Transformation<Motor> for Translator {
7544 type Output = Motor;
7545
7546 fn transformation(self, other: Motor) -> Motor {
7547 self.geometric_product(other).geometric_product(self.reversal())
7548 }
7549}
7550
7551impl GeometricQuotient<MotorDual> for Translator {
7552 type Output = MotorDual;
7553
7554 fn geometric_quotient(self, other: MotorDual) -> MotorDual {
7555 self.geometric_product(other.inverse())
7556 }
7557}
7558
7559impl Transformation<MotorDual> for Translator {
7560 type Output = MotorDual;
7561
7562 fn transformation(self, other: MotorDual) -> MotorDual {
7563 self.geometric_product(other).geometric_product(self.reversal())
7564 }
7565}
7566
7567impl GeometricQuotient<MultiVector> for Translator {
7568 type Output = MultiVector;
7569
7570 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7571 self.geometric_product(other.inverse())
7572 }
7573}
7574
7575impl Transformation<MultiVector> for Translator {
7576 type Output = MultiVector;
7577
7578 fn transformation(self, other: MultiVector) -> MultiVector {
7579 self.geometric_product(other).geometric_product(self.reversal())
7580 }
7581}
7582
7583impl GeometricQuotient<Plane> for Translator {
7584 type Output = MotorDual;
7585
7586 fn geometric_quotient(self, other: Plane) -> MotorDual {
7587 self.geometric_product(other.inverse())
7588 }
7589}
7590
7591impl Transformation<Plane> for Translator {
7592 type Output = Plane;
7593
7594 fn transformation(self, other: Plane) -> Plane {
7595 self.geometric_product(other).geometric_product(self.reversal()).into()
7596 }
7597}
7598
7599impl GeometricQuotient<Point> for Translator {
7600 type Output = Motor;
7601
7602 fn geometric_quotient(self, other: Point) -> Motor {
7603 self.geometric_product(other.inverse())
7604 }
7605}
7606
7607impl Transformation<Point> for Translator {
7608 type Output = Point;
7609
7610 fn transformation(self, other: Point) -> Point {
7611 self.geometric_product(other).geometric_product(self.reversal()).into()
7612 }
7613}
7614
7615impl GeometricQuotient<Rotor> for Translator {
7616 type Output = Motor;
7617
7618 fn geometric_quotient(self, other: Rotor) -> Motor {
7619 self.geometric_product(other.inverse())
7620 }
7621}
7622
7623impl Transformation<Rotor> for Translator {
7624 type Output = Rotor;
7625
7626 fn transformation(self, other: Rotor) -> Rotor {
7627 self.geometric_product(other).geometric_product(self.reversal()).into()
7628 }
7629}
7630
7631impl GeometricQuotient<f32> for Translator {
7632 type Output = Translator;
7633
7634 fn geometric_quotient(self, other: f32) -> Translator {
7635 self.geometric_product(other.inverse())
7636 }
7637}
7638
7639impl Transformation<f32> for Translator {
7640 type Output = f32;
7641
7642 fn transformation(self, other: f32) -> f32 {
7643 self.geometric_product(other).geometric_product(self.reversal()).into()
7644 }
7645}
7646
7647impl GeometricQuotient<Translator> for Translator {
7648 type Output = Motor;
7649
7650 fn geometric_quotient(self, other: Translator) -> Motor {
7651 self.geometric_product(other.inverse())
7652 }
7653}
7654
7655impl Transformation<Translator> for Translator {
7656 type Output = Translator;
7657
7658 fn transformation(self, other: Translator) -> Translator {
7659 self.geometric_product(other).geometric_product(self.reversal()).into()
7660 }
7661}
7662