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 g2: Simd32x4,
13 g3: Simd32x4,
15}
16
17#[derive(Clone, Copy)]
18pub union MultiVector {
19 groups: MultiVectorGroups,
20 elements: [f32; 16],
22}
23
24impl MultiVector {
25 #[allow(clippy::too_many_arguments)]
26 pub const fn new(scalar: f32, e23: f32, _e13: f32, e12: f32, e0: f32, _e023: f32, e013: f32, _e012: f32, e123: f32, e1: f32, e2: f32, e3: f32, e0123: f32, e01: f32, e02: f32, e03: f32) -> Self {
27 Self { elements: [scalar, e23, _e13, e12, e0, _e023, e013, _e012, e123, e1, e2, e3, e0123, e01, e02, e03] }
28 }
29 pub const fn from_groups(g0: Simd32x4, g1: Simd32x4, g2: Simd32x4, g3: Simd32x4) -> Self {
30 Self { groups: MultiVectorGroups { g0, g1, g2, g3 } }
31 }
32 #[inline(always)]
33 pub fn group0(&self) -> Simd32x4 {
34 unsafe { self.groups.g0 }
35 }
36 #[inline(always)]
37 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
38 unsafe { &mut self.groups.g0 }
39 }
40 #[inline(always)]
41 pub fn group1(&self) -> Simd32x4 {
42 unsafe { self.groups.g1 }
43 }
44 #[inline(always)]
45 pub fn group1_mut(&mut self) -> &mut Simd32x4 {
46 unsafe { &mut self.groups.g1 }
47 }
48 #[inline(always)]
49 pub fn group2(&self) -> Simd32x4 {
50 unsafe { self.groups.g2 }
51 }
52 #[inline(always)]
53 pub fn group2_mut(&mut self) -> &mut Simd32x4 {
54 unsafe { &mut self.groups.g2 }
55 }
56 #[inline(always)]
57 pub fn group3(&self) -> Simd32x4 {
58 unsafe { self.groups.g3 }
59 }
60 #[inline(always)]
61 pub fn group3_mut(&mut self) -> &mut Simd32x4 {
62 unsafe { &mut self.groups.g3 }
63 }
64}
65
66const MULTIVECTOR_INDEX_REMAP: [usize; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
67
68impl std::ops::Index<usize> for MultiVector {
69 type Output = f32;
70
71 fn index(&self, index: usize) -> &Self::Output {
72 unsafe { &self.elements[MULTIVECTOR_INDEX_REMAP[index]] }
73 }
74}
75
76impl std::ops::IndexMut<usize> for MultiVector {
77 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
78 unsafe { &mut self.elements[MULTIVECTOR_INDEX_REMAP[index]] }
79 }
80}
81
82impl std::convert::From<MultiVector> for [f32; 16] {
83 fn from(vector: MultiVector) -> Self {
84 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], vector.elements[8], vector.elements[9], vector.elements[10], vector.elements[11], vector.elements[12], vector.elements[13], vector.elements[14], vector.elements[15]] }
85 }
86}
87
88impl std::convert::From<[f32; 16]> for MultiVector {
89 fn from(array: [f32; 16]) -> Self {
90 Self { elements: [array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8], array[9], array[10], array[11], array[12], array[13], array[14], array[15]] }
91 }
92}
93
94impl std::fmt::Debug for MultiVector {
95 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
96 formatter
97 .debug_struct("MultiVector")
98 .field("1", &self[0])
99 .field("e23", &self[1])
100 .field("-e13", &self[2])
101 .field("e12", &self[3])
102 .field("e0", &self[4])
103 .field("-e023", &self[5])
104 .field("e013", &self[6])
105 .field("-e012", &self[7])
106 .field("e123", &self[8])
107 .field("e1", &self[9])
108 .field("e2", &self[10])
109 .field("e3", &self[11])
110 .field("e0123", &self[12])
111 .field("e01", &self[13])
112 .field("e02", &self[14])
113 .field("e03", &self[15])
114 .finish()
115 }
116}
117
118#[derive(Clone, Copy)]
119struct RotorGroups {
120 g0: Simd32x4,
122}
123
124#[derive(Clone, Copy)]
125pub union Rotor {
126 groups: RotorGroups,
127 elements: [f32; 4],
129}
130
131impl Rotor {
132 #[allow(clippy::too_many_arguments)]
133 pub const fn new(scalar: f32, e23: f32, _e13: f32, e12: f32) -> Self {
134 Self { elements: [scalar, e23, _e13, e12] }
135 }
136 pub const fn from_groups(g0: Simd32x4) -> Self {
137 Self { groups: RotorGroups { g0 } }
138 }
139 #[inline(always)]
140 pub fn group0(&self) -> Simd32x4 {
141 unsafe { self.groups.g0 }
142 }
143 #[inline(always)]
144 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
145 unsafe { &mut self.groups.g0 }
146 }
147}
148
149const ROTOR_INDEX_REMAP: [usize; 4] = [0, 1, 2, 3];
150
151impl std::ops::Index<usize> for Rotor {
152 type Output = f32;
153
154 fn index(&self, index: usize) -> &Self::Output {
155 unsafe { &self.elements[ROTOR_INDEX_REMAP[index]] }
156 }
157}
158
159impl std::ops::IndexMut<usize> for Rotor {
160 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
161 unsafe { &mut self.elements[ROTOR_INDEX_REMAP[index]] }
162 }
163}
164
165impl std::convert::From<Rotor> for [f32; 4] {
166 fn from(vector: Rotor) -> Self {
167 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3]] }
168 }
169}
170
171impl std::convert::From<[f32; 4]> for Rotor {
172 fn from(array: [f32; 4]) -> Self {
173 Self { elements: [array[0], array[1], array[2], array[3]] }
174 }
175}
176
177impl std::fmt::Debug for Rotor {
178 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
179 formatter
180 .debug_struct("Rotor")
181 .field("1", &self[0])
182 .field("e23", &self[1])
183 .field("-e13", &self[2])
184 .field("e12", &self[3])
185 .finish()
186 }
187}
188
189#[derive(Clone, Copy)]
190struct PointGroups {
191 g0: Simd32x4,
193}
194
195#[derive(Clone, Copy)]
196pub union Point {
197 groups: PointGroups,
198 elements: [f32; 4],
200}
201
202impl Point {
203 #[allow(clippy::too_many_arguments)]
204 pub const fn new(e123: f32, _e023: f32, e013: f32, _e012: f32) -> Self {
205 Self { elements: [e123, _e023, e013, _e012] }
206 }
207 pub const fn from_groups(g0: Simd32x4) -> Self {
208 Self { groups: PointGroups { g0 } }
209 }
210 #[inline(always)]
211 pub fn group0(&self) -> Simd32x4 {
212 unsafe { self.groups.g0 }
213 }
214 #[inline(always)]
215 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
216 unsafe { &mut self.groups.g0 }
217 }
218}
219
220const POINT_INDEX_REMAP: [usize; 4] = [0, 1, 2, 3];
221
222impl std::ops::Index<usize> for Point {
223 type Output = f32;
224
225 fn index(&self, index: usize) -> &Self::Output {
226 unsafe { &self.elements[POINT_INDEX_REMAP[index]] }
227 }
228}
229
230impl std::ops::IndexMut<usize> for Point {
231 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
232 unsafe { &mut self.elements[POINT_INDEX_REMAP[index]] }
233 }
234}
235
236impl std::convert::From<Point> for [f32; 4] {
237 fn from(vector: Point) -> Self {
238 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3]] }
239 }
240}
241
242impl std::convert::From<[f32; 4]> for Point {
243 fn from(array: [f32; 4]) -> Self {
244 Self { elements: [array[0], array[1], array[2], array[3]] }
245 }
246}
247
248impl std::fmt::Debug for Point {
249 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
250 formatter
251 .debug_struct("Point")
252 .field("e123", &self[0])
253 .field("-e023", &self[1])
254 .field("e013", &self[2])
255 .field("-e012", &self[3])
256 .finish()
257 }
258}
259
260#[derive(Clone, Copy)]
261struct IdealPointGroups {
262 g0: Simd32x3,
264}
265
266#[derive(Clone, Copy)]
267pub union IdealPoint {
268 groups: IdealPointGroups,
269 elements: [f32; 4],
271}
272
273impl IdealPoint {
274 #[allow(clippy::too_many_arguments)]
275 pub const fn new(e01: f32, e02: f32, e03: f32) -> Self {
276 Self { elements: [e01, e02, e03, 0.0] }
277 }
278 pub const fn from_groups(g0: Simd32x3) -> Self {
279 Self { groups: IdealPointGroups { g0 } }
280 }
281 #[inline(always)]
282 pub fn group0(&self) -> Simd32x3 {
283 unsafe { self.groups.g0 }
284 }
285 #[inline(always)]
286 pub fn group0_mut(&mut self) -> &mut Simd32x3 {
287 unsafe { &mut self.groups.g0 }
288 }
289}
290
291const IDEALPOINT_INDEX_REMAP: [usize; 3] = [0, 1, 2];
292
293impl std::ops::Index<usize> for IdealPoint {
294 type Output = f32;
295
296 fn index(&self, index: usize) -> &Self::Output {
297 unsafe { &self.elements[IDEALPOINT_INDEX_REMAP[index]] }
298 }
299}
300
301impl std::ops::IndexMut<usize> for IdealPoint {
302 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
303 unsafe { &mut self.elements[IDEALPOINT_INDEX_REMAP[index]] }
304 }
305}
306
307impl std::convert::From<IdealPoint> for [f32; 3] {
308 fn from(vector: IdealPoint) -> Self {
309 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2]] }
310 }
311}
312
313impl std::convert::From<[f32; 3]> for IdealPoint {
314 fn from(array: [f32; 3]) -> Self {
315 Self { elements: [array[0], array[1], array[2], 0.0] }
316 }
317}
318
319impl std::fmt::Debug for IdealPoint {
320 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
321 formatter
322 .debug_struct("IdealPoint")
323 .field("e01", &self[0])
324 .field("e02", &self[1])
325 .field("e03", &self[2])
326 .finish()
327 }
328}
329
330#[derive(Clone, Copy)]
331struct PlaneGroups {
332 g0: Simd32x4,
334}
335
336#[derive(Clone, Copy)]
337pub union Plane {
338 groups: PlaneGroups,
339 elements: [f32; 4],
341}
342
343impl Plane {
344 #[allow(clippy::too_many_arguments)]
345 pub const fn new(e0: f32, e1: f32, e2: f32, e3: f32) -> Self {
346 Self { elements: [e0, e1, e2, e3] }
347 }
348 pub const fn from_groups(g0: Simd32x4) -> Self {
349 Self { groups: PlaneGroups { g0 } }
350 }
351 #[inline(always)]
352 pub fn group0(&self) -> Simd32x4 {
353 unsafe { self.groups.g0 }
354 }
355 #[inline(always)]
356 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
357 unsafe { &mut self.groups.g0 }
358 }
359}
360
361const PLANE_INDEX_REMAP: [usize; 4] = [0, 1, 2, 3];
362
363impl std::ops::Index<usize> for Plane {
364 type Output = f32;
365
366 fn index(&self, index: usize) -> &Self::Output {
367 unsafe { &self.elements[PLANE_INDEX_REMAP[index]] }
368 }
369}
370
371impl std::ops::IndexMut<usize> for Plane {
372 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
373 unsafe { &mut self.elements[PLANE_INDEX_REMAP[index]] }
374 }
375}
376
377impl std::convert::From<Plane> for [f32; 4] {
378 fn from(vector: Plane) -> Self {
379 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3]] }
380 }
381}
382
383impl std::convert::From<[f32; 4]> for Plane {
384 fn from(array: [f32; 4]) -> Self {
385 Self { elements: [array[0], array[1], array[2], array[3]] }
386 }
387}
388
389impl std::fmt::Debug for Plane {
390 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
391 formatter
392 .debug_struct("Plane")
393 .field("e0", &self[0])
394 .field("e1", &self[1])
395 .field("e2", &self[2])
396 .field("e3", &self[3])
397 .finish()
398 }
399}
400
401#[derive(Clone, Copy)]
402struct LineGroups {
403 g0: Simd32x3,
405 g1: Simd32x3,
407}
408
409#[derive(Clone, Copy)]
410pub union Line {
411 groups: LineGroups,
412 elements: [f32; 8],
414}
415
416impl Line {
417 #[allow(clippy::too_many_arguments)]
418 pub const fn new(e01: f32, e02: f32, e03: f32, e23: f32, _e13: f32, e12: f32) -> Self {
419 Self { elements: [e01, e02, e03, 0.0, e23, _e13, e12, 0.0] }
420 }
421 pub const fn from_groups(g0: Simd32x3, g1: Simd32x3) -> Self {
422 Self { groups: LineGroups { g0, g1 } }
423 }
424 #[inline(always)]
425 pub fn group0(&self) -> Simd32x3 {
426 unsafe { self.groups.g0 }
427 }
428 #[inline(always)]
429 pub fn group0_mut(&mut self) -> &mut Simd32x3 {
430 unsafe { &mut self.groups.g0 }
431 }
432 #[inline(always)]
433 pub fn group1(&self) -> Simd32x3 {
434 unsafe { self.groups.g1 }
435 }
436 #[inline(always)]
437 pub fn group1_mut(&mut self) -> &mut Simd32x3 {
438 unsafe { &mut self.groups.g1 }
439 }
440}
441
442const LINE_INDEX_REMAP: [usize; 6] = [0, 1, 2, 4, 5, 6];
443
444impl std::ops::Index<usize> for Line {
445 type Output = f32;
446
447 fn index(&self, index: usize) -> &Self::Output {
448 unsafe { &self.elements[LINE_INDEX_REMAP[index]] }
449 }
450}
451
452impl std::ops::IndexMut<usize> for Line {
453 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
454 unsafe { &mut self.elements[LINE_INDEX_REMAP[index]] }
455 }
456}
457
458impl std::convert::From<Line> for [f32; 6] {
459 fn from(vector: Line) -> Self {
460 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[4], vector.elements[5], vector.elements[6]] }
461 }
462}
463
464impl std::convert::From<[f32; 6]> for Line {
465 fn from(array: [f32; 6]) -> Self {
466 Self { elements: [array[0], array[1], array[2], 0.0, array[3], array[4], array[5], 0.0] }
467 }
468}
469
470impl std::fmt::Debug for Line {
471 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
472 formatter
473 .debug_struct("Line")
474 .field("e01", &self[0])
475 .field("e02", &self[1])
476 .field("e03", &self[2])
477 .field("e23", &self[3])
478 .field("-e13", &self[4])
479 .field("e12", &self[5])
480 .finish()
481 }
482}
483
484#[derive(Clone, Copy)]
485struct TranslatorGroups {
486 g0: Simd32x4,
488}
489
490#[derive(Clone, Copy)]
491pub union Translator {
492 groups: TranslatorGroups,
493 elements: [f32; 4],
495}
496
497impl Translator {
498 #[allow(clippy::too_many_arguments)]
499 pub const fn new(scalar: f32, e01: f32, e02: f32, e03: f32) -> Self {
500 Self { elements: [scalar, e01, e02, e03] }
501 }
502 pub const fn from_groups(g0: Simd32x4) -> Self {
503 Self { groups: TranslatorGroups { g0 } }
504 }
505 #[inline(always)]
506 pub fn group0(&self) -> Simd32x4 {
507 unsafe { self.groups.g0 }
508 }
509 #[inline(always)]
510 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
511 unsafe { &mut self.groups.g0 }
512 }
513}
514
515const TRANSLATOR_INDEX_REMAP: [usize; 4] = [0, 1, 2, 3];
516
517impl std::ops::Index<usize> for Translator {
518 type Output = f32;
519
520 fn index(&self, index: usize) -> &Self::Output {
521 unsafe { &self.elements[TRANSLATOR_INDEX_REMAP[index]] }
522 }
523}
524
525impl std::ops::IndexMut<usize> for Translator {
526 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
527 unsafe { &mut self.elements[TRANSLATOR_INDEX_REMAP[index]] }
528 }
529}
530
531impl std::convert::From<Translator> for [f32; 4] {
532 fn from(vector: Translator) -> Self {
533 unsafe { [vector.elements[0], vector.elements[1], vector.elements[2], vector.elements[3]] }
534 }
535}
536
537impl std::convert::From<[f32; 4]> for Translator {
538 fn from(array: [f32; 4]) -> Self {
539 Self { elements: [array[0], array[1], array[2], array[3]] }
540 }
541}
542
543impl std::fmt::Debug for Translator {
544 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
545 formatter
546 .debug_struct("Translator")
547 .field("1", &self[0])
548 .field("e01", &self[1])
549 .field("e02", &self[2])
550 .field("e03", &self[3])
551 .finish()
552 }
553}
554
555#[derive(Clone, Copy)]
556struct MotorGroups {
557 g0: Simd32x4,
559 g1: Simd32x4,
561}
562
563#[derive(Clone, Copy)]
564pub union Motor {
565 groups: MotorGroups,
566 elements: [f32; 8],
568}
569
570impl Motor {
571 #[allow(clippy::too_many_arguments)]
572 pub const fn new(scalar: f32, e23: f32, _e13: f32, e12: f32, e0123: f32, e01: f32, e02: f32, e03: f32) -> Self {
573 Self { elements: [scalar, e23, _e13, e12, e0123, e01, e02, e03] }
574 }
575 pub const fn from_groups(g0: Simd32x4, g1: Simd32x4) -> Self {
576 Self { groups: MotorGroups { g0, g1 } }
577 }
578 #[inline(always)]
579 pub fn group0(&self) -> Simd32x4 {
580 unsafe { self.groups.g0 }
581 }
582 #[inline(always)]
583 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
584 unsafe { &mut self.groups.g0 }
585 }
586 #[inline(always)]
587 pub fn group1(&self) -> Simd32x4 {
588 unsafe { self.groups.g1 }
589 }
590 #[inline(always)]
591 pub fn group1_mut(&mut self) -> &mut Simd32x4 {
592 unsafe { &mut self.groups.g1 }
593 }
594}
595
596const MOTOR_INDEX_REMAP: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
597
598impl std::ops::Index<usize> for Motor {
599 type Output = f32;
600
601 fn index(&self, index: usize) -> &Self::Output {
602 unsafe { &self.elements[MOTOR_INDEX_REMAP[index]] }
603 }
604}
605
606impl std::ops::IndexMut<usize> for Motor {
607 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
608 unsafe { &mut self.elements[MOTOR_INDEX_REMAP[index]] }
609 }
610}
611
612impl std::convert::From<Motor> for [f32; 8] {
613 fn from(vector: Motor) -> Self {
614 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]] }
615 }
616}
617
618impl std::convert::From<[f32; 8]> for Motor {
619 fn from(array: [f32; 8]) -> Self {
620 Self { elements: [array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7]] }
621 }
622}
623
624impl std::fmt::Debug for Motor {
625 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
626 formatter
627 .debug_struct("Motor")
628 .field("1", &self[0])
629 .field("e23", &self[1])
630 .field("-e13", &self[2])
631 .field("e12", &self[3])
632 .field("e0123", &self[4])
633 .field("e01", &self[5])
634 .field("e02", &self[6])
635 .field("e03", &self[7])
636 .finish()
637 }
638}
639
640#[derive(Clone, Copy)]
641struct PointAndPlaneGroups {
642 g0: Simd32x4,
644 g1: Simd32x4,
646}
647
648#[derive(Clone, Copy)]
649pub union PointAndPlane {
650 groups: PointAndPlaneGroups,
651 elements: [f32; 8],
653}
654
655impl PointAndPlane {
656 #[allow(clippy::too_many_arguments)]
657 pub const fn new(e123: f32, _e023: f32, e013: f32, _e012: f32, e0: f32, e1: f32, e2: f32, e3: f32) -> Self {
658 Self { elements: [e123, _e023, e013, _e012, e0, e1, e2, e3] }
659 }
660 pub const fn from_groups(g0: Simd32x4, g1: Simd32x4) -> Self {
661 Self { groups: PointAndPlaneGroups { g0, g1 } }
662 }
663 #[inline(always)]
664 pub fn group0(&self) -> Simd32x4 {
665 unsafe { self.groups.g0 }
666 }
667 #[inline(always)]
668 pub fn group0_mut(&mut self) -> &mut Simd32x4 {
669 unsafe { &mut self.groups.g0 }
670 }
671 #[inline(always)]
672 pub fn group1(&self) -> Simd32x4 {
673 unsafe { self.groups.g1 }
674 }
675 #[inline(always)]
676 pub fn group1_mut(&mut self) -> &mut Simd32x4 {
677 unsafe { &mut self.groups.g1 }
678 }
679}
680
681const POINTANDPLANE_INDEX_REMAP: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
682
683impl std::ops::Index<usize> for PointAndPlane {
684 type Output = f32;
685
686 fn index(&self, index: usize) -> &Self::Output {
687 unsafe { &self.elements[POINTANDPLANE_INDEX_REMAP[index]] }
688 }
689}
690
691impl std::ops::IndexMut<usize> for PointAndPlane {
692 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
693 unsafe { &mut self.elements[POINTANDPLANE_INDEX_REMAP[index]] }
694 }
695}
696
697impl std::convert::From<PointAndPlane> for [f32; 8] {
698 fn from(vector: PointAndPlane) -> Self {
699 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]] }
700 }
701}
702
703impl std::convert::From<[f32; 8]> for PointAndPlane {
704 fn from(array: [f32; 8]) -> Self {
705 Self { elements: [array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7]] }
706 }
707}
708
709impl std::fmt::Debug for PointAndPlane {
710 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
711 formatter
712 .debug_struct("PointAndPlane")
713 .field("e123", &self[0])
714 .field("-e023", &self[1])
715 .field("e013", &self[2])
716 .field("-e012", &self[3])
717 .field("e0", &self[4])
718 .field("e1", &self[5])
719 .field("e2", &self[6])
720 .field("e3", &self[7])
721 .finish()
722 }
723}
724
725impl Add<MultiVector> for f32 {
726 type Output = MultiVector;
727
728 fn add(self, other: MultiVector) -> MultiVector {
729 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0(), g1: other.group1(), g2: other.group2(), g3: other.group3() } }
730 }
731}
732
733impl Sub<MultiVector> for f32 {
734 type Output = MultiVector;
735
736 fn sub(self, other: MultiVector) -> MultiVector {
737 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(), g2: Simd32x4::from(0.0) - other.group2(), g3: Simd32x4::from(0.0) - other.group3() } }
738 }
739}
740
741impl GeometricProduct<MultiVector> for f32 {
742 type Output = MultiVector;
743
744 fn geometric_product(self, other: MultiVector) -> MultiVector {
745 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1(), g2: Simd32x4::from(self) * other.group2(), g3: Simd32x4::from(self) * other.group3() } }
746 }
747}
748
749impl RegressiveProduct<MultiVector> for f32 {
750 type Output = f32;
751
752 fn regressive_product(self, other: MultiVector) -> f32 {
753 self * other.group3()[0]
754 }
755}
756
757impl OuterProduct<MultiVector> for f32 {
758 type Output = MultiVector;
759
760 fn outer_product(self, other: MultiVector) -> MultiVector {
761 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1(), g2: Simd32x4::from(self) * other.group2(), g3: Simd32x4::from(self) * other.group3() } }
762 }
763}
764
765impl InnerProduct<MultiVector> for f32 {
766 type Output = MultiVector;
767
768 fn inner_product(self, other: MultiVector) -> MultiVector {
769 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1(), g2: Simd32x4::from(self) * other.group2(), g3: Simd32x4::from(self) * other.group3() } }
770 }
771}
772
773impl LeftContraction<MultiVector> for f32 {
774 type Output = MultiVector;
775
776 fn left_contraction(self, other: MultiVector) -> MultiVector {
777 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1(), g2: Simd32x4::from(self) * other.group2(), g3: Simd32x4::from(self) * other.group3() } }
778 }
779}
780
781impl RightContraction<MultiVector> for f32 {
782 type Output = f32;
783
784 fn right_contraction(self, other: MultiVector) -> f32 {
785 self * other.group0()[0]
786 }
787}
788
789impl ScalarProduct<MultiVector> for f32 {
790 type Output = f32;
791
792 fn scalar_product(self, other: MultiVector) -> f32 {
793 self * other.group0()[0]
794 }
795}
796
797impl Add<Rotor> for f32 {
798 type Output = Rotor;
799
800 fn add(self, other: Rotor) -> Rotor {
801 Rotor { groups: RotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0() } }
802 }
803}
804
805impl Sub<Rotor> for f32 {
806 type Output = Rotor;
807
808 fn sub(self, other: Rotor) -> Rotor {
809 Rotor { groups: RotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0() } }
810 }
811}
812
813impl GeometricProduct<Rotor> for f32 {
814 type Output = Rotor;
815
816 fn geometric_product(self, other: Rotor) -> Rotor {
817 Rotor { groups: RotorGroups { g0: Simd32x4::from(self) * other.group0() } }
818 }
819}
820
821impl OuterProduct<Rotor> for f32 {
822 type Output = Rotor;
823
824 fn outer_product(self, other: Rotor) -> Rotor {
825 Rotor { groups: RotorGroups { g0: Simd32x4::from(self) * other.group0() } }
826 }
827}
828
829impl InnerProduct<Rotor> for f32 {
830 type Output = Rotor;
831
832 fn inner_product(self, other: Rotor) -> Rotor {
833 Rotor { groups: RotorGroups { g0: Simd32x4::from(self) * other.group0() } }
834 }
835}
836
837impl LeftContraction<Rotor> for f32 {
838 type Output = Rotor;
839
840 fn left_contraction(self, other: Rotor) -> Rotor {
841 Rotor { groups: RotorGroups { g0: Simd32x4::from(self) * other.group0() } }
842 }
843}
844
845impl RightContraction<Rotor> for f32 {
846 type Output = f32;
847
848 fn right_contraction(self, other: Rotor) -> f32 {
849 self * other.group0()[0]
850 }
851}
852
853impl ScalarProduct<Rotor> for f32 {
854 type Output = f32;
855
856 fn scalar_product(self, other: Rotor) -> f32 {
857 self * other.group0()[0]
858 }
859}
860
861impl GeometricProduct<Point> for f32 {
862 type Output = Point;
863
864 fn geometric_product(self, other: Point) -> Point {
865 Point { groups: PointGroups { g0: Simd32x4::from(self) * other.group0() } }
866 }
867}
868
869impl OuterProduct<Point> for f32 {
870 type Output = Point;
871
872 fn outer_product(self, other: Point) -> Point {
873 Point { groups: PointGroups { g0: Simd32x4::from(self) * other.group0() } }
874 }
875}
876
877impl InnerProduct<Point> for f32 {
878 type Output = Point;
879
880 fn inner_product(self, other: Point) -> Point {
881 Point { groups: PointGroups { g0: Simd32x4::from(self) * other.group0() } }
882 }
883}
884
885impl LeftContraction<Point> for f32 {
886 type Output = Point;
887
888 fn left_contraction(self, other: Point) -> Point {
889 Point { groups: PointGroups { g0: Simd32x4::from(self) * other.group0() } }
890 }
891}
892
893impl Add<IdealPoint> for f32 {
894 type Output = Translator;
895
896 fn add(self, other: IdealPoint) -> Translator {
897 Translator { groups: TranslatorGroups { 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]) } }
898 }
899}
900
901impl Sub<IdealPoint> for f32 {
902 type Output = Translator;
903
904 fn sub(self, other: IdealPoint) -> Translator {
905 Translator { groups: TranslatorGroups { 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]) } }
906 }
907}
908
909impl GeometricProduct<IdealPoint> for f32 {
910 type Output = IdealPoint;
911
912 fn geometric_product(self, other: IdealPoint) -> IdealPoint {
913 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self) * other.group0() } }
914 }
915}
916
917impl OuterProduct<IdealPoint> for f32 {
918 type Output = IdealPoint;
919
920 fn outer_product(self, other: IdealPoint) -> IdealPoint {
921 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self) * other.group0() } }
922 }
923}
924
925impl InnerProduct<IdealPoint> for f32 {
926 type Output = IdealPoint;
927
928 fn inner_product(self, other: IdealPoint) -> IdealPoint {
929 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self) * other.group0() } }
930 }
931}
932
933impl LeftContraction<IdealPoint> for f32 {
934 type Output = IdealPoint;
935
936 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
937 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self) * other.group0() } }
938 }
939}
940
941impl GeometricProduct<Plane> for f32 {
942 type Output = Plane;
943
944 fn geometric_product(self, other: Plane) -> Plane {
945 Plane { groups: PlaneGroups { g0: Simd32x4::from(self) * other.group0() } }
946 }
947}
948
949impl OuterProduct<Plane> for f32 {
950 type Output = Plane;
951
952 fn outer_product(self, other: Plane) -> Plane {
953 Plane { groups: PlaneGroups { g0: Simd32x4::from(self) * other.group0() } }
954 }
955}
956
957impl InnerProduct<Plane> for f32 {
958 type Output = Plane;
959
960 fn inner_product(self, other: Plane) -> Plane {
961 Plane { groups: PlaneGroups { g0: Simd32x4::from(self) * other.group0() } }
962 }
963}
964
965impl LeftContraction<Plane> for f32 {
966 type Output = Plane;
967
968 fn left_contraction(self, other: Plane) -> Plane {
969 Plane { groups: PlaneGroups { g0: Simd32x4::from(self) * other.group0() } }
970 }
971}
972
973impl GeometricProduct<Line> for f32 {
974 type Output = Line;
975
976 fn geometric_product(self, other: Line) -> Line {
977 Line { groups: LineGroups { g0: Simd32x3::from(self) * other.group0(), g1: Simd32x3::from(self) * other.group1() } }
978 }
979}
980
981impl OuterProduct<Line> for f32 {
982 type Output = Line;
983
984 fn outer_product(self, other: Line) -> Line {
985 Line { groups: LineGroups { g0: Simd32x3::from(self) * other.group0(), g1: Simd32x3::from(self) * other.group1() } }
986 }
987}
988
989impl InnerProduct<Line> for f32 {
990 type Output = Line;
991
992 fn inner_product(self, other: Line) -> Line {
993 Line { groups: LineGroups { g0: Simd32x3::from(self) * other.group0(), g1: Simd32x3::from(self) * other.group1() } }
994 }
995}
996
997impl LeftContraction<Line> for f32 {
998 type Output = Line;
999
1000 fn left_contraction(self, other: Line) -> Line {
1001 Line { groups: LineGroups { g0: Simd32x3::from(self) * other.group0(), g1: Simd32x3::from(self) * other.group1() } }
1002 }
1003}
1004
1005impl Add<Translator> for f32 {
1006 type Output = Translator;
1007
1008 fn add(self, other: Translator) -> Translator {
1009 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0() } }
1010 }
1011}
1012
1013impl Sub<Translator> for f32 {
1014 type Output = Translator;
1015
1016 fn sub(self, other: Translator) -> Translator {
1017 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0() } }
1018 }
1019}
1020
1021impl GeometricProduct<Translator> for f32 {
1022 type Output = Translator;
1023
1024 fn geometric_product(self, other: Translator) -> Translator {
1025 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self) * other.group0() } }
1026 }
1027}
1028
1029impl OuterProduct<Translator> for f32 {
1030 type Output = Translator;
1031
1032 fn outer_product(self, other: Translator) -> Translator {
1033 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self) * other.group0() } }
1034 }
1035}
1036
1037impl InnerProduct<Translator> for f32 {
1038 type Output = Translator;
1039
1040 fn inner_product(self, other: Translator) -> Translator {
1041 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self) * other.group0() } }
1042 }
1043}
1044
1045impl LeftContraction<Translator> for f32 {
1046 type Output = Translator;
1047
1048 fn left_contraction(self, other: Translator) -> Translator {
1049 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self) * other.group0() } }
1050 }
1051}
1052
1053impl RightContraction<Translator> for f32 {
1054 type Output = f32;
1055
1056 fn right_contraction(self, other: Translator) -> f32 {
1057 self * other.group0()[0]
1058 }
1059}
1060
1061impl ScalarProduct<Translator> for f32 {
1062 type Output = f32;
1063
1064 fn scalar_product(self, other: Translator) -> f32 {
1065 self * other.group0()[0]
1066 }
1067}
1068
1069impl Add<Motor> for f32 {
1070 type Output = Motor;
1071
1072 fn add(self, other: Motor) -> Motor {
1073 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0(), g1: other.group1() } }
1074 }
1075}
1076
1077impl Sub<Motor> for f32 {
1078 type Output = Motor;
1079
1080 fn sub(self, other: Motor) -> Motor {
1081 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0(), g1: Simd32x4::from(0.0) - other.group1() } }
1082 }
1083}
1084
1085impl GeometricProduct<Motor> for f32 {
1086 type Output = Motor;
1087
1088 fn geometric_product(self, other: Motor) -> Motor {
1089 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1090 }
1091}
1092
1093impl RegressiveProduct<Motor> for f32 {
1094 type Output = f32;
1095
1096 fn regressive_product(self, other: Motor) -> f32 {
1097 self * other.group1()[0]
1098 }
1099}
1100
1101impl OuterProduct<Motor> for f32 {
1102 type Output = Motor;
1103
1104 fn outer_product(self, other: Motor) -> Motor {
1105 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1106 }
1107}
1108
1109impl InnerProduct<Motor> for f32 {
1110 type Output = Motor;
1111
1112 fn inner_product(self, other: Motor) -> Motor {
1113 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1114 }
1115}
1116
1117impl LeftContraction<Motor> for f32 {
1118 type Output = Motor;
1119
1120 fn left_contraction(self, other: Motor) -> Motor {
1121 Motor { groups: MotorGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1122 }
1123}
1124
1125impl RightContraction<Motor> for f32 {
1126 type Output = f32;
1127
1128 fn right_contraction(self, other: Motor) -> f32 {
1129 self * other.group0()[0]
1130 }
1131}
1132
1133impl ScalarProduct<Motor> for f32 {
1134 type Output = f32;
1135
1136 fn scalar_product(self, other: Motor) -> f32 {
1137 self * other.group0()[0]
1138 }
1139}
1140
1141impl GeometricProduct<PointAndPlane> for f32 {
1142 type Output = PointAndPlane;
1143
1144 fn geometric_product(self, other: PointAndPlane) -> PointAndPlane {
1145 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1146 }
1147}
1148
1149impl OuterProduct<PointAndPlane> for f32 {
1150 type Output = PointAndPlane;
1151
1152 fn outer_product(self, other: PointAndPlane) -> PointAndPlane {
1153 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1154 }
1155}
1156
1157impl InnerProduct<PointAndPlane> for f32 {
1158 type Output = PointAndPlane;
1159
1160 fn inner_product(self, other: PointAndPlane) -> PointAndPlane {
1161 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1162 }
1163}
1164
1165impl LeftContraction<PointAndPlane> for f32 {
1166 type Output = PointAndPlane;
1167
1168 fn left_contraction(self, other: PointAndPlane) -> PointAndPlane {
1169 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self) * other.group0(), g1: Simd32x4::from(self) * other.group1() } }
1170 }
1171}
1172
1173impl Zero for MultiVector {
1174 fn zero() -> Self {
1175 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0), g1: Simd32x4::from(0.0), g2: Simd32x4::from(0.0), g3: Simd32x4::from(0.0) } }
1176 }
1177}
1178
1179impl One for MultiVector {
1180 fn one() -> Self {
1181 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(0.0), g2: Simd32x4::from(0.0), g3: Simd32x4::from(0.0) } }
1182 }
1183}
1184
1185impl Neg for MultiVector {
1186 type Output = MultiVector;
1187
1188 fn neg(self) -> MultiVector {
1189 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(-1.0), g1: self.group1() * Simd32x4::from(-1.0), g2: self.group2() * Simd32x4::from(-1.0), g3: self.group3() * Simd32x4::from(-1.0) } }
1190 }
1191}
1192
1193impl Automorphism for MultiVector {
1194 type Output = MultiVector;
1195
1196 fn automorphism(self) -> MultiVector {
1197 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() * Simd32x4::from(-1.0), g2: self.group2() * Simd32x4::from(-1.0), g3: self.group3() } }
1198 }
1199}
1200
1201impl Reversal for MultiVector {
1202 type Output = MultiVector;
1203
1204 fn reversal(self) -> MultiVector {
1205 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]), g2: self.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g3: self.group3() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
1206 }
1207}
1208
1209impl Conjugation for MultiVector {
1210 type Output = MultiVector;
1211
1212 fn conjugation(self) -> MultiVector {
1213 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]), g2: self.group2() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g3: self.group3() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
1214 }
1215}
1216
1217impl Dual for MultiVector {
1218 type Output = MultiVector;
1219
1220 fn dual(self) -> MultiVector {
1221 MultiVector { groups: MultiVectorGroups { g0: self.group3(), g1: self.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g2: self.group1() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g3: self.group0() } }
1222 }
1223}
1224
1225impl Into<f32> for MultiVector {
1226 fn into(self) -> f32 {
1227 self.group0()[0]
1228 }
1229}
1230
1231impl Add<f32> for MultiVector {
1232 type Output = MultiVector;
1233
1234 fn add(self, other: f32) -> MultiVector {
1235 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1(), g2: self.group2(), g3: self.group3() } }
1236 }
1237}
1238
1239impl AddAssign<f32> for MultiVector {
1240 fn add_assign(&mut self, other: f32) {
1241 *self = (*self).add(other);
1242 }
1243}
1244
1245impl Sub<f32> for MultiVector {
1246 type Output = MultiVector;
1247
1248 fn sub(self, other: f32) -> MultiVector {
1249 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1(), g2: self.group2(), g3: self.group3() } }
1250 }
1251}
1252
1253impl SubAssign<f32> for MultiVector {
1254 fn sub_assign(&mut self, other: f32) {
1255 *self = (*self).sub(other);
1256 }
1257}
1258
1259impl GeometricProduct<f32> for MultiVector {
1260 type Output = MultiVector;
1261
1262 fn geometric_product(self, other: f32) -> MultiVector {
1263 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other), g2: self.group2() * Simd32x4::from(other), g3: self.group3() * Simd32x4::from(other) } }
1264 }
1265}
1266
1267impl RegressiveProduct<f32> for MultiVector {
1268 type Output = f32;
1269
1270 fn regressive_product(self, other: f32) -> f32 {
1271 self.group3()[0] * other
1272 }
1273}
1274
1275impl OuterProduct<f32> for MultiVector {
1276 type Output = MultiVector;
1277
1278 fn outer_product(self, other: f32) -> MultiVector {
1279 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other), g2: self.group2() * Simd32x4::from(other), g3: self.group3() * Simd32x4::from(other) } }
1280 }
1281}
1282
1283impl InnerProduct<f32> for MultiVector {
1284 type Output = MultiVector;
1285
1286 fn inner_product(self, other: f32) -> MultiVector {
1287 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other), g2: self.group2() * Simd32x4::from(other), g3: self.group3() * Simd32x4::from(other) } }
1288 }
1289}
1290
1291impl LeftContraction<f32> for MultiVector {
1292 type Output = f32;
1293
1294 fn left_contraction(self, other: f32) -> f32 {
1295 self.group0()[0] * other
1296 }
1297}
1298
1299impl RightContraction<f32> for MultiVector {
1300 type Output = MultiVector;
1301
1302 fn right_contraction(self, other: f32) -> MultiVector {
1303 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other), g2: self.group2() * Simd32x4::from(other), g3: self.group3() * Simd32x4::from(other) } }
1304 }
1305}
1306
1307impl ScalarProduct<f32> for MultiVector {
1308 type Output = f32;
1309
1310 fn scalar_product(self, other: f32) -> f32 {
1311 self.group0()[0] * other
1312 }
1313}
1314
1315impl Add<MultiVector> for MultiVector {
1316 type Output = MultiVector;
1317
1318 fn add(self, other: MultiVector) -> MultiVector {
1319 MultiVector { groups: MultiVectorGroups { g0: self.group0() + other.group0(), g1: self.group1() + other.group1(), g2: self.group2() + other.group2(), g3: self.group3() + other.group3() } }
1320 }
1321}
1322
1323impl AddAssign<MultiVector> for MultiVector {
1324 fn add_assign(&mut self, other: MultiVector) {
1325 *self = (*self).add(other);
1326 }
1327}
1328
1329impl Sub<MultiVector> for MultiVector {
1330 type Output = MultiVector;
1331
1332 fn sub(self, other: MultiVector) -> MultiVector {
1333 MultiVector { groups: MultiVectorGroups { g0: self.group0() - other.group0(), g1: self.group1() - other.group1(), g2: self.group2() - other.group2(), g3: self.group3() - other.group3() } }
1334 }
1335}
1336
1337impl SubAssign<MultiVector> for MultiVector {
1338 fn sub_assign(&mut self, other: MultiVector) {
1339 *self = (*self).sub(other);
1340 }
1341}
1342
1343impl Mul<MultiVector> for MultiVector {
1344 type Output = MultiVector;
1345
1346 fn mul(self, other: MultiVector) -> MultiVector {
1347 MultiVector { groups: MultiVectorGroups { g0: self.group0() * other.group0(), g1: self.group1() * other.group1(), g2: self.group2() * other.group2(), g3: self.group3() * other.group3() } }
1348 }
1349}
1350
1351impl MulAssign<MultiVector> for MultiVector {
1352 fn mul_assign(&mut self, other: MultiVector) {
1353 *self = (*self).mul(other);
1354 }
1355}
1356
1357impl Div<MultiVector> for MultiVector {
1358 type Output = MultiVector;
1359
1360 fn div(self, other: MultiVector) -> MultiVector {
1361 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]), g2: Simd32x4::from([self.group2()[0], self.group2()[1], self.group2()[2], self.group2()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) / Simd32x4::from([other.group2()[0], other.group2()[1], other.group2()[2], other.group2()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]), g3: Simd32x4::from([self.group3()[0], self.group3()[1], self.group3()[2], self.group3()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) / Simd32x4::from([other.group3()[0], other.group3()[1], other.group3()[2], other.group3()[3]]) * Simd32x4::from([1.0, 1.0, 1.0, 1.0]) } }
1362 }
1363}
1364
1365impl DivAssign<MultiVector> for MultiVector {
1366 fn div_assign(&mut self, other: MultiVector) {
1367 *self = (*self).div(other);
1368 }
1369}
1370
1371impl GeometricProduct<MultiVector> for MultiVector {
1372 type Output = MultiVector;
1373
1374 fn geometric_product(self, other: MultiVector) -> MultiVector {
1375 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([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.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]) + Simd32x4::from(self.group2()[0]) * other.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group3() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group3(), 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([1.0, 1.0, -1.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]) * 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]) + Simd32x4::from(self.group2()[0]) * other.group3() + Simd32x4::from(self.group2()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) - Simd32x4::from(self.group3()[0]) * other.group2() + Simd32x4::from(self.group3()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) - Simd32x4::from(self.group1()[0]) * other.group3() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group1() + Simd32x4::from(self.group3()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * other.group2() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) - Simd32x4::from(self.group2()[0]) * other.group1() + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) } }
1376 }
1377}
1378
1379impl RegressiveProduct<MultiVector> for MultiVector {
1380 type Output = MultiVector;
1381
1382 fn regressive_product(self, other: MultiVector) -> MultiVector {
1383 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group2(), 1, 0, 1, 1) * Simd32x4::from([-1.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[0]) * other.group1() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group1()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[0]) * other.group0() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group1() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group1()[1]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.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]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[0]) * other.group3() + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group2() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group2()[1], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group1()[0], other.group3()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]), g3: Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[0]) * other.group3() + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group1()[0], self.group3()[1], self.group1()[1], self.group1()[1]]) * Simd32x4::from([other.group1()[0], other.group3()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) } }
1384 }
1385}
1386
1387impl OuterProduct<MultiVector> for MultiVector {
1388 type Output = MultiVector;
1389
1390 fn outer_product(self, other: MultiVector) -> MultiVector {
1391 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group2()[1]) * swizzle!(other.group2(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + 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]) * 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.group2()[1]) * swizzle!(other.group3(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group3(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group3(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group2(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[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.group2(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group3()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group3()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group2() + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group2()[1]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[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.group3(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1392 }
1393}
1394
1395impl InnerProduct<MultiVector> for MultiVector {
1396 type Output = MultiVector;
1397
1398 fn inner_product(self, other: MultiVector) -> MultiVector {
1399 MultiVector { groups: MultiVectorGroups { 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]) + 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, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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.group2()[0]) * other.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group2(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group2(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group2(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group3() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group3(), 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[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]) * 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.group2()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) - Simd32x4::from(self.group3()[0]) * other.group2() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group2()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, -1.0]) - Simd32x4::from(self.group1()[0]) * other.group3() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group1() + Simd32x4::from(self.group3()[1]) * swizzle!(other.group1(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group1(), 3, 3, 0, 1) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group1(), 2, 2, 1, 0) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group2(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group2(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + self.group0() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
1400 }
1401}
1402
1403impl LeftContraction<MultiVector> for MultiVector {
1404 type Output = MultiVector;
1405
1406 fn left_contraction(self, other: MultiVector) -> MultiVector {
1407 MultiVector { groups: MultiVectorGroups { 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]) + 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]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group2(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group2(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group2(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.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]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group3(), 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]), g2: Simd32x4::from(self.group0()[0]) * other.group2() - Simd32x4::from(self.group1()[0]) * other.group3() + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group1(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + self.group0() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
1408 }
1409}
1410
1411impl RightContraction<MultiVector> for MultiVector {
1412 type Output = MultiVector;
1413
1414 fn right_contraction(self, other: MultiVector) -> MultiVector {
1415 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()[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, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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.group2()[0]) * other.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group2()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[0]) * other.group3() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group3()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group3()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group3()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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.group3()[0]) * other.group2() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group2()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group2()[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]), g2: Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group1() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group2()[1], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group2()[0], other.group0()[0], other.group2()[3], other.group2()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group1()[0], self.group3()[1], self.group1()[1], self.group1()[1]]) * Simd32x4::from([other.group2()[0], other.group0()[0], other.group2()[3], other.group2()[2]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) } }
1416 }
1417}
1418
1419impl ScalarProduct<MultiVector> for MultiVector {
1420 type Output = f32;
1421
1422 fn scalar_product(self, other: MultiVector) -> f32 {
1423 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] - self.group2()[0] * other.group2()[0] + self.group2()[1] * other.group2()[1] + self.group2()[2] * other.group2()[2] + self.group2()[3] * other.group2()[3] - self.group3()[0] * other.group3()[0] + self.group3()[1] * other.group3()[1] + self.group3()[2] * other.group3()[2] + self.group3()[3] * other.group3()[3]
1424 }
1425}
1426
1427impl Into<Rotor> for MultiVector {
1428 fn into(self) -> Rotor {
1429 Rotor { groups: RotorGroups { g0: self.group0() } }
1430 }
1431}
1432
1433impl Add<Rotor> for MultiVector {
1434 type Output = MultiVector;
1435
1436 fn add(self, other: Rotor) -> MultiVector {
1437 MultiVector { groups: MultiVectorGroups { g0: self.group0() + other.group0(), g1: self.group1(), g2: self.group2(), g3: self.group3() } }
1438 }
1439}
1440
1441impl AddAssign<Rotor> for MultiVector {
1442 fn add_assign(&mut self, other: Rotor) {
1443 *self = (*self).add(other);
1444 }
1445}
1446
1447impl Sub<Rotor> for MultiVector {
1448 type Output = MultiVector;
1449
1450 fn sub(self, other: Rotor) -> MultiVector {
1451 MultiVector { groups: MultiVectorGroups { g0: self.group0() - other.group0(), g1: self.group1(), g2: self.group2(), g3: self.group3() } }
1452 }
1453}
1454
1455impl SubAssign<Rotor> for MultiVector {
1456 fn sub_assign(&mut self, other: Rotor) {
1457 *self = (*self).sub(other);
1458 }
1459}
1460
1461impl GeometricProduct<Rotor> for MultiVector {
1462 type Output = MultiVector;
1463
1464 fn geometric_product(self, other: Rotor) -> MultiVector {
1465 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([-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]), g1: 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]), g2: Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]), g3: Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) } }
1466 }
1467}
1468
1469impl OuterProduct<Rotor> for MultiVector {
1470 type Output = MultiVector;
1471
1472 fn outer_product(self, other: Rotor) -> MultiVector {
1473 MultiVector { groups: MultiVectorGroups { 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]), g1: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g2: Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1474 }
1475}
1476
1477impl InnerProduct<Rotor> for MultiVector {
1478 type Output = MultiVector;
1479
1480 fn inner_product(self, other: Rotor) -> MultiVector {
1481 MultiVector { groups: MultiVectorGroups { 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]), g1: 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(), 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]), g2: Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + swizzle!(self.group2(), 0, 1, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group3() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1482 }
1483}
1484
1485impl RightContraction<Rotor> for MultiVector {
1486 type Output = MultiVector;
1487
1488 fn right_contraction(self, other: Rotor) -> MultiVector {
1489 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()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group2() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g3: Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group3() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1490 }
1491}
1492
1493impl ScalarProduct<Rotor> for MultiVector {
1494 type Output = f32;
1495
1496 fn scalar_product(self, other: Rotor) -> f32 {
1497 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2] - self.group0()[3] * other.group0()[3]
1498 }
1499}
1500
1501impl Into<Point> for MultiVector {
1502 fn into(self) -> Point {
1503 Point { groups: PointGroups { g0: Simd32x4::from([self.group2()[0], self.group1()[1], self.group1()[2], self.group1()[3]]) } }
1504 }
1505}
1506
1507impl Add<Point> for MultiVector {
1508 type Output = MultiVector;
1509
1510 fn add(self, other: Point) -> MultiVector {
1511 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() + other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g2: self.group2() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: self.group3() } }
1512 }
1513}
1514
1515impl AddAssign<Point> for MultiVector {
1516 fn add_assign(&mut self, other: Point) {
1517 *self = (*self).add(other);
1518 }
1519}
1520
1521impl Sub<Point> for MultiVector {
1522 type Output = MultiVector;
1523
1524 fn sub(self, other: Point) -> MultiVector {
1525 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() - other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g2: self.group2() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: self.group3() } }
1526 }
1527}
1528
1529impl SubAssign<Point> for MultiVector {
1530 fn sub_assign(&mut self, other: Point) {
1531 *self = (*self).sub(other);
1532 }
1533}
1534
1535impl GeometricProduct<Point> for MultiVector {
1536 type Output = MultiVector;
1537
1538 fn geometric_product(self, other: Point) -> MultiVector {
1539 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group2()[0], self.group1()[0], self.group1()[0], self.group1()[0]]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group3()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g2: Simd32x4::from(self.group3()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([-1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([-1.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group2()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + self.group1() * Simd32x4::from(other.group0()[0]) } }
1540 }
1541}
1542
1543impl ScalarProduct<Point> for MultiVector {
1544 type Output = f32;
1545
1546 fn scalar_product(self, other: Point) -> f32 {
1547 self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2] + self.group1()[3] * other.group0()[3] - self.group2()[0] * other.group0()[0]
1548 }
1549}
1550
1551impl Into<IdealPoint> for MultiVector {
1552 fn into(self) -> IdealPoint {
1553 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from([self.group3()[1], self.group3()[2], self.group3()[3]]) } }
1554 }
1555}
1556
1557impl Add<IdealPoint> for MultiVector {
1558 type Output = MultiVector;
1559
1560 fn add(self, other: IdealPoint) -> MultiVector {
1561 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1(), g2: self.group2(), g3: self.group3() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1562 }
1563}
1564
1565impl AddAssign<IdealPoint> for MultiVector {
1566 fn add_assign(&mut self, other: IdealPoint) {
1567 *self = (*self).add(other);
1568 }
1569}
1570
1571impl Sub<IdealPoint> for MultiVector {
1572 type Output = MultiVector;
1573
1574 fn sub(self, other: IdealPoint) -> MultiVector {
1575 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1(), g2: self.group2(), g3: self.group3() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1576 }
1577}
1578
1579impl SubAssign<IdealPoint> for MultiVector {
1580 fn sub_assign(&mut self, other: IdealPoint) {
1581 *self = (*self).sub(other);
1582 }
1583}
1584
1585impl GeometricProduct<IdealPoint> for MultiVector {
1586 type Output = MultiVector;
1587
1588 fn geometric_product(self, other: IdealPoint) -> MultiVector {
1589 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group3()[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.group3()[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.group3()[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.group3()[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]), g1: Simd32x4::from(self.group2()[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.group2()[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.group2()[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.group2()[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]), g2: Simd32x4::from(self.group1()[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.group1()[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.group1()[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.group1()[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]), g3: 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]) } }
1590 }
1591}
1592
1593impl ScalarProduct<IdealPoint> for MultiVector {
1594 type Output = f32;
1595
1596 fn scalar_product(self, other: IdealPoint) -> f32 {
1597 self.group3()[1] * other.group0()[0] + self.group3()[2] * other.group0()[1] + self.group3()[3] * other.group0()[2]
1598 }
1599}
1600
1601impl Into<Plane> for MultiVector {
1602 fn into(self) -> Plane {
1603 Plane { groups: PlaneGroups { g0: Simd32x4::from([self.group1()[0], self.group2()[1], self.group2()[2], self.group2()[3]]) } }
1604 }
1605}
1606
1607impl Add<Plane> for MultiVector {
1608 type Output = MultiVector;
1609
1610 fn add(self, other: Plane) -> MultiVector {
1611 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: self.group2() + other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g3: self.group3() } }
1612 }
1613}
1614
1615impl AddAssign<Plane> for MultiVector {
1616 fn add_assign(&mut self, other: Plane) {
1617 *self = (*self).add(other);
1618 }
1619}
1620
1621impl Sub<Plane> for MultiVector {
1622 type Output = MultiVector;
1623
1624 fn sub(self, other: Plane) -> MultiVector {
1625 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: self.group2() - other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g3: self.group3() } }
1626 }
1627}
1628
1629impl SubAssign<Plane> for MultiVector {
1630 fn sub_assign(&mut self, other: Plane) {
1631 *self = (*self).sub(other);
1632 }
1633}
1634
1635impl GeometricProduct<Plane> for MultiVector {
1636 type Output = MultiVector;
1637
1638 fn geometric_product(self, other: Plane) -> MultiVector {
1639 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group2()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group3()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group3()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group0(), g3: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([-1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([-1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, -1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group2()[0], self.group1()[0], self.group1()[0], self.group1()[0]]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
1640 }
1641}
1642
1643impl ScalarProduct<Plane> for MultiVector {
1644 type Output = f32;
1645
1646 fn scalar_product(self, other: Plane) -> f32 {
1647 0.0 - self.group1()[0] * other.group0()[0] + self.group2()[1] * other.group0()[1] + self.group2()[2] * other.group0()[2] + self.group2()[3] * other.group0()[3]
1648 }
1649}
1650
1651impl Into<Line> for MultiVector {
1652 fn into(self) -> Line {
1653 Line { groups: LineGroups { g0: Simd32x3::from([self.group3()[1], self.group3()[2], self.group3()[3]]), g1: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
1654 }
1655}
1656
1657impl Add<Line> for MultiVector {
1658 type Output = MultiVector;
1659
1660 fn add(self, other: Line) -> MultiVector {
1661 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: self.group1(), g2: self.group2(), g3: self.group3() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1662 }
1663}
1664
1665impl AddAssign<Line> for MultiVector {
1666 fn add_assign(&mut self, other: Line) {
1667 *self = (*self).add(other);
1668 }
1669}
1670
1671impl Sub<Line> for MultiVector {
1672 type Output = MultiVector;
1673
1674 fn sub(self, other: Line) -> MultiVector {
1675 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: self.group1(), g2: self.group2(), g3: self.group3() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1676 }
1677}
1678
1679impl SubAssign<Line> for MultiVector {
1680 fn sub_assign(&mut self, other: Line) {
1681 *self = (*self).sub(other);
1682 }
1683}
1684
1685impl GeometricProduct<Line> for MultiVector {
1686 type Output = MultiVector;
1687
1688 fn geometric_product(self, other: Line) -> MultiVector {
1689 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[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]) + Simd32x4::from(self.group3()[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.group3()[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.group3()[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.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[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]) + Simd32x4::from(self.group2()[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.group2()[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.group2()[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.group1()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group1()[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.group1()[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.group1()[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.group2()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]), g3: 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.group3()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[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]) } }
1690 }
1691}
1692
1693impl ScalarProduct<Line> for MultiVector {
1694 type Output = f32;
1695
1696 fn scalar_product(self, other: Line) -> f32 {
1697 0.0 - self.group0()[1] * other.group1()[0] - self.group0()[2] * other.group1()[1] - self.group0()[3] * other.group1()[2] + self.group3()[1] * other.group0()[0] + self.group3()[2] * other.group0()[1] + self.group3()[3] * other.group0()[2]
1698 }
1699}
1700
1701impl Into<Translator> for MultiVector {
1702 fn into(self) -> Translator {
1703 Translator { groups: TranslatorGroups { g0: Simd32x4::from([self.group0()[0], self.group3()[1], self.group3()[2], self.group3()[3]]) } }
1704 }
1705}
1706
1707impl Add<Translator> for MultiVector {
1708 type Output = MultiVector;
1709
1710 fn add(self, other: Translator) -> MultiVector {
1711 MultiVector { groups: MultiVectorGroups { g0: self.group0() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1(), g2: self.group2(), g3: self.group3() + other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1712 }
1713}
1714
1715impl AddAssign<Translator> for MultiVector {
1716 fn add_assign(&mut self, other: Translator) {
1717 *self = (*self).add(other);
1718 }
1719}
1720
1721impl Sub<Translator> for MultiVector {
1722 type Output = MultiVector;
1723
1724 fn sub(self, other: Translator) -> MultiVector {
1725 MultiVector { groups: MultiVectorGroups { g0: self.group0() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1(), g2: self.group2(), g3: self.group3() - other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1726 }
1727}
1728
1729impl SubAssign<Translator> for MultiVector {
1730 fn sub_assign(&mut self, other: Translator) {
1731 *self = (*self).sub(other);
1732 }
1733}
1734
1735impl GeometricProduct<Translator> for MultiVector {
1736 type Output = MultiVector;
1737
1738 fn geometric_product(self, other: Translator) -> MultiVector {
1739 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group3()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group2()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([-1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([-1.0, -1.0, 1.0, 0.0]) + self.group1() * Simd32x4::from(other.group0()[0]), g2: Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group2()[0], self.group1()[0], self.group1()[0], self.group1()[0]]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group3()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group0() } }
1740 }
1741}
1742
1743impl OuterProduct<Translator> for MultiVector {
1744 type Output = MultiVector;
1745
1746 fn outer_product(self, other: Translator) -> MultiVector {
1747 MultiVector { groups: MultiVectorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + self.group1() * Simd32x4::from(other.group0()[0]), g2: self.group2() * Simd32x4::from(other.group0()[0]), g3: 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]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 1, 2, 3) } }
1748 }
1749}
1750
1751impl InnerProduct<Translator> for MultiVector {
1752 type Output = MultiVector;
1753
1754 fn inner_product(self, other: Translator) -> MultiVector {
1755 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group3()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + self.group1() * Simd32x4::from(other.group0()[0]), g2: 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(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group2()[0], self.group1()[0], self.group1()[0], self.group1()[0]]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group3()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group0() } }
1756 }
1757}
1758
1759impl RightContraction<Translator> for MultiVector {
1760 type Output = MultiVector;
1761
1762 fn right_contraction(self, other: Translator) -> MultiVector {
1763 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group3()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[3]) * 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]), g2: Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group2()[0], self.group2()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]), g3: self.group3() * Simd32x4::from(other.group0()[0]) } }
1764 }
1765}
1766
1767impl ScalarProduct<Translator> for MultiVector {
1768 type Output = f32;
1769
1770 fn scalar_product(self, other: Translator) -> f32 {
1771 self.group0()[0] * other.group0()[0] + self.group3()[1] * other.group0()[1] + self.group3()[2] * other.group0()[2] + self.group3()[3] * other.group0()[3]
1772 }
1773}
1774
1775impl Into<Motor> for MultiVector {
1776 fn into(self) -> Motor {
1777 Motor { groups: MotorGroups { g0: self.group0(), g1: self.group3() } }
1778 }
1779}
1780
1781impl Add<Motor> for MultiVector {
1782 type Output = MultiVector;
1783
1784 fn add(self, other: Motor) -> MultiVector {
1785 MultiVector { groups: MultiVectorGroups { g0: self.group0() + other.group0(), g1: self.group1(), g2: self.group2(), g3: self.group3() + other.group1() } }
1786 }
1787}
1788
1789impl AddAssign<Motor> for MultiVector {
1790 fn add_assign(&mut self, other: Motor) {
1791 *self = (*self).add(other);
1792 }
1793}
1794
1795impl Sub<Motor> for MultiVector {
1796 type Output = MultiVector;
1797
1798 fn sub(self, other: Motor) -> MultiVector {
1799 MultiVector { groups: MultiVectorGroups { g0: self.group0() - other.group0(), g1: self.group1(), g2: self.group2(), g3: self.group3() - other.group1() } }
1800 }
1801}
1802
1803impl SubAssign<Motor> for MultiVector {
1804 fn sub_assign(&mut self, other: Motor) {
1805 *self = (*self).sub(other);
1806 }
1807}
1808
1809impl GeometricProduct<Motor> for MultiVector {
1810 type Output = MultiVector;
1811
1812 fn geometric_product(self, other: Motor) -> MultiVector {
1813 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([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group1() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: 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]) + Simd32x4::from(self.group2()[0]) * other.group1() + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]), g2: Simd32x4::from(0.0) - Simd32x4::from(self.group1()[0]) * other.group1() + 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]) + Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]), g3: 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([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) } }
1814 }
1815}
1816
1817impl RegressiveProduct<Motor> for MultiVector {
1818 type Output = MultiVector;
1819
1820 fn regressive_product(self, other: Motor) -> MultiVector {
1821 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group3()[0]) * other.group0() + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.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.group1()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[0]) * other.group1() + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group1()[0], self.group2()[1], self.group1()[1], self.group1()[1]]) * Simd32x4::from([other.group0()[0], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group3()[0]) * other.group1() + self.group3() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1822 }
1823}
1824
1825impl OuterProduct<Motor> for MultiVector {
1826 type Output = MultiVector;
1827
1828 fn outer_product(self, other: Motor) -> MultiVector {
1829 MultiVector { groups: MultiVectorGroups { 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]), g1: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g2: Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group0(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[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]) } }
1830 }
1831}
1832
1833impl InnerProduct<Motor> for MultiVector {
1834 type Output = MultiVector;
1835
1836 fn inner_product(self, other: Motor) -> MultiVector {
1837 MultiVector { groups: MultiVectorGroups { 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]) + Simd32x4::from(self.group3()[0]) * other.group1() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group1(), 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]), g1: 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(), 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.group2()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 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]), g2: Simd32x4::from(0.0) - Simd32x4::from(self.group1()[0]) * other.group1() + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + swizzle!(self.group1(), 0, 1, 1, 1) * swizzle!(other.group1(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
1838 }
1839}
1840
1841impl LeftContraction<Motor> for MultiVector {
1842 type Output = MultiVector;
1843
1844 fn left_contraction(self, other: Motor) -> MultiVector {
1845 MultiVector { groups: MultiVectorGroups { 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]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group3()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.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.group2()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([-1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: Simd32x4::from(0.0) - Simd32x4::from(self.group1()[0]) * other.group1() + Simd32x4::from(self.group2()[1]) * swizzle!(other.group0(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group2()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + self.group1() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group1() + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
1846 }
1847}
1848
1849impl RightContraction<Motor> for MultiVector {
1850 type Output = MultiVector;
1851
1852 fn right_contraction(self, other: Motor) -> MultiVector {
1853 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()[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.group3()[0]) * other.group1() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from(other.group1()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group2()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group1()[0], self.group2()[1], self.group1()[1], self.group1()[1]]) * Simd32x4::from([other.group1()[0], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group3()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group3() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
1854 }
1855}
1856
1857impl ScalarProduct<Motor> for MultiVector {
1858 type Output = f32;
1859
1860 fn scalar_product(self, other: Motor) -> f32 {
1861 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.group3()[0] * other.group1()[0] + self.group3()[1] * other.group1()[1] + self.group3()[2] * other.group1()[2] + self.group3()[3] * other.group1()[3]
1862 }
1863}
1864
1865impl Into<PointAndPlane> for MultiVector {
1866 fn into(self) -> PointAndPlane {
1867 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from([self.group2()[0], self.group1()[1], self.group1()[2], self.group1()[3]]), g1: Simd32x4::from([self.group1()[0], self.group2()[1], self.group2()[2], self.group2()[3]]) } }
1868 }
1869}
1870
1871impl Add<PointAndPlane> for MultiVector {
1872 type Output = MultiVector;
1873
1874 fn add(self, other: PointAndPlane) -> MultiVector {
1875 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() + Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]), g2: self.group2() + Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]), g3: self.group3() } }
1876 }
1877}
1878
1879impl AddAssign<PointAndPlane> for MultiVector {
1880 fn add_assign(&mut self, other: PointAndPlane) {
1881 *self = (*self).add(other);
1882 }
1883}
1884
1885impl Sub<PointAndPlane> for MultiVector {
1886 type Output = MultiVector;
1887
1888 fn sub(self, other: PointAndPlane) -> MultiVector {
1889 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: self.group1() - Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]), g2: self.group2() - Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]), g3: self.group3() } }
1890 }
1891}
1892
1893impl SubAssign<PointAndPlane> for MultiVector {
1894 fn sub_assign(&mut self, other: PointAndPlane) {
1895 *self = (*self).sub(other);
1896 }
1897}
1898
1899impl GeometricProduct<PointAndPlane> for MultiVector {
1900 type Output = MultiVector;
1901
1902 fn geometric_product(self, other: PointAndPlane) -> MultiVector {
1903 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) - Simd32x4::from(self.group3()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group3()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group3()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group3()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group3()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]), g3: Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) - Simd32x4::from(self.group2()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group2()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group2()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group2()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
1904 }
1905}
1906
1907impl ScalarProduct<PointAndPlane> for MultiVector {
1908 type Output = f32;
1909
1910 fn scalar_product(self, other: PointAndPlane) -> f32 {
1911 0.0 - self.group1()[0] * other.group1()[0] + self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2] + self.group1()[3] * other.group0()[3] - self.group2()[0] * other.group0()[0] + self.group2()[1] * other.group1()[1] + self.group2()[2] * other.group1()[2] + self.group2()[3] * other.group1()[3]
1912 }
1913}
1914
1915impl SquaredMagnitude for MultiVector {
1916 type Output = f32;
1917
1918 fn squared_magnitude(self) -> f32 {
1919 self.scalar_product(self.reversal())
1920 }
1921}
1922
1923impl Magnitude for MultiVector {
1924 type Output = f32;
1925
1926 fn magnitude(self) -> f32 {
1927 self.squared_magnitude().sqrt()
1928 }
1929}
1930
1931impl Mul<f32> for MultiVector {
1932 type Output = MultiVector;
1933
1934 fn mul(self, other: f32) -> MultiVector {
1935 self.geometric_product(other)
1936 }
1937}
1938
1939impl MulAssign<f32> for MultiVector {
1940 fn mul_assign(&mut self, other: f32) {
1941 *self = (*self).mul(other);
1942 }
1943}
1944
1945impl Signum for MultiVector {
1946 type Output = MultiVector;
1947
1948 fn signum(self) -> MultiVector {
1949 self.geometric_product(1.0 / self.magnitude())
1950 }
1951}
1952
1953impl Inverse for MultiVector {
1954 type Output = MultiVector;
1955
1956 fn inverse(self) -> MultiVector {
1957 self.reversal().geometric_product(1.0 / self.squared_magnitude())
1958 }
1959}
1960
1961impl Zero for Rotor {
1962 fn zero() -> Self {
1963 Rotor { groups: RotorGroups { g0: Simd32x4::from(0.0) } }
1964 }
1965}
1966
1967impl One for Rotor {
1968 fn one() -> Self {
1969 Rotor { groups: RotorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
1970 }
1971}
1972
1973impl Neg for Rotor {
1974 type Output = Rotor;
1975
1976 fn neg(self) -> Rotor {
1977 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
1978 }
1979}
1980
1981impl Automorphism for Rotor {
1982 type Output = Rotor;
1983
1984 fn automorphism(self) -> Rotor {
1985 Rotor { groups: RotorGroups { g0: self.group0() } }
1986 }
1987}
1988
1989impl Reversal for Rotor {
1990 type Output = Rotor;
1991
1992 fn reversal(self) -> Rotor {
1993 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
1994 }
1995}
1996
1997impl Conjugation for Rotor {
1998 type Output = Rotor;
1999
2000 fn conjugation(self) -> Rotor {
2001 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
2002 }
2003}
2004
2005impl Into<f32> for Rotor {
2006 fn into(self) -> f32 {
2007 self.group0()[0]
2008 }
2009}
2010
2011impl Add<f32> for Rotor {
2012 type Output = Rotor;
2013
2014 fn add(self, other: f32) -> Rotor {
2015 Rotor { groups: RotorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2016 }
2017}
2018
2019impl AddAssign<f32> for Rotor {
2020 fn add_assign(&mut self, other: f32) {
2021 *self = (*self).add(other);
2022 }
2023}
2024
2025impl Sub<f32> for Rotor {
2026 type Output = Rotor;
2027
2028 fn sub(self, other: f32) -> Rotor {
2029 Rotor { groups: RotorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2030 }
2031}
2032
2033impl SubAssign<f32> for Rotor {
2034 fn sub_assign(&mut self, other: f32) {
2035 *self = (*self).sub(other);
2036 }
2037}
2038
2039impl GeometricProduct<f32> for Rotor {
2040 type Output = Rotor;
2041
2042 fn geometric_product(self, other: f32) -> Rotor {
2043 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from(other) } }
2044 }
2045}
2046
2047impl OuterProduct<f32> for Rotor {
2048 type Output = Rotor;
2049
2050 fn outer_product(self, other: f32) -> Rotor {
2051 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from(other) } }
2052 }
2053}
2054
2055impl InnerProduct<f32> for Rotor {
2056 type Output = Rotor;
2057
2058 fn inner_product(self, other: f32) -> Rotor {
2059 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from(other) } }
2060 }
2061}
2062
2063impl LeftContraction<f32> for Rotor {
2064 type Output = f32;
2065
2066 fn left_contraction(self, other: f32) -> f32 {
2067 self.group0()[0] * other
2068 }
2069}
2070
2071impl RightContraction<f32> for Rotor {
2072 type Output = Rotor;
2073
2074 fn right_contraction(self, other: f32) -> Rotor {
2075 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from(other) } }
2076 }
2077}
2078
2079impl ScalarProduct<f32> for Rotor {
2080 type Output = f32;
2081
2082 fn scalar_product(self, other: f32) -> f32 {
2083 self.group0()[0] * other
2084 }
2085}
2086
2087impl Add<MultiVector> for Rotor {
2088 type Output = MultiVector;
2089
2090 fn add(self, other: MultiVector) -> MultiVector {
2091 MultiVector { groups: MultiVectorGroups { g0: self.group0() + other.group0(), g1: other.group1(), g2: other.group2(), g3: other.group3() } }
2092 }
2093}
2094
2095impl Sub<MultiVector> for Rotor {
2096 type Output = MultiVector;
2097
2098 fn sub(self, other: MultiVector) -> MultiVector {
2099 MultiVector { groups: MultiVectorGroups { g0: self.group0() - other.group0(), g1: Simd32x4::from(0.0) - other.group1(), g2: Simd32x4::from(0.0) - other.group2(), g3: Simd32x4::from(0.0) - other.group3() } }
2100 }
2101}
2102
2103impl GeometricProduct<MultiVector> for Rotor {
2104 type Output = MultiVector;
2105
2106 fn geometric_product(self, other: MultiVector) -> MultiVector {
2107 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([-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]), 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([1.0, 1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
2108 }
2109}
2110
2111impl OuterProduct<MultiVector> for Rotor {
2112 type Output = MultiVector;
2113
2114 fn outer_product(self, other: MultiVector) -> MultiVector {
2115 MultiVector { groups: MultiVectorGroups { 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group2(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group3()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group3()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group3(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2116 }
2117}
2118
2119impl InnerProduct<MultiVector> for Rotor {
2120 type Output = MultiVector;
2121
2122 fn inner_product(self, other: MultiVector) -> MultiVector {
2123 MultiVector { groups: MultiVectorGroups { 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, -1.0]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group2(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + self.group0() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2124 }
2125}
2126
2127impl LeftContraction<MultiVector> for Rotor {
2128 type Output = MultiVector;
2129
2130 fn left_contraction(self, other: MultiVector) -> MultiVector {
2131 MultiVector { groups: MultiVectorGroups { 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + self.group0() * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + self.group0() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2132 }
2133}
2134
2135impl ScalarProduct<MultiVector> for Rotor {
2136 type Output = f32;
2137
2138 fn scalar_product(self, other: MultiVector) -> f32 {
2139 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2] - self.group0()[3] * other.group0()[3]
2140 }
2141}
2142
2143impl Add<Rotor> for Rotor {
2144 type Output = Rotor;
2145
2146 fn add(self, other: Rotor) -> Rotor {
2147 Rotor { groups: RotorGroups { g0: self.group0() + other.group0() } }
2148 }
2149}
2150
2151impl AddAssign<Rotor> for Rotor {
2152 fn add_assign(&mut self, other: Rotor) {
2153 *self = (*self).add(other);
2154 }
2155}
2156
2157impl Sub<Rotor> for Rotor {
2158 type Output = Rotor;
2159
2160 fn sub(self, other: Rotor) -> Rotor {
2161 Rotor { groups: RotorGroups { g0: self.group0() - other.group0() } }
2162 }
2163}
2164
2165impl SubAssign<Rotor> for Rotor {
2166 fn sub_assign(&mut self, other: Rotor) {
2167 *self = (*self).sub(other);
2168 }
2169}
2170
2171impl Mul<Rotor> for Rotor {
2172 type Output = Rotor;
2173
2174 fn mul(self, other: Rotor) -> Rotor {
2175 Rotor { groups: RotorGroups { g0: self.group0() * other.group0() } }
2176 }
2177}
2178
2179impl MulAssign<Rotor> for Rotor {
2180 fn mul_assign(&mut self, other: Rotor) {
2181 *self = (*self).mul(other);
2182 }
2183}
2184
2185impl Div<Rotor> for Rotor {
2186 type Output = Rotor;
2187
2188 fn div(self, other: Rotor) -> Rotor {
2189 Rotor { groups: RotorGroups { 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]) } }
2190 }
2191}
2192
2193impl DivAssign<Rotor> for Rotor {
2194 fn div_assign(&mut self, other: Rotor) {
2195 *self = (*self).div(other);
2196 }
2197}
2198
2199impl GeometricProduct<Rotor> for Rotor {
2200 type Output = Rotor;
2201
2202 fn geometric_product(self, other: Rotor) -> Rotor {
2203 Rotor { groups: RotorGroups { 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]) } }
2204 }
2205}
2206
2207impl OuterProduct<Rotor> for Rotor {
2208 type Output = Rotor;
2209
2210 fn outer_product(self, other: Rotor) -> Rotor {
2211 Rotor { groups: RotorGroups { 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]) } }
2212 }
2213}
2214
2215impl InnerProduct<Rotor> for Rotor {
2216 type Output = Rotor;
2217
2218 fn inner_product(self, other: Rotor) -> Rotor {
2219 Rotor { groups: RotorGroups { 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]) } }
2220 }
2221}
2222
2223impl LeftContraction<Rotor> for Rotor {
2224 type Output = Rotor;
2225
2226 fn left_contraction(self, other: Rotor) -> Rotor {
2227 Rotor { groups: RotorGroups { 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]) } }
2228 }
2229}
2230
2231impl RightContraction<Rotor> for Rotor {
2232 type Output = Rotor;
2233
2234 fn right_contraction(self, other: Rotor) -> Rotor {
2235 Rotor { groups: RotorGroups { 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]) } }
2236 }
2237}
2238
2239impl ScalarProduct<Rotor> for Rotor {
2240 type Output = f32;
2241
2242 fn scalar_product(self, other: Rotor) -> f32 {
2243 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2] - self.group0()[3] * other.group0()[3]
2244 }
2245}
2246
2247impl GeometricProduct<Point> for Rotor {
2248 type Output = PointAndPlane;
2249
2250 fn geometric_product(self, other: Point) -> PointAndPlane {
2251 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]), g1: 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]) } }
2252 }
2253}
2254
2255impl OuterProduct<Point> for Rotor {
2256 type Output = Point;
2257
2258 fn outer_product(self, other: Point) -> Point {
2259 Point { groups: PointGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
2260 }
2261}
2262
2263impl InnerProduct<Point> for Rotor {
2264 type Output = PointAndPlane;
2265
2266 fn inner_product(self, other: Point) -> PointAndPlane {
2267 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: 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]) } }
2268 }
2269}
2270
2271impl LeftContraction<Point> for Rotor {
2272 type Output = PointAndPlane;
2273
2274 fn left_contraction(self, other: Point) -> PointAndPlane {
2275 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: 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]) } }
2276 }
2277}
2278
2279impl RegressiveProduct<IdealPoint> for Rotor {
2280 type Output = f32;
2281
2282 fn regressive_product(self, other: IdealPoint) -> f32 {
2283 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
2284 }
2285}
2286
2287impl InnerProduct<IdealPoint> for Rotor {
2288 type Output = IdealPoint;
2289
2290 fn inner_product(self, other: IdealPoint) -> IdealPoint {
2291 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2292 }
2293}
2294
2295impl LeftContraction<IdealPoint> for Rotor {
2296 type Output = IdealPoint;
2297
2298 fn left_contraction(self, other: IdealPoint) -> IdealPoint {
2299 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
2300 }
2301}
2302
2303impl GeometricProduct<Plane> for Rotor {
2304 type Output = PointAndPlane;
2305
2306 fn geometric_product(self, other: Plane) -> PointAndPlane {
2307 PointAndPlane { groups: PointAndPlaneGroups { g0: 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]), g1: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
2308 }
2309}
2310
2311impl OuterProduct<Plane> for Rotor {
2312 type Output = PointAndPlane;
2313
2314 fn outer_product(self, other: Plane) -> PointAndPlane {
2315 PointAndPlane { groups: PointAndPlaneGroups { g0: 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]), g1: Simd32x4::from(self.group0()[0]) * other.group0() } }
2316 }
2317}
2318
2319impl InnerProduct<Plane> for Rotor {
2320 type Output = Plane;
2321
2322 fn inner_product(self, other: Plane) -> Plane {
2323 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) } }
2324 }
2325}
2326
2327impl LeftContraction<Plane> for Rotor {
2328 type Output = Plane;
2329
2330 fn left_contraction(self, other: Plane) -> Plane {
2331 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
2332 }
2333}
2334
2335impl GeometricProduct<Line> for Rotor {
2336 type Output = Motor;
2337
2338 fn geometric_product(self, other: Line) -> Motor {
2339 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: 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]) } }
2340 }
2341}
2342
2343impl RegressiveProduct<Line> for Rotor {
2344 type Output = f32;
2345
2346 fn regressive_product(self, other: Line) -> f32 {
2347 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
2348 }
2349}
2350
2351impl RightContraction<Line> for Rotor {
2352 type Output = f32;
2353
2354 fn right_contraction(self, other: Line) -> f32 {
2355 0.0 - self.group0()[1] * other.group1()[0] - self.group0()[2] * other.group1()[1] - self.group0()[3] * other.group1()[2]
2356 }
2357}
2358
2359impl ScalarProduct<Line> for Rotor {
2360 type Output = f32;
2361
2362 fn scalar_product(self, other: Line) -> f32 {
2363 0.0 - self.group0()[1] * other.group1()[0] - self.group0()[2] * other.group1()[1] - self.group0()[3] * other.group1()[2]
2364 }
2365}
2366
2367impl GeometricProduct<Translator> for Rotor {
2368 type Output = Motor;
2369
2370 fn geometric_product(self, other: Translator) -> Motor {
2371 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
2372 }
2373}
2374
2375impl RegressiveProduct<Translator> for Rotor {
2376 type Output = f32;
2377
2378 fn regressive_product(self, other: Translator) -> f32 {
2379 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
2380 }
2381}
2382
2383impl OuterProduct<Translator> for Rotor {
2384 type Output = Motor;
2385
2386 fn outer_product(self, other: Translator) -> Motor {
2387 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: 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, 1, 2, 3) } }
2388 }
2389}
2390
2391impl LeftContraction<Translator> for Rotor {
2392 type Output = Translator;
2393
2394 fn left_contraction(self, other: Translator) -> Translator {
2395 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
2396 }
2397}
2398
2399impl RightContraction<Translator> for Rotor {
2400 type Output = Rotor;
2401
2402 fn right_contraction(self, other: Translator) -> Rotor {
2403 Rotor { groups: RotorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
2404 }
2405}
2406
2407impl ScalarProduct<Translator> for Rotor {
2408 type Output = f32;
2409
2410 fn scalar_product(self, other: Translator) -> f32 {
2411 self.group0()[0] * other.group0()[0]
2412 }
2413}
2414
2415impl Add<Motor> for Rotor {
2416 type Output = Motor;
2417
2418 fn add(self, other: Motor) -> Motor {
2419 Motor { groups: MotorGroups { g0: self.group0() + other.group0(), g1: other.group1() } }
2420 }
2421}
2422
2423impl Sub<Motor> for Rotor {
2424 type Output = Motor;
2425
2426 fn sub(self, other: Motor) -> Motor {
2427 Motor { groups: MotorGroups { g0: self.group0() - other.group0(), g1: Simd32x4::from(0.0) - other.group1() } }
2428 }
2429}
2430
2431impl GeometricProduct<Motor> for Rotor {
2432 type Output = Motor;
2433
2434 fn geometric_product(self, other: Motor) -> Motor {
2435 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]), 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([1.0, 1.0, -1.0, -1.0]) } }
2436 }
2437}
2438
2439impl RegressiveProduct<Motor> for Rotor {
2440 type Output = Rotor;
2441
2442 fn regressive_product(self, other: Motor) -> Rotor {
2443 Rotor { groups: RotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[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.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
2444 }
2445}
2446
2447impl OuterProduct<Motor> for Rotor {
2448 type Output = Motor;
2449
2450 fn outer_product(self, other: Motor) -> Motor {
2451 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.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]) } }
2452 }
2453}
2454
2455impl InnerProduct<Motor> for Rotor {
2456 type Output = Motor;
2457
2458 fn inner_product(self, other: Motor) -> Motor {
2459 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2460 }
2461}
2462
2463impl LeftContraction<Motor> for Rotor {
2464 type Output = Motor;
2465
2466 fn left_contraction(self, other: Motor) -> Motor {
2467 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2468 }
2469}
2470
2471impl RightContraction<Motor> for Rotor {
2472 type Output = Rotor;
2473
2474 fn right_contraction(self, other: Motor) -> Rotor {
2475 Rotor { groups: RotorGroups { 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]) } }
2476 }
2477}
2478
2479impl ScalarProduct<Motor> for Rotor {
2480 type Output = f32;
2481
2482 fn scalar_product(self, other: Motor) -> f32 {
2483 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2] - self.group0()[3] * other.group0()[3]
2484 }
2485}
2486
2487impl GeometricProduct<PointAndPlane> for Rotor {
2488 type Output = PointAndPlane;
2489
2490 fn geometric_product(self, other: PointAndPlane) -> PointAndPlane {
2491 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
2492 }
2493}
2494
2495impl OuterProduct<PointAndPlane> for Rotor {
2496 type Output = PointAndPlane;
2497
2498 fn outer_product(self, other: PointAndPlane) -> PointAndPlane {
2499 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, -1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() } }
2500 }
2501}
2502
2503impl InnerProduct<PointAndPlane> for Rotor {
2504 type Output = PointAndPlane;
2505
2506 fn inner_product(self, other: PointAndPlane) -> PointAndPlane {
2507 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
2508 }
2509}
2510
2511impl LeftContraction<PointAndPlane> for Rotor {
2512 type Output = PointAndPlane;
2513
2514 fn left_contraction(self, other: PointAndPlane) -> PointAndPlane {
2515 PointAndPlane { groups: PointAndPlaneGroups { 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, 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]) } }
2516 }
2517}
2518
2519impl SquaredMagnitude for Rotor {
2520 type Output = f32;
2521
2522 fn squared_magnitude(self) -> f32 {
2523 self.scalar_product(self.reversal())
2524 }
2525}
2526
2527impl Magnitude for Rotor {
2528 type Output = f32;
2529
2530 fn magnitude(self) -> f32 {
2531 self.squared_magnitude().sqrt()
2532 }
2533}
2534
2535impl Mul<f32> for Rotor {
2536 type Output = Rotor;
2537
2538 fn mul(self, other: f32) -> Rotor {
2539 self.geometric_product(other)
2540 }
2541}
2542
2543impl MulAssign<f32> for Rotor {
2544 fn mul_assign(&mut self, other: f32) {
2545 *self = (*self).mul(other);
2546 }
2547}
2548
2549impl Signum for Rotor {
2550 type Output = Rotor;
2551
2552 fn signum(self) -> Rotor {
2553 self.geometric_product(1.0 / self.magnitude())
2554 }
2555}
2556
2557impl Inverse for Rotor {
2558 type Output = Rotor;
2559
2560 fn inverse(self) -> Rotor {
2561 self.reversal().geometric_product(1.0 / self.squared_magnitude())
2562 }
2563}
2564
2565impl Zero for Point {
2566 fn zero() -> Self {
2567 Point { groups: PointGroups { g0: Simd32x4::from(0.0) } }
2568 }
2569}
2570
2571impl One for Point {
2572 fn one() -> Self {
2573 Point { groups: PointGroups { g0: Simd32x4::from(0.0) } }
2574 }
2575}
2576
2577impl Neg for Point {
2578 type Output = Point;
2579
2580 fn neg(self) -> Point {
2581 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
2582 }
2583}
2584
2585impl Automorphism for Point {
2586 type Output = Point;
2587
2588 fn automorphism(self) -> Point {
2589 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
2590 }
2591}
2592
2593impl Reversal for Point {
2594 type Output = Point;
2595
2596 fn reversal(self) -> Point {
2597 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
2598 }
2599}
2600
2601impl Conjugation for Point {
2602 type Output = Point;
2603
2604 fn conjugation(self) -> Point {
2605 Point { groups: PointGroups { g0: self.group0() } }
2606 }
2607}
2608
2609impl Dual for Point {
2610 type Output = Plane;
2611
2612 fn dual(self) -> Plane {
2613 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
2614 }
2615}
2616
2617impl GeometricProduct<f32> for Point {
2618 type Output = Point;
2619
2620 fn geometric_product(self, other: f32) -> Point {
2621 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other) } }
2622 }
2623}
2624
2625impl OuterProduct<f32> for Point {
2626 type Output = Point;
2627
2628 fn outer_product(self, other: f32) -> Point {
2629 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other) } }
2630 }
2631}
2632
2633impl InnerProduct<f32> for Point {
2634 type Output = Point;
2635
2636 fn inner_product(self, other: f32) -> Point {
2637 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other) } }
2638 }
2639}
2640
2641impl RightContraction<f32> for Point {
2642 type Output = Point;
2643
2644 fn right_contraction(self, other: f32) -> Point {
2645 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other) } }
2646 }
2647}
2648
2649impl Add<MultiVector> for Point {
2650 type Output = MultiVector;
2651
2652 fn add(self, other: MultiVector) -> MultiVector {
2653 MultiVector { groups: MultiVectorGroups { g0: other.group0(), g1: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group1(), g2: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group2(), g3: other.group3() } }
2654 }
2655}
2656
2657impl Sub<MultiVector> for Point {
2658 type Output = MultiVector;
2659
2660 fn sub(self, other: MultiVector) -> MultiVector {
2661 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group1(), g2: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group2(), g3: Simd32x4::from(0.0) - other.group3() } }
2662 }
2663}
2664
2665impl GeometricProduct<MultiVector> for Point {
2666 type Output = MultiVector;
2667
2668 fn geometric_product(self, other: MultiVector) -> MultiVector {
2669 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + 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([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group3() + 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]), g2: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g3: Simd32x4::from(0.0) - Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) } }
2670 }
2671}
2672
2673impl ScalarProduct<MultiVector> for Point {
2674 type Output = f32;
2675
2676 fn scalar_product(self, other: MultiVector) -> f32 {
2677 0.0 - self.group0()[0] * other.group2()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2] + self.group0()[3] * other.group1()[3]
2678 }
2679}
2680
2681impl GeometricProduct<Rotor> for Point {
2682 type Output = PointAndPlane;
2683
2684 fn geometric_product(self, other: Rotor) -> PointAndPlane {
2685 PointAndPlane { groups: PointAndPlaneGroups { g0: 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([1.0, 1.0, 1.0, -1.0]), g1: 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, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
2686 }
2687}
2688
2689impl OuterProduct<Rotor> for Point {
2690 type Output = Point;
2691
2692 fn outer_product(self, other: Rotor) -> Point {
2693 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
2694 }
2695}
2696
2697impl InnerProduct<Rotor> for Point {
2698 type Output = PointAndPlane;
2699
2700 fn inner_product(self, other: Rotor) -> PointAndPlane {
2701 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: 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, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
2702 }
2703}
2704
2705impl RightContraction<Rotor> for Point {
2706 type Output = PointAndPlane;
2707
2708 fn right_contraction(self, other: Rotor) -> PointAndPlane {
2709 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: 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, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
2710 }
2711}
2712
2713impl Add<Point> for Point {
2714 type Output = Point;
2715
2716 fn add(self, other: Point) -> Point {
2717 Point { groups: PointGroups { g0: self.group0() + other.group0() } }
2718 }
2719}
2720
2721impl AddAssign<Point> for Point {
2722 fn add_assign(&mut self, other: Point) {
2723 *self = (*self).add(other);
2724 }
2725}
2726
2727impl Sub<Point> for Point {
2728 type Output = Point;
2729
2730 fn sub(self, other: Point) -> Point {
2731 Point { groups: PointGroups { g0: self.group0() - other.group0() } }
2732 }
2733}
2734
2735impl SubAssign<Point> for Point {
2736 fn sub_assign(&mut self, other: Point) {
2737 *self = (*self).sub(other);
2738 }
2739}
2740
2741impl Mul<Point> for Point {
2742 type Output = Point;
2743
2744 fn mul(self, other: Point) -> Point {
2745 Point { groups: PointGroups { g0: self.group0() * other.group0() } }
2746 }
2747}
2748
2749impl MulAssign<Point> for Point {
2750 fn mul_assign(&mut self, other: Point) {
2751 *self = (*self).mul(other);
2752 }
2753}
2754
2755impl Div<Point> for Point {
2756 type Output = Point;
2757
2758 fn div(self, other: Point) -> Point {
2759 Point { groups: PointGroups { 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]) } }
2760 }
2761}
2762
2763impl DivAssign<Point> for Point {
2764 fn div_assign(&mut self, other: Point) {
2765 *self = (*self).div(other);
2766 }
2767}
2768
2769impl RegressiveProduct<Point> for Point {
2770 type Output = Line;
2771
2772 fn regressive_product(self, other: Point) -> Line {
2773 Line { groups: LineGroups { 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]), g1: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from(-1.0) } }
2774 }
2775}
2776
2777impl InnerProduct<Point> for Point {
2778 type Output = f32;
2779
2780 fn inner_product(self, other: Point) -> f32 {
2781 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]
2782 }
2783}
2784
2785impl LeftContraction<Point> for Point {
2786 type Output = f32;
2787
2788 fn left_contraction(self, other: Point) -> f32 {
2789 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]
2790 }
2791}
2792
2793impl RightContraction<Point> for Point {
2794 type Output = f32;
2795
2796 fn right_contraction(self, other: Point) -> f32 {
2797 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]
2798 }
2799}
2800
2801impl ScalarProduct<Point> for Point {
2802 type Output = f32;
2803
2804 fn scalar_product(self, other: Point) -> f32 {
2805 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]
2806 }
2807}
2808
2809impl RegressiveProduct<IdealPoint> for Point {
2810 type Output = Plane;
2811
2812 fn regressive_product(self, other: IdealPoint) -> Plane {
2813 Plane { groups: PlaneGroups { 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]) } }
2814 }
2815}
2816
2817impl Add<Plane> for Point {
2818 type Output = PointAndPlane;
2819
2820 fn add(self, other: Plane) -> PointAndPlane {
2821 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0(), g1: other.group0() } }
2822 }
2823}
2824
2825impl Sub<Plane> for Point {
2826 type Output = PointAndPlane;
2827
2828 fn sub(self, other: Plane) -> PointAndPlane {
2829 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0(), g1: Simd32x4::from(0.0) - other.group0() } }
2830 }
2831}
2832
2833impl RegressiveProduct<Plane> for Point {
2834 type Output = f32;
2835
2836 fn regressive_product(self, other: Plane) -> f32 {
2837 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]
2838 }
2839}
2840
2841impl InnerProduct<Plane> for Point {
2842 type Output = Line;
2843
2844 fn inner_product(self, other: Plane) -> Line {
2845 Line { groups: LineGroups { 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]), g1: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x3::from(other.group0()[0]) } }
2846 }
2847}
2848
2849impl RightContraction<Plane> for Point {
2850 type Output = Line;
2851
2852 fn right_contraction(self, other: Plane) -> Line {
2853 Line { groups: LineGroups { 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]), g1: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x3::from(other.group0()[0]) } }
2854 }
2855}
2856
2857impl GeometricProduct<Line> for Point {
2858 type Output = PointAndPlane;
2859
2860 fn geometric_product(self, other: Line) -> PointAndPlane {
2861 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[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]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2862 }
2863}
2864
2865impl RegressiveProduct<Line> for Point {
2866 type Output = Plane;
2867
2868 fn regressive_product(self, other: Line) -> Plane {
2869 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[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]) } }
2870 }
2871}
2872
2873impl InnerProduct<Line> for Point {
2874 type Output = Plane;
2875
2876 fn inner_product(self, other: Line) -> Plane {
2877 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2878 }
2879}
2880
2881impl RightContraction<Line> for Point {
2882 type Output = Plane;
2883
2884 fn right_contraction(self, other: Line) -> Plane {
2885 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2886 }
2887}
2888
2889impl RegressiveProduct<Translator> for Point {
2890 type Output = Plane;
2891
2892 fn regressive_product(self, other: Translator) -> Plane {
2893 Plane { groups: PlaneGroups { 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()[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, 1, 2, 3) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
2894 }
2895}
2896
2897impl OuterProduct<Translator> for Point {
2898 type Output = Point;
2899
2900 fn outer_product(self, other: Translator) -> Point {
2901 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
2902 }
2903}
2904
2905impl GeometricProduct<Motor> for Point {
2906 type Output = PointAndPlane;
2907
2908 fn geometric_product(self, other: Motor) -> PointAndPlane {
2909 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group1()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
2910 }
2911}
2912
2913impl RegressiveProduct<Motor> for Point {
2914 type Output = PointAndPlane;
2915
2916 fn regressive_product(self, other: Motor) -> PointAndPlane {
2917 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group1()[0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[1], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[2], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * other.group1() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
2918 }
2919}
2920
2921impl OuterProduct<Motor> for Point {
2922 type Output = Point;
2923
2924 fn outer_product(self, other: Motor) -> Point {
2925 Point { groups: PointGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
2926 }
2927}
2928
2929impl InnerProduct<Motor> for Point {
2930 type Output = PointAndPlane;
2931
2932 fn inner_product(self, other: Motor) -> PointAndPlane {
2933 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group1()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
2934 }
2935}
2936
2937impl LeftContraction<Motor> for Point {
2938 type Output = Plane;
2939
2940 fn left_contraction(self, other: Motor) -> Plane {
2941 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
2942 }
2943}
2944
2945impl RightContraction<Motor> for Point {
2946 type Output = PointAndPlane;
2947
2948 fn right_contraction(self, other: Motor) -> PointAndPlane {
2949 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[2], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[3]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
2950 }
2951}
2952
2953impl Add<PointAndPlane> for Point {
2954 type Output = PointAndPlane;
2955
2956 fn add(self, other: PointAndPlane) -> PointAndPlane {
2957 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() + other.group0(), g1: other.group1() } }
2958 }
2959}
2960
2961impl Sub<PointAndPlane> for Point {
2962 type Output = PointAndPlane;
2963
2964 fn sub(self, other: PointAndPlane) -> PointAndPlane {
2965 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() - other.group0(), g1: Simd32x4::from(0.0) - other.group1() } }
2966 }
2967}
2968
2969impl GeometricProduct<PointAndPlane> for Point {
2970 type Output = Motor;
2971
2972 fn geometric_product(self, other: PointAndPlane) -> Motor {
2973 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(0.0) - Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) } }
2974 }
2975}
2976
2977impl LeftContraction<PointAndPlane> for Point {
2978 type Output = f32;
2979
2980 fn left_contraction(self, other: PointAndPlane) -> f32 {
2981 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]
2982 }
2983}
2984
2985impl ScalarProduct<PointAndPlane> for Point {
2986 type Output = f32;
2987
2988 fn scalar_product(self, other: PointAndPlane) -> f32 {
2989 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]
2990 }
2991}
2992
2993impl SquaredMagnitude for Point {
2994 type Output = f32;
2995
2996 fn squared_magnitude(self) -> f32 {
2997 self.scalar_product(self.reversal())
2998 }
2999}
3000
3001impl Magnitude for Point {
3002 type Output = f32;
3003
3004 fn magnitude(self) -> f32 {
3005 self.squared_magnitude().sqrt()
3006 }
3007}
3008
3009impl Mul<f32> for Point {
3010 type Output = Point;
3011
3012 fn mul(self, other: f32) -> Point {
3013 self.geometric_product(other)
3014 }
3015}
3016
3017impl MulAssign<f32> for Point {
3018 fn mul_assign(&mut self, other: f32) {
3019 *self = (*self).mul(other);
3020 }
3021}
3022
3023impl Signum for Point {
3024 type Output = Point;
3025
3026 fn signum(self) -> Point {
3027 self.geometric_product(1.0 / self.magnitude())
3028 }
3029}
3030
3031impl Inverse for Point {
3032 type Output = Point;
3033
3034 fn inverse(self) -> Point {
3035 self.reversal().geometric_product(1.0 / self.squared_magnitude())
3036 }
3037}
3038
3039impl Zero for IdealPoint {
3040 fn zero() -> Self {
3041 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(0.0) } }
3042 }
3043}
3044
3045impl One for IdealPoint {
3046 fn one() -> Self {
3047 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(0.0) } }
3048 }
3049}
3050
3051impl Neg for IdealPoint {
3052 type Output = IdealPoint;
3053
3054 fn neg(self) -> IdealPoint {
3055 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3056 }
3057}
3058
3059impl Automorphism for IdealPoint {
3060 type Output = IdealPoint;
3061
3062 fn automorphism(self) -> IdealPoint {
3063 IdealPoint { groups: IdealPointGroups { g0: self.group0() } }
3064 }
3065}
3066
3067impl Reversal for IdealPoint {
3068 type Output = IdealPoint;
3069
3070 fn reversal(self) -> IdealPoint {
3071 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3072 }
3073}
3074
3075impl Conjugation for IdealPoint {
3076 type Output = IdealPoint;
3077
3078 fn conjugation(self) -> IdealPoint {
3079 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(-1.0) } }
3080 }
3081}
3082
3083impl Add<f32> for IdealPoint {
3084 type Output = Translator;
3085
3086 fn add(self, other: f32) -> Translator {
3087 Translator { groups: TranslatorGroups { 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]) } }
3088 }
3089}
3090
3091impl Sub<f32> for IdealPoint {
3092 type Output = Translator;
3093
3094 fn sub(self, other: f32) -> Translator {
3095 Translator { groups: TranslatorGroups { 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]) } }
3096 }
3097}
3098
3099impl GeometricProduct<f32> for IdealPoint {
3100 type Output = IdealPoint;
3101
3102 fn geometric_product(self, other: f32) -> IdealPoint {
3103 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other) } }
3104 }
3105}
3106
3107impl OuterProduct<f32> for IdealPoint {
3108 type Output = IdealPoint;
3109
3110 fn outer_product(self, other: f32) -> IdealPoint {
3111 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other) } }
3112 }
3113}
3114
3115impl InnerProduct<f32> for IdealPoint {
3116 type Output = IdealPoint;
3117
3118 fn inner_product(self, other: f32) -> IdealPoint {
3119 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other) } }
3120 }
3121}
3122
3123impl RightContraction<f32> for IdealPoint {
3124 type Output = IdealPoint;
3125
3126 fn right_contraction(self, other: f32) -> IdealPoint {
3127 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other) } }
3128 }
3129}
3130
3131impl Add<MultiVector> for IdealPoint {
3132 type Output = MultiVector;
3133
3134 fn add(self, other: MultiVector) -> MultiVector {
3135 MultiVector { groups: MultiVectorGroups { g0: other.group0(), g1: other.group1(), g2: other.group2(), g3: 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.group3() } }
3136 }
3137}
3138
3139impl Sub<MultiVector> for IdealPoint {
3140 type Output = MultiVector;
3141
3142 fn sub(self, other: MultiVector) -> MultiVector {
3143 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: Simd32x4::from(0.0) - other.group1(), g2: Simd32x4::from(0.0) - other.group2(), g3: 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.group3() } }
3144 }
3145}
3146
3147impl GeometricProduct<MultiVector> for IdealPoint {
3148 type Output = MultiVector;
3149
3150 fn geometric_product(self, other: MultiVector) -> MultiVector {
3151 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g2: 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.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]), g3: 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]) } }
3152 }
3153}
3154
3155impl ScalarProduct<MultiVector> for IdealPoint {
3156 type Output = f32;
3157
3158 fn scalar_product(self, other: MultiVector) -> f32 {
3159 self.group0()[0] * other.group3()[1] + self.group0()[1] * other.group3()[2] + self.group0()[2] * other.group3()[3]
3160 }
3161}
3162
3163impl RegressiveProduct<Rotor> for IdealPoint {
3164 type Output = f32;
3165
3166 fn regressive_product(self, other: Rotor) -> f32 {
3167 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
3168 }
3169}
3170
3171impl InnerProduct<Rotor> for IdealPoint {
3172 type Output = IdealPoint;
3173
3174 fn inner_product(self, other: Rotor) -> IdealPoint {
3175 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3176 }
3177}
3178
3179impl RightContraction<Rotor> for IdealPoint {
3180 type Output = IdealPoint;
3181
3182 fn right_contraction(self, other: Rotor) -> IdealPoint {
3183 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3184 }
3185}
3186
3187impl RegressiveProduct<Point> for IdealPoint {
3188 type Output = Plane;
3189
3190 fn regressive_product(self, other: Point) -> Plane {
3191 Plane { groups: PlaneGroups { 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]) } }
3192 }
3193}
3194
3195impl Add<IdealPoint> for IdealPoint {
3196 type Output = IdealPoint;
3197
3198 fn add(self, other: IdealPoint) -> IdealPoint {
3199 IdealPoint { groups: IdealPointGroups { g0: self.group0() + other.group0() } }
3200 }
3201}
3202
3203impl AddAssign<IdealPoint> for IdealPoint {
3204 fn add_assign(&mut self, other: IdealPoint) {
3205 *self = (*self).add(other);
3206 }
3207}
3208
3209impl Sub<IdealPoint> for IdealPoint {
3210 type Output = IdealPoint;
3211
3212 fn sub(self, other: IdealPoint) -> IdealPoint {
3213 IdealPoint { groups: IdealPointGroups { g0: self.group0() - other.group0() } }
3214 }
3215}
3216
3217impl SubAssign<IdealPoint> for IdealPoint {
3218 fn sub_assign(&mut self, other: IdealPoint) {
3219 *self = (*self).sub(other);
3220 }
3221}
3222
3223impl Mul<IdealPoint> for IdealPoint {
3224 type Output = IdealPoint;
3225
3226 fn mul(self, other: IdealPoint) -> IdealPoint {
3227 IdealPoint { groups: IdealPointGroups { g0: self.group0() * other.group0() } }
3228 }
3229}
3230
3231impl MulAssign<IdealPoint> for IdealPoint {
3232 fn mul_assign(&mut self, other: IdealPoint) {
3233 *self = (*self).mul(other);
3234 }
3235}
3236
3237impl Div<IdealPoint> for IdealPoint {
3238 type Output = IdealPoint;
3239
3240 fn div(self, other: IdealPoint) -> IdealPoint {
3241 IdealPoint { groups: IdealPointGroups { 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]) } }
3242 }
3243}
3244
3245impl DivAssign<IdealPoint> for IdealPoint {
3246 fn div_assign(&mut self, other: IdealPoint) {
3247 *self = (*self).div(other);
3248 }
3249}
3250
3251impl GeometricProduct<IdealPoint> for IdealPoint {
3252 type Output = Rotor;
3253
3254 fn geometric_product(self, other: IdealPoint) -> Rotor {
3255 Rotor { groups: RotorGroups { 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]) } }
3256 }
3257}
3258
3259impl InnerProduct<IdealPoint> for IdealPoint {
3260 type Output = f32;
3261
3262 fn inner_product(self, other: IdealPoint) -> f32 {
3263 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3264 }
3265}
3266
3267impl LeftContraction<IdealPoint> for IdealPoint {
3268 type Output = f32;
3269
3270 fn left_contraction(self, other: IdealPoint) -> f32 {
3271 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3272 }
3273}
3274
3275impl RightContraction<IdealPoint> for IdealPoint {
3276 type Output = f32;
3277
3278 fn right_contraction(self, other: IdealPoint) -> f32 {
3279 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3280 }
3281}
3282
3283impl ScalarProduct<IdealPoint> for IdealPoint {
3284 type Output = f32;
3285
3286 fn scalar_product(self, other: IdealPoint) -> f32 {
3287 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3288 }
3289}
3290
3291impl InnerProduct<Plane> for IdealPoint {
3292 type Output = Plane;
3293
3294 fn inner_product(self, other: Plane) -> Plane {
3295 Plane { groups: PlaneGroups { 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]) } }
3296 }
3297}
3298
3299impl RightContraction<Plane> for IdealPoint {
3300 type Output = Plane;
3301
3302 fn right_contraction(self, other: Plane) -> Plane {
3303 Plane { groups: PlaneGroups { 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]) } }
3304 }
3305}
3306
3307impl Add<Line> for IdealPoint {
3308 type Output = Line;
3309
3310 fn add(self, other: Line) -> Line {
3311 Line { groups: LineGroups { g0: self.group0() + other.group0(), g1: other.group1() } }
3312 }
3313}
3314
3315impl Sub<Line> for IdealPoint {
3316 type Output = Line;
3317
3318 fn sub(self, other: Line) -> Line {
3319 Line { groups: LineGroups { g0: self.group0() - other.group0(), g1: Simd32x3::from(0.0) - other.group1() } }
3320 }
3321}
3322
3323impl GeometricProduct<Line> for IdealPoint {
3324 type Output = Motor;
3325
3326 fn geometric_product(self, other: Line) -> Motor {
3327 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]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) } }
3328 }
3329}
3330
3331impl RegressiveProduct<Line> for IdealPoint {
3332 type Output = f32;
3333
3334 fn regressive_product(self, other: Line) -> f32 {
3335 self.group0()[0] * other.group1()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2]
3336 }
3337}
3338
3339impl InnerProduct<Line> for IdealPoint {
3340 type Output = f32;
3341
3342 fn inner_product(self, other: Line) -> f32 {
3343 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3344 }
3345}
3346
3347impl LeftContraction<Line> for IdealPoint {
3348 type Output = f32;
3349
3350 fn left_contraction(self, other: Line) -> f32 {
3351 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3352 }
3353}
3354
3355impl RightContraction<Line> for IdealPoint {
3356 type Output = f32;
3357
3358 fn right_contraction(self, other: Line) -> f32 {
3359 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3360 }
3361}
3362
3363impl ScalarProduct<Line> for IdealPoint {
3364 type Output = f32;
3365
3366 fn scalar_product(self, other: Line) -> f32 {
3367 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
3368 }
3369}
3370
3371impl Add<Translator> for IdealPoint {
3372 type Output = Translator;
3373
3374 fn add(self, other: Translator) -> Translator {
3375 Translator { groups: TranslatorGroups { 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() } }
3376 }
3377}
3378
3379impl Sub<Translator> for IdealPoint {
3380 type Output = Translator;
3381
3382 fn sub(self, other: Translator) -> Translator {
3383 Translator { groups: TranslatorGroups { 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() } }
3384 }
3385}
3386
3387impl OuterProduct<Translator> for IdealPoint {
3388 type Output = IdealPoint;
3389
3390 fn outer_product(self, other: Translator) -> IdealPoint {
3391 IdealPoint { groups: IdealPointGroups { g0: self.group0() * Simd32x3::from(other.group0()[0]) } }
3392 }
3393}
3394
3395impl InnerProduct<Translator> for IdealPoint {
3396 type Output = Translator;
3397
3398 fn inner_product(self, other: Translator) -> Translator {
3399 Translator { groups: TranslatorGroups { 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]) } }
3400 }
3401}
3402
3403impl LeftContraction<Translator> for IdealPoint {
3404 type Output = f32;
3405
3406 fn left_contraction(self, other: Translator) -> f32 {
3407 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
3408 }
3409}
3410
3411impl RightContraction<Translator> for IdealPoint {
3412 type Output = Translator;
3413
3414 fn right_contraction(self, other: Translator) -> Translator {
3415 Translator { groups: TranslatorGroups { 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]) } }
3416 }
3417}
3418
3419impl ScalarProduct<Translator> for IdealPoint {
3420 type Output = f32;
3421
3422 fn scalar_product(self, other: Translator) -> f32 {
3423 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
3424 }
3425}
3426
3427impl Add<Motor> for IdealPoint {
3428 type Output = Motor;
3429
3430 fn add(self, other: Motor) -> Motor {
3431 Motor { groups: MotorGroups { g0: other.group0(), g1: 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.group1() } }
3432 }
3433}
3434
3435impl Sub<Motor> for IdealPoint {
3436 type Output = Motor;
3437
3438 fn sub(self, other: Motor) -> Motor {
3439 Motor { groups: MotorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: 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.group1() } }
3440 }
3441}
3442
3443impl GeometricProduct<Motor> for IdealPoint {
3444 type Output = Motor;
3445
3446 fn geometric_product(self, other: Motor) -> Motor {
3447 Motor { groups: MotorGroups { 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]) * 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.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]) } }
3448 }
3449}
3450
3451impl RegressiveProduct<Motor> for IdealPoint {
3452 type Output = Translator;
3453
3454 fn regressive_product(self, other: Motor) -> Translator {
3455 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group1()[0], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[3], other.group0()[3], other.group0()[3], other.group1()[0]]) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[0], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
3456 }
3457}
3458
3459impl LeftContraction<Motor> for IdealPoint {
3460 type Output = Rotor;
3461
3462 fn left_contraction(self, other: Motor) -> Rotor {
3463 Rotor { groups: RotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 0) * 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, 1.0, 0.0, 0.0]) } }
3464 }
3465}
3466
3467impl RightContraction<Motor> for IdealPoint {
3468 type Output = Translator;
3469
3470 fn right_contraction(self, other: Motor) -> Translator {
3471 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[2], other.group1()[2], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[3], other.group1()[3], other.group1()[3], other.group0()[0]]) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[0], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
3472 }
3473}
3474
3475impl ScalarProduct<Motor> for IdealPoint {
3476 type Output = f32;
3477
3478 fn scalar_product(self, other: Motor) -> f32 {
3479 self.group0()[0] * other.group1()[1] + self.group0()[1] * other.group1()[2] + self.group0()[2] * other.group1()[3]
3480 }
3481}
3482
3483impl GeometricProduct<PointAndPlane> for IdealPoint {
3484 type Output = PointAndPlane;
3485
3486 fn geometric_product(self, other: PointAndPlane) -> PointAndPlane {
3487 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
3488 }
3489}
3490
3491impl RegressiveProduct<PointAndPlane> for IdealPoint {
3492 type Output = Plane;
3493
3494 fn regressive_product(self, other: PointAndPlane) -> Plane {
3495 Plane { groups: PlaneGroups { 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]) } }
3496 }
3497}
3498
3499impl InnerProduct<PointAndPlane> for IdealPoint {
3500 type Output = Plane;
3501
3502 fn inner_product(self, other: PointAndPlane) -> Plane {
3503 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
3504 }
3505}
3506
3507impl RightContraction<PointAndPlane> for IdealPoint {
3508 type Output = Plane;
3509
3510 fn right_contraction(self, other: PointAndPlane) -> Plane {
3511 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 0) * 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, 1.0, 0.0, 0.0]) } }
3512 }
3513}
3514
3515impl SquaredMagnitude for IdealPoint {
3516 type Output = f32;
3517
3518 fn squared_magnitude(self) -> f32 {
3519 self.scalar_product(self.reversal())
3520 }
3521}
3522
3523impl Magnitude for IdealPoint {
3524 type Output = f32;
3525
3526 fn magnitude(self) -> f32 {
3527 self.squared_magnitude().sqrt()
3528 }
3529}
3530
3531impl Mul<f32> for IdealPoint {
3532 type Output = IdealPoint;
3533
3534 fn mul(self, other: f32) -> IdealPoint {
3535 self.geometric_product(other)
3536 }
3537}
3538
3539impl MulAssign<f32> for IdealPoint {
3540 fn mul_assign(&mut self, other: f32) {
3541 *self = (*self).mul(other);
3542 }
3543}
3544
3545impl Signum for IdealPoint {
3546 type Output = IdealPoint;
3547
3548 fn signum(self) -> IdealPoint {
3549 self.geometric_product(1.0 / self.magnitude())
3550 }
3551}
3552
3553impl Inverse for IdealPoint {
3554 type Output = IdealPoint;
3555
3556 fn inverse(self) -> IdealPoint {
3557 self.reversal().geometric_product(1.0 / self.squared_magnitude())
3558 }
3559}
3560
3561impl Zero for Plane {
3562 fn zero() -> Self {
3563 Plane { groups: PlaneGroups { g0: Simd32x4::from(0.0) } }
3564 }
3565}
3566
3567impl One for Plane {
3568 fn one() -> Self {
3569 Plane { groups: PlaneGroups { g0: Simd32x4::from(0.0) } }
3570 }
3571}
3572
3573impl Neg for Plane {
3574 type Output = Plane;
3575
3576 fn neg(self) -> Plane {
3577 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
3578 }
3579}
3580
3581impl Automorphism for Plane {
3582 type Output = Plane;
3583
3584 fn automorphism(self) -> Plane {
3585 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
3586 }
3587}
3588
3589impl Reversal for Plane {
3590 type Output = Plane;
3591
3592 fn reversal(self) -> Plane {
3593 Plane { groups: PlaneGroups { g0: self.group0() } }
3594 }
3595}
3596
3597impl Conjugation for Plane {
3598 type Output = Plane;
3599
3600 fn conjugation(self) -> Plane {
3601 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
3602 }
3603}
3604
3605impl Dual for Plane {
3606 type Output = Point;
3607
3608 fn dual(self) -> Point {
3609 Point { groups: PointGroups { g0: self.group0() } }
3610 }
3611}
3612
3613impl GeometricProduct<f32> for Plane {
3614 type Output = Plane;
3615
3616 fn geometric_product(self, other: f32) -> Plane {
3617 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other) } }
3618 }
3619}
3620
3621impl OuterProduct<f32> for Plane {
3622 type Output = Plane;
3623
3624 fn outer_product(self, other: f32) -> Plane {
3625 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other) } }
3626 }
3627}
3628
3629impl InnerProduct<f32> for Plane {
3630 type Output = Plane;
3631
3632 fn inner_product(self, other: f32) -> Plane {
3633 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other) } }
3634 }
3635}
3636
3637impl RightContraction<f32> for Plane {
3638 type Output = Plane;
3639
3640 fn right_contraction(self, other: f32) -> Plane {
3641 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other) } }
3642 }
3643}
3644
3645impl Add<MultiVector> for Plane {
3646 type Output = MultiVector;
3647
3648 fn add(self, other: MultiVector) -> MultiVector {
3649 MultiVector { groups: MultiVectorGroups { g0: other.group0(), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group1(), g2: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group2(), g3: other.group3() } }
3650 }
3651}
3652
3653impl Sub<MultiVector> for Plane {
3654 type Output = MultiVector;
3655
3656 fn sub(self, other: MultiVector) -> MultiVector {
3657 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group1(), g2: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group2(), g3: Simd32x4::from(0.0) - other.group3() } }
3658 }
3659}
3660
3661impl GeometricProduct<MultiVector> for Plane {
3662 type Output = MultiVector;
3663
3664 fn geometric_product(self, other: MultiVector) -> MultiVector {
3665 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.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), 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.group3(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]), g2: Simd32x4::from(0.0) - Simd32x4::from(self.group0()[0]) * other.group3() + 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]), g3: Simd32x4::from(self.group0()[0]) * other.group2() + 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([1.0, 1.0, -1.0, -1.0]) } }
3666 }
3667}
3668
3669impl ScalarProduct<MultiVector> for Plane {
3670 type Output = f32;
3671
3672 fn scalar_product(self, other: MultiVector) -> f32 {
3673 0.0 - self.group0()[0] * other.group1()[0] + self.group0()[1] * other.group2()[1] + self.group0()[2] * other.group2()[2] + self.group0()[3] * other.group2()[3]
3674 }
3675}
3676
3677impl GeometricProduct<Rotor> for Plane {
3678 type Output = PointAndPlane;
3679
3680 fn geometric_product(self, other: Rotor) -> PointAndPlane {
3681 PointAndPlane { groups: PointAndPlaneGroups { 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()[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, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: 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([1.0, 1.0, 1.0, -1.0]) } }
3682 }
3683}
3684
3685impl OuterProduct<Rotor> for Plane {
3686 type Output = PointAndPlane;
3687
3688 fn outer_product(self, other: Rotor) -> PointAndPlane {
3689 PointAndPlane { groups: PointAndPlaneGroups { 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()[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, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: self.group0() * Simd32x4::from(other.group0()[0]) } }
3690 }
3691}
3692
3693impl InnerProduct<Rotor> for Plane {
3694 type Output = Plane;
3695
3696 fn inner_product(self, other: Rotor) -> Plane {
3697 Plane { groups: PlaneGroups { g0: 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([1.0, 1.0, 1.0, -1.0]) } }
3698 }
3699}
3700
3701impl RightContraction<Rotor> for Plane {
3702 type Output = Plane;
3703
3704 fn right_contraction(self, other: Rotor) -> Plane {
3705 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
3706 }
3707}
3708
3709impl Add<Point> for Plane {
3710 type Output = PointAndPlane;
3711
3712 fn add(self, other: Point) -> PointAndPlane {
3713 PointAndPlane { groups: PointAndPlaneGroups { g0: other.group0(), g1: self.group0() } }
3714 }
3715}
3716
3717impl Sub<Point> for Plane {
3718 type Output = PointAndPlane;
3719
3720 fn sub(self, other: Point) -> PointAndPlane {
3721 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: self.group0() } }
3722 }
3723}
3724
3725impl RegressiveProduct<Point> for Plane {
3726 type Output = f32;
3727
3728 fn regressive_product(self, other: Point) -> f32 {
3729 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
3730 }
3731}
3732
3733impl InnerProduct<Point> for Plane {
3734 type Output = Line;
3735
3736 fn inner_product(self, other: Point) -> Line {
3737 Line { groups: LineGroups { 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]), g1: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x3::from(other.group0()[0]) } }
3738 }
3739}
3740
3741impl LeftContraction<Point> for Plane {
3742 type Output = Line;
3743
3744 fn left_contraction(self, other: Point) -> Line {
3745 Line { groups: LineGroups { 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]), g1: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x3::from(other.group0()[0]) } }
3746 }
3747}
3748
3749impl InnerProduct<IdealPoint> for Plane {
3750 type Output = Plane;
3751
3752 fn inner_product(self, other: IdealPoint) -> Plane {
3753 Plane { groups: PlaneGroups { 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) } }
3754 }
3755}
3756
3757impl LeftContraction<IdealPoint> for Plane {
3758 type Output = Plane;
3759
3760 fn left_contraction(self, other: IdealPoint) -> Plane {
3761 Plane { groups: PlaneGroups { 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) } }
3762 }
3763}
3764
3765impl Add<Plane> for Plane {
3766 type Output = Plane;
3767
3768 fn add(self, other: Plane) -> Plane {
3769 Plane { groups: PlaneGroups { g0: self.group0() + other.group0() } }
3770 }
3771}
3772
3773impl AddAssign<Plane> for Plane {
3774 fn add_assign(&mut self, other: Plane) {
3775 *self = (*self).add(other);
3776 }
3777}
3778
3779impl Sub<Plane> for Plane {
3780 type Output = Plane;
3781
3782 fn sub(self, other: Plane) -> Plane {
3783 Plane { groups: PlaneGroups { g0: self.group0() - other.group0() } }
3784 }
3785}
3786
3787impl SubAssign<Plane> for Plane {
3788 fn sub_assign(&mut self, other: Plane) {
3789 *self = (*self).sub(other);
3790 }
3791}
3792
3793impl Mul<Plane> for Plane {
3794 type Output = Plane;
3795
3796 fn mul(self, other: Plane) -> Plane {
3797 Plane { groups: PlaneGroups { g0: self.group0() * other.group0() } }
3798 }
3799}
3800
3801impl MulAssign<Plane> for Plane {
3802 fn mul_assign(&mut self, other: Plane) {
3803 *self = (*self).mul(other);
3804 }
3805}
3806
3807impl Div<Plane> for Plane {
3808 type Output = Plane;
3809
3810 fn div(self, other: Plane) -> Plane {
3811 Plane { groups: PlaneGroups { 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]) } }
3812 }
3813}
3814
3815impl DivAssign<Plane> for Plane {
3816 fn div_assign(&mut self, other: Plane) {
3817 *self = (*self).div(other);
3818 }
3819}
3820
3821impl OuterProduct<Plane> for Plane {
3822 type Output = Line;
3823
3824 fn outer_product(self, other: Plane) -> Line {
3825 Line { groups: LineGroups { g0: Simd32x3::from(self.group0()[0]) * Simd32x3::from([other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) * Simd32x3::from(other.group0()[0]) * Simd32x3::from(-1.0), g1: 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]) } }
3826 }
3827}
3828
3829impl InnerProduct<Plane> for Plane {
3830 type Output = f32;
3831
3832 fn inner_product(self, other: Plane) -> f32 {
3833 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]
3834 }
3835}
3836
3837impl LeftContraction<Plane> for Plane {
3838 type Output = f32;
3839
3840 fn left_contraction(self, other: Plane) -> f32 {
3841 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]
3842 }
3843}
3844
3845impl RightContraction<Plane> for Plane {
3846 type Output = f32;
3847
3848 fn right_contraction(self, other: Plane) -> f32 {
3849 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]
3850 }
3851}
3852
3853impl ScalarProduct<Plane> for Plane {
3854 type Output = f32;
3855
3856 fn scalar_product(self, other: Plane) -> f32 {
3857 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]
3858 }
3859}
3860
3861impl GeometricProduct<Line> for Plane {
3862 type Output = PointAndPlane;
3863
3864 fn geometric_product(self, other: Line) -> PointAndPlane {
3865 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[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]) } }
3866 }
3867}
3868
3869impl OuterProduct<Line> for Plane {
3870 type Output = Point;
3871
3872 fn outer_product(self, other: Line) -> Point {
3873 Point { groups: PointGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
3874 }
3875}
3876
3877impl InnerProduct<Line> for Plane {
3878 type Output = Plane;
3879
3880 fn inner_product(self, other: Line) -> Plane {
3881 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[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]) } }
3882 }
3883}
3884
3885impl LeftContraction<Line> for Plane {
3886 type Output = Plane;
3887
3888 fn left_contraction(self, other: Line) -> Plane {
3889 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[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]) } }
3890 }
3891}
3892
3893impl InnerProduct<Translator> for Plane {
3894 type Output = Plane;
3895
3896 fn inner_product(self, other: Translator) -> Plane {
3897 Plane { groups: PlaneGroups { 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]) } }
3898 }
3899}
3900
3901impl LeftContraction<Translator> for Plane {
3902 type Output = Plane;
3903
3904 fn left_contraction(self, other: Translator) -> Plane {
3905 Plane { groups: PlaneGroups { 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()[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, 1, 2, 3) * Simd32x4::from(-1.0) } }
3906 }
3907}
3908
3909impl RightContraction<Translator> for Plane {
3910 type Output = Plane;
3911
3912 fn right_contraction(self, other: Translator) -> Plane {
3913 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
3914 }
3915}
3916
3917impl GeometricProduct<Motor> for Plane {
3918 type Output = PointAndPlane;
3919
3920 fn geometric_product(self, other: Motor) -> PointAndPlane {
3921 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(0.0) - Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group1()[0], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
3922 }
3923}
3924
3925impl RegressiveProduct<Motor> for Plane {
3926 type Output = Plane;
3927
3928 fn regressive_product(self, other: Motor) -> Plane {
3929 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other.group1()[0]) } }
3930 }
3931}
3932
3933impl OuterProduct<Motor> for Plane {
3934 type Output = PointAndPlane;
3935
3936 fn outer_product(self, other: Motor) -> PointAndPlane {
3937 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[2], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[3]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g1: self.group0() * Simd32x4::from(other.group0()[0]) } }
3938 }
3939}
3940
3941impl InnerProduct<Motor> for Plane {
3942 type Output = PointAndPlane;
3943
3944 fn inner_product(self, other: Motor) -> PointAndPlane {
3945 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
3946 }
3947}
3948
3949impl LeftContraction<Motor> for Plane {
3950 type Output = PointAndPlane;
3951
3952 fn left_contraction(self, other: Motor) -> PointAndPlane {
3953 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[1], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[2], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * other.group1() * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
3954 }
3955}
3956
3957impl RightContraction<Motor> for Plane {
3958 type Output = Plane;
3959
3960 fn right_contraction(self, other: Motor) -> Plane {
3961 Plane { groups: PlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
3962 }
3963}
3964
3965impl Add<PointAndPlane> for Plane {
3966 type Output = PointAndPlane;
3967
3968 fn add(self, other: PointAndPlane) -> PointAndPlane {
3969 PointAndPlane { groups: PointAndPlaneGroups { g0: other.group0(), g1: self.group0() + other.group1() } }
3970 }
3971}
3972
3973impl Sub<PointAndPlane> for Plane {
3974 type Output = PointAndPlane;
3975
3976 fn sub(self, other: PointAndPlane) -> PointAndPlane {
3977 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: self.group0() - other.group1() } }
3978 }
3979}
3980
3981impl GeometricProduct<PointAndPlane> for Plane {
3982 type Output = Motor;
3983
3984 fn geometric_product(self, other: PointAndPlane) -> Motor {
3985 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
3986 }
3987}
3988
3989impl RegressiveProduct<PointAndPlane> for Plane {
3990 type Output = f32;
3991
3992 fn regressive_product(self, other: PointAndPlane) -> f32 {
3993 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
3994 }
3995}
3996
3997impl RightContraction<PointAndPlane> for Plane {
3998 type Output = f32;
3999
4000 fn right_contraction(self, other: PointAndPlane) -> f32 {
4001 0.0 - self.group0()[0] * other.group1()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2] + self.group0()[3] * other.group1()[3]
4002 }
4003}
4004
4005impl ScalarProduct<PointAndPlane> for Plane {
4006 type Output = f32;
4007
4008 fn scalar_product(self, other: PointAndPlane) -> f32 {
4009 0.0 - self.group0()[0] * other.group1()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2] + self.group0()[3] * other.group1()[3]
4010 }
4011}
4012
4013impl SquaredMagnitude for Plane {
4014 type Output = f32;
4015
4016 fn squared_magnitude(self) -> f32 {
4017 self.scalar_product(self.reversal())
4018 }
4019}
4020
4021impl Magnitude for Plane {
4022 type Output = f32;
4023
4024 fn magnitude(self) -> f32 {
4025 self.squared_magnitude().sqrt()
4026 }
4027}
4028
4029impl Mul<f32> for Plane {
4030 type Output = Plane;
4031
4032 fn mul(self, other: f32) -> Plane {
4033 self.geometric_product(other)
4034 }
4035}
4036
4037impl MulAssign<f32> for Plane {
4038 fn mul_assign(&mut self, other: f32) {
4039 *self = (*self).mul(other);
4040 }
4041}
4042
4043impl Signum for Plane {
4044 type Output = Plane;
4045
4046 fn signum(self) -> Plane {
4047 self.geometric_product(1.0 / self.magnitude())
4048 }
4049}
4050
4051impl Inverse for Plane {
4052 type Output = Plane;
4053
4054 fn inverse(self) -> Plane {
4055 self.reversal().geometric_product(1.0 / self.squared_magnitude())
4056 }
4057}
4058
4059impl Zero for Line {
4060 fn zero() -> Self {
4061 Line { groups: LineGroups { g0: Simd32x3::from(0.0), g1: Simd32x3::from(0.0) } }
4062 }
4063}
4064
4065impl One for Line {
4066 fn one() -> Self {
4067 Line { groups: LineGroups { g0: Simd32x3::from(0.0), g1: Simd32x3::from(0.0) } }
4068 }
4069}
4070
4071impl Neg for Line {
4072 type Output = Line;
4073
4074 fn neg(self) -> Line {
4075 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(-1.0), g1: self.group1() * Simd32x3::from(-1.0) } }
4076 }
4077}
4078
4079impl Automorphism for Line {
4080 type Output = Line;
4081
4082 fn automorphism(self) -> Line {
4083 Line { groups: LineGroups { g0: self.group0(), g1: self.group1() } }
4084 }
4085}
4086
4087impl Reversal for Line {
4088 type Output = Line;
4089
4090 fn reversal(self) -> Line {
4091 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(-1.0), g1: self.group1() * Simd32x3::from(-1.0) } }
4092 }
4093}
4094
4095impl Conjugation for Line {
4096 type Output = Line;
4097
4098 fn conjugation(self) -> Line {
4099 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(-1.0), g1: self.group1() * Simd32x3::from(-1.0) } }
4100 }
4101}
4102
4103impl Dual for Line {
4104 type Output = Line;
4105
4106 fn dual(self) -> Line {
4107 Line { groups: LineGroups { g0: self.group1(), g1: self.group0() } }
4108 }
4109}
4110
4111impl GeometricProduct<f32> for Line {
4112 type Output = Line;
4113
4114 fn geometric_product(self, other: f32) -> Line {
4115 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(other), g1: self.group1() * Simd32x3::from(other) } }
4116 }
4117}
4118
4119impl OuterProduct<f32> for Line {
4120 type Output = Line;
4121
4122 fn outer_product(self, other: f32) -> Line {
4123 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(other), g1: self.group1() * Simd32x3::from(other) } }
4124 }
4125}
4126
4127impl InnerProduct<f32> for Line {
4128 type Output = Line;
4129
4130 fn inner_product(self, other: f32) -> Line {
4131 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(other), g1: self.group1() * Simd32x3::from(other) } }
4132 }
4133}
4134
4135impl RightContraction<f32> for Line {
4136 type Output = Line;
4137
4138 fn right_contraction(self, other: f32) -> Line {
4139 Line { groups: LineGroups { g0: self.group0() * Simd32x3::from(other), g1: self.group1() * Simd32x3::from(other) } }
4140 }
4141}
4142
4143impl Add<MultiVector> for Line {
4144 type Output = MultiVector;
4145
4146 fn add(self, other: MultiVector) -> MultiVector {
4147 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group1()[0], self.group1()[1], self.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group0(), g1: other.group1(), g2: other.group2(), g3: 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.group3() } }
4148 }
4149}
4150
4151impl Sub<MultiVector> for Line {
4152 type Output = MultiVector;
4153
4154 fn sub(self, other: MultiVector) -> MultiVector {
4155 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from([self.group0()[0], self.group1()[0], self.group1()[1], self.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group0(), g1: Simd32x4::from(0.0) - other.group1(), g2: Simd32x4::from(0.0) - other.group2(), g3: 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.group3() } }
4156 }
4157}
4158
4159impl GeometricProduct<MultiVector> for Line {
4160 type Output = MultiVector;
4161
4162 fn geometric_product(self, other: MultiVector) -> MultiVector {
4163 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g2: 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.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]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g3: 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]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
4164 }
4165}
4166
4167impl ScalarProduct<MultiVector> for Line {
4168 type Output = f32;
4169
4170 fn scalar_product(self, other: MultiVector) -> f32 {
4171 self.group0()[0] * other.group3()[1] + self.group0()[1] * other.group3()[2] + self.group0()[2] * other.group3()[3] - self.group1()[0] * other.group0()[1] - self.group1()[1] * other.group0()[2] - self.group1()[2] * other.group0()[3]
4172 }
4173}
4174
4175impl GeometricProduct<Rotor> for Line {
4176 type Output = Motor;
4177
4178 fn geometric_product(self, other: Rotor) -> Motor {
4179 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.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()[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]) } }
4180 }
4181}
4182
4183impl RegressiveProduct<Rotor> for Line {
4184 type Output = f32;
4185
4186 fn regressive_product(self, other: Rotor) -> f32 {
4187 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
4188 }
4189}
4190
4191impl LeftContraction<Rotor> for Line {
4192 type Output = f32;
4193
4194 fn left_contraction(self, other: Rotor) -> f32 {
4195 0.0 - self.group1()[0] * other.group0()[1] - self.group1()[1] * other.group0()[2] - self.group1()[2] * other.group0()[3]
4196 }
4197}
4198
4199impl ScalarProduct<Rotor> for Line {
4200 type Output = f32;
4201
4202 fn scalar_product(self, other: Rotor) -> f32 {
4203 0.0 - self.group1()[0] * other.group0()[1] - self.group1()[1] * other.group0()[2] - self.group1()[2] * other.group0()[3]
4204 }
4205}
4206
4207impl GeometricProduct<Point> for Line {
4208 type Output = PointAndPlane;
4209
4210 fn geometric_product(self, other: Point) -> PointAndPlane {
4211 PointAndPlane { groups: PointAndPlaneGroups { 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.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, -1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
4212 }
4213}
4214
4215impl RegressiveProduct<Point> for Line {
4216 type Output = Plane;
4217
4218 fn regressive_product(self, other: Point) -> Plane {
4219 Plane { groups: PlaneGroups { 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.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
4220 }
4221}
4222
4223impl InnerProduct<Point> for Line {
4224 type Output = Plane;
4225
4226 fn inner_product(self, other: Point) -> Plane {
4227 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
4228 }
4229}
4230
4231impl LeftContraction<Point> for Line {
4232 type Output = Plane;
4233
4234 fn left_contraction(self, other: Point) -> Plane {
4235 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
4236 }
4237}
4238
4239impl Into<IdealPoint> for Line {
4240 fn into(self) -> IdealPoint {
4241 IdealPoint { groups: IdealPointGroups { g0: self.group0() } }
4242 }
4243}
4244
4245impl Add<IdealPoint> for Line {
4246 type Output = Line;
4247
4248 fn add(self, other: IdealPoint) -> Line {
4249 Line { groups: LineGroups { g0: self.group0() + other.group0(), g1: self.group1() } }
4250 }
4251}
4252
4253impl AddAssign<IdealPoint> for Line {
4254 fn add_assign(&mut self, other: IdealPoint) {
4255 *self = (*self).add(other);
4256 }
4257}
4258
4259impl Sub<IdealPoint> for Line {
4260 type Output = Line;
4261
4262 fn sub(self, other: IdealPoint) -> Line {
4263 Line { groups: LineGroups { g0: self.group0() - other.group0(), g1: self.group1() } }
4264 }
4265}
4266
4267impl SubAssign<IdealPoint> for Line {
4268 fn sub_assign(&mut self, other: IdealPoint) {
4269 *self = (*self).sub(other);
4270 }
4271}
4272
4273impl GeometricProduct<IdealPoint> for Line {
4274 type Output = Motor;
4275
4276 fn geometric_product(self, other: IdealPoint) -> Motor {
4277 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]), g1: Simd32x4::from(self.group1()[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.group1()[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.group1()[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]) } }
4278 }
4279}
4280
4281impl RegressiveProduct<IdealPoint> for Line {
4282 type Output = f32;
4283
4284 fn regressive_product(self, other: IdealPoint) -> f32 {
4285 self.group1()[0] * other.group0()[0] + self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2]
4286 }
4287}
4288
4289impl InnerProduct<IdealPoint> for Line {
4290 type Output = f32;
4291
4292 fn inner_product(self, other: IdealPoint) -> f32 {
4293 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
4294 }
4295}
4296
4297impl LeftContraction<IdealPoint> for Line {
4298 type Output = f32;
4299
4300 fn left_contraction(self, other: IdealPoint) -> f32 {
4301 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
4302 }
4303}
4304
4305impl RightContraction<IdealPoint> for Line {
4306 type Output = f32;
4307
4308 fn right_contraction(self, other: IdealPoint) -> f32 {
4309 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
4310 }
4311}
4312
4313impl ScalarProduct<IdealPoint> for Line {
4314 type Output = f32;
4315
4316 fn scalar_product(self, other: IdealPoint) -> f32 {
4317 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2]
4318 }
4319}
4320
4321impl GeometricProduct<Plane> for Line {
4322 type Output = PointAndPlane;
4323
4324 fn geometric_product(self, other: Plane) -> PointAndPlane {
4325 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[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.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
4326 }
4327}
4328
4329impl OuterProduct<Plane> for Line {
4330 type Output = Point;
4331
4332 fn outer_product(self, other: Plane) -> Point {
4333 Point { groups: PointGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) } }
4334 }
4335}
4336
4337impl InnerProduct<Plane> for Line {
4338 type Output = Plane;
4339
4340 fn inner_product(self, other: Plane) -> Plane {
4341 Plane { groups: PlaneGroups { 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.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
4342 }
4343}
4344
4345impl RightContraction<Plane> for Line {
4346 type Output = Plane;
4347
4348 fn right_contraction(self, other: Plane) -> Plane {
4349 Plane { groups: PlaneGroups { 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.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
4350 }
4351}
4352
4353impl Add<Line> for Line {
4354 type Output = Line;
4355
4356 fn add(self, other: Line) -> Line {
4357 Line { groups: LineGroups { g0: self.group0() + other.group0(), g1: self.group1() + other.group1() } }
4358 }
4359}
4360
4361impl AddAssign<Line> for Line {
4362 fn add_assign(&mut self, other: Line) {
4363 *self = (*self).add(other);
4364 }
4365}
4366
4367impl Sub<Line> for Line {
4368 type Output = Line;
4369
4370 fn sub(self, other: Line) -> Line {
4371 Line { groups: LineGroups { g0: self.group0() - other.group0(), g1: self.group1() - other.group1() } }
4372 }
4373}
4374
4375impl SubAssign<Line> for Line {
4376 fn sub_assign(&mut self, other: Line) {
4377 *self = (*self).sub(other);
4378 }
4379}
4380
4381impl Mul<Line> for Line {
4382 type Output = Line;
4383
4384 fn mul(self, other: Line) -> Line {
4385 Line { groups: LineGroups { g0: self.group0() * other.group0(), g1: self.group1() * other.group1() } }
4386 }
4387}
4388
4389impl MulAssign<Line> for Line {
4390 fn mul_assign(&mut self, other: Line) {
4391 *self = (*self).mul(other);
4392 }
4393}
4394
4395impl Div<Line> for Line {
4396 type Output = Line;
4397
4398 fn div(self, other: Line) -> Line {
4399 Line { groups: LineGroups { 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]), g1: Simd32x3::from([self.group1()[0], self.group1()[1], self.group1()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) / Simd32x3::from([other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x3::from([1.0, 1.0, 1.0]) } }
4400 }
4401}
4402
4403impl DivAssign<Line> for Line {
4404 fn div_assign(&mut self, other: Line) {
4405 *self = (*self).div(other);
4406 }
4407}
4408
4409impl GeometricProduct<Line> for Line {
4410 type Output = Motor;
4411
4412 fn geometric_product(self, other: Line) -> Motor {
4413 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.group1()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[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]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) + Simd32x4::from(self.group1()[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.group1()[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.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) } }
4414 }
4415}
4416
4417impl RegressiveProduct<Line> for Line {
4418 type Output = f32;
4419
4420 fn regressive_product(self, other: Line) -> f32 {
4421 self.group0()[0] * other.group1()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2] + self.group1()[0] * other.group0()[0] + self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2]
4422 }
4423}
4424
4425impl InnerProduct<Line> for Line {
4426 type Output = f32;
4427
4428 fn inner_product(self, other: Line) -> f32 {
4429 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] - self.group1()[0] * other.group1()[0] - self.group1()[1] * other.group1()[1] - self.group1()[2] * other.group1()[2]
4430 }
4431}
4432
4433impl LeftContraction<Line> for Line {
4434 type Output = f32;
4435
4436 fn left_contraction(self, other: Line) -> f32 {
4437 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] - self.group1()[0] * other.group1()[0] - self.group1()[1] * other.group1()[1] - self.group1()[2] * other.group1()[2]
4438 }
4439}
4440
4441impl RightContraction<Line> for Line {
4442 type Output = f32;
4443
4444 fn right_contraction(self, other: Line) -> f32 {
4445 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] - self.group1()[0] * other.group1()[0] - self.group1()[1] * other.group1()[1] - self.group1()[2] * other.group1()[2]
4446 }
4447}
4448
4449impl ScalarProduct<Line> for Line {
4450 type Output = f32;
4451
4452 fn scalar_product(self, other: Line) -> f32 {
4453 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] - self.group1()[0] * other.group1()[0] - self.group1()[1] * other.group1()[1] - self.group1()[2] * other.group1()[2]
4454 }
4455}
4456
4457impl GeometricProduct<Translator> for Line {
4458 type Output = Motor;
4459
4460 fn geometric_product(self, other: Translator) -> Motor {
4461 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.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.group0()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group0()[1], self.group0()[2]]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4462 }
4463}
4464
4465impl RegressiveProduct<Translator> for Line {
4466 type Output = f32;
4467
4468 fn regressive_product(self, other: Translator) -> f32 {
4469 self.group1()[0] * other.group0()[1] + self.group1()[1] * other.group0()[2] + self.group1()[2] * other.group0()[3]
4470 }
4471}
4472
4473impl LeftContraction<Translator> for Line {
4474 type Output = f32;
4475
4476 fn left_contraction(self, other: Translator) -> f32 {
4477 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
4478 }
4479}
4480
4481impl ScalarProduct<Translator> for Line {
4482 type Output = f32;
4483
4484 fn scalar_product(self, other: Translator) -> f32 {
4485 self.group0()[0] * other.group0()[1] + self.group0()[1] * other.group0()[2] + self.group0()[2] * other.group0()[3]
4486 }
4487}
4488
4489impl Add<Motor> for Line {
4490 type Output = Motor;
4491
4492 fn add(self, other: Motor) -> Motor {
4493 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group1()[0], self.group1()[1], self.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group0(), g1: 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.group1() } }
4494 }
4495}
4496
4497impl Sub<Motor> for Line {
4498 type Output = Motor;
4499
4500 fn sub(self, other: Motor) -> Motor {
4501 Motor { groups: MotorGroups { g0: Simd32x4::from([self.group0()[0], self.group1()[0], self.group1()[1], self.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group0(), g1: 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.group1() } }
4502 }
4503}
4504
4505impl GeometricProduct<Motor> for Line {
4506 type Output = Motor;
4507
4508 fn geometric_product(self, other: Motor) -> Motor {
4509 Motor { groups: MotorGroups { 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]) * 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]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.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()[1]) * swizzle!(other.group0(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
4510 }
4511}
4512
4513impl ScalarProduct<Motor> for Line {
4514 type Output = f32;
4515
4516 fn scalar_product(self, other: Motor) -> f32 {
4517 self.group0()[0] * other.group1()[1] + self.group0()[1] * other.group1()[2] + self.group0()[2] * other.group1()[3] - self.group1()[0] * other.group0()[1] - self.group1()[1] * other.group0()[2] - self.group1()[2] * other.group0()[3]
4518 }
4519}
4520
4521impl GeometricProduct<PointAndPlane> for Line {
4522 type Output = PointAndPlane;
4523
4524 fn geometric_product(self, other: PointAndPlane) -> PointAndPlane {
4525 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
4526 }
4527}
4528
4529impl RegressiveProduct<PointAndPlane> for Line {
4530 type Output = Plane;
4531
4532 fn regressive_product(self, other: PointAndPlane) -> Plane {
4533 Plane { groups: PlaneGroups { 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.group1()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
4534 }
4535}
4536
4537impl OuterProduct<PointAndPlane> for Line {
4538 type Output = Point;
4539
4540 fn outer_product(self, other: PointAndPlane) -> Point {
4541 Point { groups: PointGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) } }
4542 }
4543}
4544
4545impl InnerProduct<PointAndPlane> for Line {
4546 type Output = Plane;
4547
4548 fn inner_product(self, other: PointAndPlane) -> Plane {
4549 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
4550 }
4551}
4552
4553impl LeftContraction<PointAndPlane> for Line {
4554 type Output = Plane;
4555
4556 fn left_contraction(self, other: PointAndPlane) -> Plane {
4557 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from([self.group1()[0], self.group1()[0], self.group0()[0], self.group0()[0]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
4558 }
4559}
4560
4561impl RightContraction<PointAndPlane> for Line {
4562 type Output = Plane;
4563
4564 fn right_contraction(self, other: PointAndPlane) -> Plane {
4565 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[0], self.group0()[0], self.group1()[0], self.group1()[0]]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
4566 }
4567}
4568
4569impl SquaredMagnitude for Line {
4570 type Output = f32;
4571
4572 fn squared_magnitude(self) -> f32 {
4573 self.scalar_product(self.reversal())
4574 }
4575}
4576
4577impl Magnitude for Line {
4578 type Output = f32;
4579
4580 fn magnitude(self) -> f32 {
4581 self.squared_magnitude().sqrt()
4582 }
4583}
4584
4585impl Mul<f32> for Line {
4586 type Output = Line;
4587
4588 fn mul(self, other: f32) -> Line {
4589 self.geometric_product(other)
4590 }
4591}
4592
4593impl MulAssign<f32> for Line {
4594 fn mul_assign(&mut self, other: f32) {
4595 *self = (*self).mul(other);
4596 }
4597}
4598
4599impl Signum for Line {
4600 type Output = Line;
4601
4602 fn signum(self) -> Line {
4603 self.geometric_product(1.0 / self.magnitude())
4604 }
4605}
4606
4607impl Inverse for Line {
4608 type Output = Line;
4609
4610 fn inverse(self) -> Line {
4611 self.reversal().geometric_product(1.0 / self.squared_magnitude())
4612 }
4613}
4614
4615impl Zero for Translator {
4616 fn zero() -> Self {
4617 Translator { groups: TranslatorGroups { g0: Simd32x4::from(0.0) } }
4618 }
4619}
4620
4621impl One for Translator {
4622 fn one() -> Self {
4623 Translator { groups: TranslatorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4624 }
4625}
4626
4627impl Neg for Translator {
4628 type Output = Translator;
4629
4630 fn neg(self) -> Translator {
4631 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from(-1.0) } }
4632 }
4633}
4634
4635impl Automorphism for Translator {
4636 type Output = Translator;
4637
4638 fn automorphism(self) -> Translator {
4639 Translator { groups: TranslatorGroups { g0: self.group0() } }
4640 }
4641}
4642
4643impl Reversal for Translator {
4644 type Output = Translator;
4645
4646 fn reversal(self) -> Translator {
4647 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
4648 }
4649}
4650
4651impl Conjugation for Translator {
4652 type Output = Translator;
4653
4654 fn conjugation(self) -> Translator {
4655 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
4656 }
4657}
4658
4659impl Into<f32> for Translator {
4660 fn into(self) -> f32 {
4661 self.group0()[0]
4662 }
4663}
4664
4665impl Add<f32> for Translator {
4666 type Output = Translator;
4667
4668 fn add(self, other: f32) -> Translator {
4669 Translator { groups: TranslatorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4670 }
4671}
4672
4673impl AddAssign<f32> for Translator {
4674 fn add_assign(&mut self, other: f32) {
4675 *self = (*self).add(other);
4676 }
4677}
4678
4679impl Sub<f32> for Translator {
4680 type Output = Translator;
4681
4682 fn sub(self, other: f32) -> Translator {
4683 Translator { groups: TranslatorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
4684 }
4685}
4686
4687impl SubAssign<f32> for Translator {
4688 fn sub_assign(&mut self, other: f32) {
4689 *self = (*self).sub(other);
4690 }
4691}
4692
4693impl GeometricProduct<f32> for Translator {
4694 type Output = Translator;
4695
4696 fn geometric_product(self, other: f32) -> Translator {
4697 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from(other) } }
4698 }
4699}
4700
4701impl OuterProduct<f32> for Translator {
4702 type Output = Translator;
4703
4704 fn outer_product(self, other: f32) -> Translator {
4705 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from(other) } }
4706 }
4707}
4708
4709impl InnerProduct<f32> for Translator {
4710 type Output = Translator;
4711
4712 fn inner_product(self, other: f32) -> Translator {
4713 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from(other) } }
4714 }
4715}
4716
4717impl LeftContraction<f32> for Translator {
4718 type Output = f32;
4719
4720 fn left_contraction(self, other: f32) -> f32 {
4721 self.group0()[0] * other
4722 }
4723}
4724
4725impl RightContraction<f32> for Translator {
4726 type Output = Translator;
4727
4728 fn right_contraction(self, other: f32) -> Translator {
4729 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from(other) } }
4730 }
4731}
4732
4733impl ScalarProduct<f32> for Translator {
4734 type Output = f32;
4735
4736 fn scalar_product(self, other: f32) -> f32 {
4737 self.group0()[0] * other
4738 }
4739}
4740
4741impl Add<MultiVector> for Translator {
4742 type Output = MultiVector;
4743
4744 fn add(self, other: MultiVector) -> MultiVector {
4745 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0(), g1: other.group1(), g2: other.group2(), g3: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group3() } }
4746 }
4747}
4748
4749impl Sub<MultiVector> for Translator {
4750 type Output = MultiVector;
4751
4752 fn sub(self, other: MultiVector) -> MultiVector {
4753 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0(), g1: Simd32x4::from(0.0) - other.group1(), g2: Simd32x4::from(0.0) - other.group2(), g3: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group3() } }
4754 }
4755}
4756
4757impl GeometricProduct<MultiVector> for Translator {
4758 type Output = MultiVector;
4759
4760 fn geometric_product(self, other: MultiVector) -> MultiVector {
4761 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 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.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + 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([-1.0, -1.0, 1.0, 1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + 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]) } }
4762 }
4763}
4764
4765impl OuterProduct<MultiVector> for Translator {
4766 type Output = MultiVector;
4767
4768 fn outer_product(self, other: MultiVector) -> MultiVector {
4769 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.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group2(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2(), g3: Simd32x4::from(self.group0()[0]) * other.group3() + 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]) } }
4770 }
4771}
4772
4773impl InnerProduct<MultiVector> for Translator {
4774 type Output = MultiVector;
4775
4776 fn inner_product(self, other: MultiVector) -> MultiVector {
4777 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group3(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group2(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 0, 1) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 1, 0) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group1(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
4778 }
4779}
4780
4781impl LeftContraction<MultiVector> for Translator {
4782 type Output = MultiVector;
4783
4784 fn left_contraction(self, other: MultiVector) -> MultiVector {
4785 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group3(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1(), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group1(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() } }
4786 }
4787}
4788
4789impl ScalarProduct<MultiVector> for Translator {
4790 type Output = f32;
4791
4792 fn scalar_product(self, other: MultiVector) -> f32 {
4793 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group3()[1] + self.group0()[2] * other.group3()[2] + self.group0()[3] * other.group3()[3]
4794 }
4795}
4796
4797impl GeometricProduct<Rotor> for Translator {
4798 type Output = Motor;
4799
4800 fn geometric_product(self, other: Rotor) -> Motor {
4801 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: 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]) } }
4802 }
4803}
4804
4805impl RegressiveProduct<Rotor> for Translator {
4806 type Output = f32;
4807
4808 fn regressive_product(self, other: Rotor) -> f32 {
4809 self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
4810 }
4811}
4812
4813impl OuterProduct<Rotor> for Translator {
4814 type Output = Motor;
4815
4816 fn outer_product(self, other: Rotor) -> Motor {
4817 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: 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]) } }
4818 }
4819}
4820
4821impl LeftContraction<Rotor> for Translator {
4822 type Output = Rotor;
4823
4824 fn left_contraction(self, other: Rotor) -> Rotor {
4825 Rotor { groups: RotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
4826 }
4827}
4828
4829impl RightContraction<Rotor> for Translator {
4830 type Output = Translator;
4831
4832 fn right_contraction(self, other: Rotor) -> Translator {
4833 Translator { groups: TranslatorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]) } }
4834 }
4835}
4836
4837impl ScalarProduct<Rotor> for Translator {
4838 type Output = f32;
4839
4840 fn scalar_product(self, other: Rotor) -> f32 {
4841 self.group0()[0] * other.group0()[0]
4842 }
4843}
4844
4845impl RegressiveProduct<Point> for Translator {
4846 type Output = Plane;
4847
4848 fn regressive_product(self, other: Point) -> Plane {
4849 Plane { groups: PlaneGroups { g0: 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]) } }
4850 }
4851}
4852
4853impl OuterProduct<Point> for Translator {
4854 type Output = Point;
4855
4856 fn outer_product(self, other: Point) -> Point {
4857 Point { groups: PointGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
4858 }
4859}
4860
4861impl Into<IdealPoint> for Translator {
4862 fn into(self) -> IdealPoint {
4863 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
4864 }
4865}
4866
4867impl Add<IdealPoint> for Translator {
4868 type Output = Translator;
4869
4870 fn add(self, other: IdealPoint) -> Translator {
4871 Translator { groups: TranslatorGroups { 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]) } }
4872 }
4873}
4874
4875impl AddAssign<IdealPoint> for Translator {
4876 fn add_assign(&mut self, other: IdealPoint) {
4877 *self = (*self).add(other);
4878 }
4879}
4880
4881impl Sub<IdealPoint> for Translator {
4882 type Output = Translator;
4883
4884 fn sub(self, other: IdealPoint) -> Translator {
4885 Translator { groups: TranslatorGroups { 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]) } }
4886 }
4887}
4888
4889impl SubAssign<IdealPoint> for Translator {
4890 fn sub_assign(&mut self, other: IdealPoint) {
4891 *self = (*self).sub(other);
4892 }
4893}
4894
4895impl OuterProduct<IdealPoint> for Translator {
4896 type Output = IdealPoint;
4897
4898 fn outer_product(self, other: IdealPoint) -> IdealPoint {
4899 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from(self.group0()[0]) * other.group0() } }
4900 }
4901}
4902
4903impl InnerProduct<IdealPoint> for Translator {
4904 type Output = Translator;
4905
4906 fn inner_product(self, other: IdealPoint) -> Translator {
4907 Translator { groups: TranslatorGroups { 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]]) } }
4908 }
4909}
4910
4911impl LeftContraction<IdealPoint> for Translator {
4912 type Output = Translator;
4913
4914 fn left_contraction(self, other: IdealPoint) -> Translator {
4915 Translator { groups: TranslatorGroups { 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]]) } }
4916 }
4917}
4918
4919impl RightContraction<IdealPoint> for Translator {
4920 type Output = f32;
4921
4922 fn right_contraction(self, other: IdealPoint) -> f32 {
4923 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
4924 }
4925}
4926
4927impl ScalarProduct<IdealPoint> for Translator {
4928 type Output = f32;
4929
4930 fn scalar_product(self, other: IdealPoint) -> f32 {
4931 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
4932 }
4933}
4934
4935impl InnerProduct<Plane> for Translator {
4936 type Output = Plane;
4937
4938 fn inner_product(self, other: Plane) -> Plane {
4939 Plane { groups: PlaneGroups { 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]) } }
4940 }
4941}
4942
4943impl LeftContraction<Plane> for Translator {
4944 type Output = Plane;
4945
4946 fn left_contraction(self, other: Plane) -> Plane {
4947 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
4948 }
4949}
4950
4951impl RightContraction<Plane> for Translator {
4952 type Output = Plane;
4953
4954 fn right_contraction(self, other: Plane) -> Plane {
4955 Plane { groups: PlaneGroups { g0: 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]) } }
4956 }
4957}
4958
4959impl GeometricProduct<Line> for Translator {
4960 type Output = Motor;
4961
4962 fn geometric_product(self, other: Line) -> Motor {
4963 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.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[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]) } }
4964 }
4965}
4966
4967impl RegressiveProduct<Line> for Translator {
4968 type Output = f32;
4969
4970 fn regressive_product(self, other: Line) -> f32 {
4971 self.group0()[1] * other.group1()[0] + self.group0()[2] * other.group1()[1] + self.group0()[3] * other.group1()[2]
4972 }
4973}
4974
4975impl RightContraction<Line> for Translator {
4976 type Output = f32;
4977
4978 fn right_contraction(self, other: Line) -> f32 {
4979 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
4980 }
4981}
4982
4983impl ScalarProduct<Line> for Translator {
4984 type Output = f32;
4985
4986 fn scalar_product(self, other: Line) -> f32 {
4987 self.group0()[1] * other.group0()[0] + self.group0()[2] * other.group0()[1] + self.group0()[3] * other.group0()[2]
4988 }
4989}
4990
4991impl Add<Translator> for Translator {
4992 type Output = Translator;
4993
4994 fn add(self, other: Translator) -> Translator {
4995 Translator { groups: TranslatorGroups { g0: self.group0() + other.group0() } }
4996 }
4997}
4998
4999impl AddAssign<Translator> for Translator {
5000 fn add_assign(&mut self, other: Translator) {
5001 *self = (*self).add(other);
5002 }
5003}
5004
5005impl Sub<Translator> for Translator {
5006 type Output = Translator;
5007
5008 fn sub(self, other: Translator) -> Translator {
5009 Translator { groups: TranslatorGroups { g0: self.group0() - other.group0() } }
5010 }
5011}
5012
5013impl SubAssign<Translator> for Translator {
5014 fn sub_assign(&mut self, other: Translator) {
5015 *self = (*self).sub(other);
5016 }
5017}
5018
5019impl Mul<Translator> for Translator {
5020 type Output = Translator;
5021
5022 fn mul(self, other: Translator) -> Translator {
5023 Translator { groups: TranslatorGroups { g0: self.group0() * other.group0() } }
5024 }
5025}
5026
5027impl MulAssign<Translator> for Translator {
5028 fn mul_assign(&mut self, other: Translator) {
5029 *self = (*self).mul(other);
5030 }
5031}
5032
5033impl Div<Translator> for Translator {
5034 type Output = Translator;
5035
5036 fn div(self, other: Translator) -> Translator {
5037 Translator { groups: TranslatorGroups { 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]) } }
5038 }
5039}
5040
5041impl DivAssign<Translator> for Translator {
5042 fn div_assign(&mut self, other: Translator) {
5043 *self = (*self).div(other);
5044 }
5045}
5046
5047impl OuterProduct<Translator> for Translator {
5048 type Output = Translator;
5049
5050 fn outer_product(self, other: Translator) -> Translator {
5051 Translator { groups: TranslatorGroups { 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]) } }
5052 }
5053}
5054
5055impl InnerProduct<Translator> for Translator {
5056 type Output = Translator;
5057
5058 fn inner_product(self, other: Translator) -> Translator {
5059 Translator { groups: TranslatorGroups { 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]) } }
5060 }
5061}
5062
5063impl LeftContraction<Translator> for Translator {
5064 type Output = Translator;
5065
5066 fn left_contraction(self, other: Translator) -> Translator {
5067 Translator { groups: TranslatorGroups { 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]) } }
5068 }
5069}
5070
5071impl RightContraction<Translator> for Translator {
5072 type Output = Translator;
5073
5074 fn right_contraction(self, other: Translator) -> Translator {
5075 Translator { groups: TranslatorGroups { 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]) } }
5076 }
5077}
5078
5079impl ScalarProduct<Translator> for Translator {
5080 type Output = f32;
5081
5082 fn scalar_product(self, other: Translator) -> f32 {
5083 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group0()[1] + self.group0()[2] * other.group0()[2] + self.group0()[3] * other.group0()[3]
5084 }
5085}
5086
5087impl Add<Motor> for Translator {
5088 type Output = Motor;
5089
5090 fn add(self, other: Motor) -> Motor {
5091 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + other.group0(), g1: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + other.group1() } }
5092 }
5093}
5094
5095impl Sub<Motor> for Translator {
5096 type Output = Motor;
5097
5098 fn sub(self, other: Motor) -> Motor {
5099 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - other.group0(), g1: self.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) - other.group1() } }
5100 }
5101}
5102
5103impl GeometricProduct<Motor> for Translator {
5104 type Output = Motor;
5105
5106 fn geometric_product(self, other: Motor) -> Motor {
5107 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + 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]) } }
5108 }
5109}
5110
5111impl RegressiveProduct<Motor> for Translator {
5112 type Output = Translator;
5113
5114 fn regressive_product(self, other: Motor) -> Translator {
5115 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[1], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group1()[0], other.group0()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group0()[3], other.group0()[3], other.group1()[0]]) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5116 }
5117}
5118
5119impl OuterProduct<Motor> for Translator {
5120 type Output = Motor;
5121
5122 fn outer_product(self, other: Motor) -> Motor {
5123 Motor { groups: MotorGroups { 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, 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]) } }
5124 }
5125}
5126
5127impl InnerProduct<Motor> for Translator {
5128 type Output = Motor;
5129
5130 fn inner_product(self, other: Motor) -> Motor {
5131 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + self.group0() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5132 }
5133}
5134
5135impl LeftContraction<Motor> for Translator {
5136 type Output = Motor;
5137
5138 fn left_contraction(self, other: Motor) -> Motor {
5139 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() } }
5140 }
5141}
5142
5143impl RightContraction<Motor> for Translator {
5144 type Output = Translator;
5145
5146 fn right_contraction(self, other: Motor) -> Translator {
5147 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[1], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[2], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group1()[3], other.group1()[3], other.group0()[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]) } }
5148 }
5149}
5150
5151impl ScalarProduct<Motor> for Translator {
5152 type Output = f32;
5153
5154 fn scalar_product(self, other: Motor) -> f32 {
5155 self.group0()[0] * other.group0()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2] + self.group0()[3] * other.group1()[3]
5156 }
5157}
5158
5159impl GeometricProduct<PointAndPlane> for Translator {
5160 type Output = PointAndPlane;
5161
5162 fn geometric_product(self, other: PointAndPlane) -> PointAndPlane {
5163 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
5164 }
5165}
5166
5167impl RegressiveProduct<PointAndPlane> for Translator {
5168 type Output = Plane;
5169
5170 fn regressive_product(self, other: PointAndPlane) -> Plane {
5171 Plane { groups: PlaneGroups { g0: 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]) } }
5172 }
5173}
5174
5175impl OuterProduct<PointAndPlane> for Translator {
5176 type Output = PointAndPlane;
5177
5178 fn outer_product(self, other: PointAndPlane) -> PointAndPlane {
5179 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group1(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() } }
5180 }
5181}
5182
5183impl InnerProduct<PointAndPlane> for Translator {
5184 type Output = PointAndPlane;
5185
5186 fn inner_product(self, other: PointAndPlane) -> PointAndPlane {
5187 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
5188 }
5189}
5190
5191impl LeftContraction<PointAndPlane> for Translator {
5192 type Output = PointAndPlane;
5193
5194 fn left_contraction(self, other: PointAndPlane) -> PointAndPlane {
5195 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + swizzle!(self.group0(), 0, 0, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) } }
5196 }
5197}
5198
5199impl RightContraction<PointAndPlane> for Translator {
5200 type Output = Plane;
5201
5202 fn right_contraction(self, other: PointAndPlane) -> Plane {
5203 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) } }
5204 }
5205}
5206
5207impl SquaredMagnitude for Translator {
5208 type Output = f32;
5209
5210 fn squared_magnitude(self) -> f32 {
5211 self.scalar_product(self.reversal())
5212 }
5213}
5214
5215impl Magnitude for Translator {
5216 type Output = f32;
5217
5218 fn magnitude(self) -> f32 {
5219 self.squared_magnitude().sqrt()
5220 }
5221}
5222
5223impl Mul<f32> for Translator {
5224 type Output = Translator;
5225
5226 fn mul(self, other: f32) -> Translator {
5227 self.geometric_product(other)
5228 }
5229}
5230
5231impl MulAssign<f32> for Translator {
5232 fn mul_assign(&mut self, other: f32) {
5233 *self = (*self).mul(other);
5234 }
5235}
5236
5237impl Signum for Translator {
5238 type Output = Translator;
5239
5240 fn signum(self) -> Translator {
5241 self.geometric_product(1.0 / self.magnitude())
5242 }
5243}
5244
5245impl Inverse for Translator {
5246 type Output = Translator;
5247
5248 fn inverse(self) -> Translator {
5249 self.reversal().geometric_product(1.0 / self.squared_magnitude())
5250 }
5251}
5252
5253impl Zero for Motor {
5254 fn zero() -> Self {
5255 Motor { groups: MotorGroups { g0: Simd32x4::from(0.0), g1: Simd32x4::from(0.0) } }
5256 }
5257}
5258
5259impl One for Motor {
5260 fn one() -> Self {
5261 Motor { groups: MotorGroups { g0: Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(0.0) } }
5262 }
5263}
5264
5265impl Neg for Motor {
5266 type Output = Motor;
5267
5268 fn neg(self) -> Motor {
5269 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(-1.0), g1: self.group1() * Simd32x4::from(-1.0) } }
5270 }
5271}
5272
5273impl Automorphism for Motor {
5274 type Output = Motor;
5275
5276 fn automorphism(self) -> Motor {
5277 Motor { groups: MotorGroups { g0: self.group0(), g1: self.group1() } }
5278 }
5279}
5280
5281impl Reversal for Motor {
5282 type Output = Motor;
5283
5284 fn reversal(self) -> Motor {
5285 Motor { groups: MotorGroups { 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]) } }
5286 }
5287}
5288
5289impl Conjugation for Motor {
5290 type Output = Motor;
5291
5292 fn conjugation(self) -> Motor {
5293 Motor { groups: MotorGroups { 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]) } }
5294 }
5295}
5296
5297impl Dual for Motor {
5298 type Output = Motor;
5299
5300 fn dual(self) -> Motor {
5301 Motor { groups: MotorGroups { g0: self.group1(), g1: self.group0() } }
5302 }
5303}
5304
5305impl Into<f32> for Motor {
5306 fn into(self) -> f32 {
5307 self.group0()[0]
5308 }
5309}
5310
5311impl Add<f32> for Motor {
5312 type Output = Motor;
5313
5314 fn add(self, other: f32) -> Motor {
5315 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() } }
5316 }
5317}
5318
5319impl AddAssign<f32> for Motor {
5320 fn add_assign(&mut self, other: f32) {
5321 *self = (*self).add(other);
5322 }
5323}
5324
5325impl Sub<f32> for Motor {
5326 type Output = Motor;
5327
5328 fn sub(self, other: f32) -> Motor {
5329 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from(other) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() } }
5330 }
5331}
5332
5333impl SubAssign<f32> for Motor {
5334 fn sub_assign(&mut self, other: f32) {
5335 *self = (*self).sub(other);
5336 }
5337}
5338
5339impl GeometricProduct<f32> for Motor {
5340 type Output = Motor;
5341
5342 fn geometric_product(self, other: f32) -> Motor {
5343 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
5344 }
5345}
5346
5347impl RegressiveProduct<f32> for Motor {
5348 type Output = f32;
5349
5350 fn regressive_product(self, other: f32) -> f32 {
5351 self.group1()[0] * other
5352 }
5353}
5354
5355impl OuterProduct<f32> for Motor {
5356 type Output = Motor;
5357
5358 fn outer_product(self, other: f32) -> Motor {
5359 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
5360 }
5361}
5362
5363impl InnerProduct<f32> for Motor {
5364 type Output = Motor;
5365
5366 fn inner_product(self, other: f32) -> Motor {
5367 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
5368 }
5369}
5370
5371impl LeftContraction<f32> for Motor {
5372 type Output = f32;
5373
5374 fn left_contraction(self, other: f32) -> f32 {
5375 self.group0()[0] * other
5376 }
5377}
5378
5379impl RightContraction<f32> for Motor {
5380 type Output = Motor;
5381
5382 fn right_contraction(self, other: f32) -> Motor {
5383 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
5384 }
5385}
5386
5387impl ScalarProduct<f32> for Motor {
5388 type Output = f32;
5389
5390 fn scalar_product(self, other: f32) -> f32 {
5391 self.group0()[0] * other
5392 }
5393}
5394
5395impl Add<MultiVector> for Motor {
5396 type Output = MultiVector;
5397
5398 fn add(self, other: MultiVector) -> MultiVector {
5399 MultiVector { groups: MultiVectorGroups { g0: self.group0() + other.group0(), g1: other.group1(), g2: other.group2(), g3: self.group1() + other.group3() } }
5400 }
5401}
5402
5403impl Sub<MultiVector> for Motor {
5404 type Output = MultiVector;
5405
5406 fn sub(self, other: MultiVector) -> MultiVector {
5407 MultiVector { groups: MultiVectorGroups { g0: self.group0() - other.group0(), g1: Simd32x4::from(0.0) - other.group1(), g2: Simd32x4::from(0.0) - other.group2(), g3: self.group1() - other.group3() } }
5408 }
5409}
5410
5411impl GeometricProduct<MultiVector> for Motor {
5412 type Output = MultiVector;
5413
5414 fn geometric_product(self, other: MultiVector) -> MultiVector {
5415 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([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 0) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * other.group3() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 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([1.0, 1.0, -1.0, -1.0]) - Simd32x4::from(self.group1()[0]) * other.group2() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * other.group1() + 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]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.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]) * 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]) } }
5416 }
5417}
5418
5419impl RegressiveProduct<MultiVector> for Motor {
5420 type Output = MultiVector;
5421
5422 fn regressive_product(self, other: MultiVector) -> MultiVector {
5423 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * other.group0() + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[0]) * other.group1() + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group1(), 1, 0, 0, 0) * swizzle!(other.group1(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]), g2: Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group2() + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group1()[1], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group1()[0], other.group2()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]), g3: Simd32x4::from(self.group1()[0]) * other.group3() + self.group1() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5424 }
5425}
5426
5427impl OuterProduct<MultiVector> for Motor {
5428 type Output = MultiVector;
5429
5430 fn outer_product(self, other: MultiVector) -> MultiVector {
5431 MultiVector { groups: MultiVectorGroups { 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group2(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group2(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group3()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group3()[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]) * 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.group3(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5432 }
5433}
5434
5435impl InnerProduct<MultiVector> for Motor {
5436 type Output = MultiVector;
5437
5438 fn inner_product(self, other: MultiVector) -> MultiVector {
5439 MultiVector { groups: MultiVectorGroups { 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]) + Simd32x4::from(self.group1()[0]) * other.group3() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) - Simd32x4::from(self.group1()[0]) * other.group2() + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group2()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * other.group1() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 0, 1) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 1, 0) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + swizzle!(self.group0(), 0, 1, 1, 1) * swizzle!(other.group2(), 0, 0, 3, 2) * Simd32x4::from([0.0, -1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + 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]) * 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]) + self.group0() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
5440 }
5441}
5442
5443impl LeftContraction<MultiVector> for Motor {
5444 type Output = MultiVector;
5445
5446 fn left_contraction(self, other: MultiVector) -> MultiVector {
5447 MultiVector { groups: MultiVectorGroups { 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]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from(other.group3()[0]) * Simd32x4::from([-1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.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]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.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]), g2: Simd32x4::from(self.group0()[0]) * other.group2() + Simd32x4::from(self.group1()[1]) * swizzle!(other.group1(), 3, 3, 3, 2) * Simd32x4::from([0.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group2()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]), g3: Simd32x4::from(self.group0()[0]) * other.group3() + self.group0() * Simd32x4::from(other.group3()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
5448 }
5449}
5450
5451impl RightContraction<MultiVector> for Motor {
5452 type Output = MultiVector;
5453
5454 fn right_contraction(self, other: MultiVector) -> MultiVector {
5455 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()[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]) * other.group3() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group3()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group3()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group3()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(0.0) - Simd32x4::from(self.group1()[0]) * other.group2() + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group2()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group2()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + swizzle!(self.group1(), 1, 0, 0, 0) * swizzle!(other.group2(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g2: Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group1() + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group0()[0], self.group1()[1], self.group0()[1], self.group0()[1]]) * Simd32x4::from([other.group2()[0], other.group1()[0], other.group2()[3], other.group2()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]), g3: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5456 }
5457}
5458
5459impl ScalarProduct<MultiVector> for Motor {
5460 type Output = f32;
5461
5462 fn scalar_product(self, other: MultiVector) -> f32 {
5463 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.group3()[0] + self.group1()[1] * other.group3()[1] + self.group1()[2] * other.group3()[2] + self.group1()[3] * other.group3()[3]
5464 }
5465}
5466
5467impl Into<Rotor> for Motor {
5468 fn into(self) -> Rotor {
5469 Rotor { groups: RotorGroups { g0: self.group0() } }
5470 }
5471}
5472
5473impl Add<Rotor> for Motor {
5474 type Output = Motor;
5475
5476 fn add(self, other: Rotor) -> Motor {
5477 Motor { groups: MotorGroups { g0: self.group0() + other.group0(), g1: self.group1() } }
5478 }
5479}
5480
5481impl AddAssign<Rotor> for Motor {
5482 fn add_assign(&mut self, other: Rotor) {
5483 *self = (*self).add(other);
5484 }
5485}
5486
5487impl Sub<Rotor> for Motor {
5488 type Output = Motor;
5489
5490 fn sub(self, other: Rotor) -> Motor {
5491 Motor { groups: MotorGroups { g0: self.group0() - other.group0(), g1: self.group1() } }
5492 }
5493}
5494
5495impl SubAssign<Rotor> for Motor {
5496 fn sub_assign(&mut self, other: Rotor) {
5497 *self = (*self).sub(other);
5498 }
5499}
5500
5501impl GeometricProduct<Rotor> for Motor {
5502 type Output = Motor;
5503
5504 fn geometric_product(self, other: Rotor) -> Motor {
5505 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]), g1: 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]) } }
5506 }
5507}
5508
5509impl RegressiveProduct<Rotor> for Motor {
5510 type Output = Rotor;
5511
5512 fn regressive_product(self, other: Rotor) -> Rotor {
5513 Rotor { groups: RotorGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0() + 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.group1(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5514 }
5515}
5516
5517impl OuterProduct<Rotor> for Motor {
5518 type Output = Motor;
5519
5520 fn outer_product(self, other: Rotor) -> Motor {
5521 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]), g1: 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(), 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]) } }
5522 }
5523}
5524
5525impl InnerProduct<Rotor> for Motor {
5526 type Output = Motor;
5527
5528 fn inner_product(self, other: Rotor) -> Motor {
5529 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]), g1: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5530 }
5531}
5532
5533impl LeftContraction<Rotor> for Motor {
5534 type Output = Rotor;
5535
5536 fn left_contraction(self, other: Rotor) -> Rotor {
5537 Rotor { groups: RotorGroups { 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]) } }
5538 }
5539}
5540
5541impl RightContraction<Rotor> for Motor {
5542 type Output = Motor;
5543
5544 fn right_contraction(self, other: Rotor) -> Motor {
5545 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]), g1: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5546 }
5547}
5548
5549impl ScalarProduct<Rotor> for Motor {
5550 type Output = f32;
5551
5552 fn scalar_product(self, other: Rotor) -> f32 {
5553 self.group0()[0] * other.group0()[0] - self.group0()[1] * other.group0()[1] - self.group0()[2] * other.group0()[2] - self.group0()[3] * other.group0()[3]
5554 }
5555}
5556
5557impl GeometricProduct<Point> for Motor {
5558 type Output = PointAndPlane;
5559
5560 fn geometric_product(self, other: Point) -> PointAndPlane {
5561 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.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()[1], self.group1()[1], self.group0()[1], 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()[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]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
5562 }
5563}
5564
5565impl RegressiveProduct<Point> for Motor {
5566 type Output = PointAndPlane;
5567
5568 fn regressive_product(self, other: Point) -> PointAndPlane {
5569 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
5570 }
5571}
5572
5573impl OuterProduct<Point> for Motor {
5574 type Output = Point;
5575
5576 fn outer_product(self, other: Point) -> Point {
5577 Point { groups: PointGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
5578 }
5579}
5580
5581impl InnerProduct<Point> for Motor {
5582 type Output = PointAndPlane;
5583
5584 fn inner_product(self, other: Point) -> PointAndPlane {
5585 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: 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]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
5586 }
5587}
5588
5589impl LeftContraction<Point> for Motor {
5590 type Output = PointAndPlane;
5591
5592 fn left_contraction(self, other: Point) -> PointAndPlane {
5593 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0(), g1: 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()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
5594 }
5595}
5596
5597impl RightContraction<Point> for Motor {
5598 type Output = Plane;
5599
5600 fn right_contraction(self, other: Point) -> Plane {
5601 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
5602 }
5603}
5604
5605impl Into<IdealPoint> for Motor {
5606 fn into(self) -> IdealPoint {
5607 IdealPoint { groups: IdealPointGroups { g0: Simd32x3::from([self.group1()[1], self.group1()[2], self.group1()[3]]) } }
5608 }
5609}
5610
5611impl Add<IdealPoint> for Motor {
5612 type Output = Motor;
5613
5614 fn add(self, other: IdealPoint) -> Motor {
5615 Motor { groups: MotorGroups { g0: self.group0(), g1: self.group1() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5616 }
5617}
5618
5619impl AddAssign<IdealPoint> for Motor {
5620 fn add_assign(&mut self, other: IdealPoint) {
5621 *self = (*self).add(other);
5622 }
5623}
5624
5625impl Sub<IdealPoint> for Motor {
5626 type Output = Motor;
5627
5628 fn sub(self, other: IdealPoint) -> Motor {
5629 Motor { groups: MotorGroups { g0: self.group0(), g1: self.group1() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5630 }
5631}
5632
5633impl SubAssign<IdealPoint> for Motor {
5634 fn sub_assign(&mut self, other: IdealPoint) {
5635 *self = (*self).sub(other);
5636 }
5637}
5638
5639impl GeometricProduct<IdealPoint> for Motor {
5640 type Output = Motor;
5641
5642 fn geometric_product(self, other: IdealPoint) -> Motor {
5643 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group1()[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.group1()[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.group1()[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.group1()[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]), g1: 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]) } }
5644 }
5645}
5646
5647impl RegressiveProduct<IdealPoint> for Motor {
5648 type Output = Translator;
5649
5650 fn regressive_product(self, other: IdealPoint) -> Translator {
5651 Translator { groups: TranslatorGroups { 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]) + Simd32x4::from([self.group0()[1], self.group1()[0], self.group1()[0], self.group1()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5652 }
5653}
5654
5655impl LeftContraction<IdealPoint> for Motor {
5656 type Output = Translator;
5657
5658 fn left_contraction(self, other: IdealPoint) -> Translator {
5659 Translator { groups: TranslatorGroups { g0: 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]) + Simd32x4::from([self.group1()[1], self.group0()[0], self.group0()[0], self.group0()[0]]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5660 }
5661}
5662
5663impl RightContraction<IdealPoint> for Motor {
5664 type Output = Rotor;
5665
5666 fn right_contraction(self, other: IdealPoint) -> Rotor {
5667 Rotor { groups: RotorGroups { g0: 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]) + swizzle!(self.group1(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) } }
5668 }
5669}
5670
5671impl ScalarProduct<IdealPoint> for Motor {
5672 type Output = f32;
5673
5674 fn scalar_product(self, other: IdealPoint) -> f32 {
5675 self.group1()[1] * other.group0()[0] + self.group1()[2] * other.group0()[1] + self.group1()[3] * other.group0()[2]
5676 }
5677}
5678
5679impl GeometricProduct<Plane> for Motor {
5680 type Output = PointAndPlane;
5681
5682 fn geometric_product(self, other: Plane) -> PointAndPlane {
5683 PointAndPlane { groups: PointAndPlaneGroups { g0: 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]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[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.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
5684 }
5685}
5686
5687impl RegressiveProduct<Plane> for Motor {
5688 type Output = Plane;
5689
5690 fn regressive_product(self, other: Plane) -> Plane {
5691 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0() } }
5692 }
5693}
5694
5695impl OuterProduct<Plane> for Motor {
5696 type Output = PointAndPlane;
5697
5698 fn outer_product(self, other: Plane) -> PointAndPlane {
5699 PointAndPlane { groups: PointAndPlaneGroups { g0: 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()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[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.group0() } }
5700 }
5701}
5702
5703impl InnerProduct<Plane> for Motor {
5704 type Output = PointAndPlane;
5705
5706 fn inner_product(self, other: Plane) -> PointAndPlane {
5707 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
5708 }
5709}
5710
5711impl LeftContraction<Plane> for Motor {
5712 type Output = Plane;
5713
5714 fn left_contraction(self, other: Plane) -> Plane {
5715 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() } }
5716 }
5717}
5718
5719impl RightContraction<Plane> for Motor {
5720 type Output = PointAndPlane;
5721
5722 fn right_contraction(self, other: Plane) -> PointAndPlane {
5723 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
5724 }
5725}
5726
5727impl Into<Line> for Motor {
5728 fn into(self) -> Line {
5729 Line { groups: LineGroups { g0: Simd32x3::from([self.group1()[1], self.group1()[2], self.group1()[3]]), g1: Simd32x3::from([self.group0()[1], self.group0()[2], self.group0()[3]]) } }
5730 }
5731}
5732
5733impl Add<Line> for Motor {
5734 type Output = Motor;
5735
5736 fn add(self, other: Line) -> Motor {
5737 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from([other.group0()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: self.group1() + Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5738 }
5739}
5740
5741impl AddAssign<Line> for Motor {
5742 fn add_assign(&mut self, other: Line) {
5743 *self = (*self).add(other);
5744 }
5745}
5746
5747impl Sub<Line> for Motor {
5748 type Output = Motor;
5749
5750 fn sub(self, other: Line) -> Motor {
5751 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from([other.group0()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: self.group1() - Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5752 }
5753}
5754
5755impl SubAssign<Line> for Motor {
5756 fn sub_assign(&mut self, other: Line) {
5757 *self = (*self).sub(other);
5758 }
5759}
5760
5761impl GeometricProduct<Line> for Motor {
5762 type Output = Motor;
5763
5764 fn geometric_product(self, other: Line) -> Motor {
5765 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) + Simd32x4::from(self.group1()[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.group1()[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.group1()[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.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]), g1: 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.group1()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[1], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[2], other.group1()[1], other.group1()[0], other.group1()[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]) } }
5766 }
5767}
5768
5769impl ScalarProduct<Line> for Motor {
5770 type Output = f32;
5771
5772 fn scalar_product(self, other: Line) -> f32 {
5773 0.0 - self.group0()[1] * other.group1()[0] - self.group0()[2] * other.group1()[1] - self.group0()[3] * other.group1()[2] + self.group1()[1] * other.group0()[0] + self.group1()[2] * other.group0()[1] + self.group1()[3] * other.group0()[2]
5774 }
5775}
5776
5777impl Into<Translator> for Motor {
5778 fn into(self) -> Translator {
5779 Translator { groups: TranslatorGroups { g0: Simd32x4::from([self.group0()[0], self.group1()[1], self.group1()[2], self.group1()[3]]) } }
5780 }
5781}
5782
5783impl Add<Translator> for Motor {
5784 type Output = Motor;
5785
5786 fn add(self, other: Translator) -> Motor {
5787 Motor { groups: MotorGroups { g0: self.group0() + Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() + other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5788 }
5789}
5790
5791impl AddAssign<Translator> for Motor {
5792 fn add_assign(&mut self, other: Translator) {
5793 *self = (*self).add(other);
5794 }
5795}
5796
5797impl Sub<Translator> for Motor {
5798 type Output = Motor;
5799
5800 fn sub(self, other: Translator) -> Motor {
5801 Motor { groups: MotorGroups { g0: self.group0() - Simd32x4::from(other.group0()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: self.group1() - other.group0() * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5802 }
5803}
5804
5805impl SubAssign<Translator> for Motor {
5806 fn sub_assign(&mut self, other: Translator) {
5807 *self = (*self).sub(other);
5808 }
5809}
5810
5811impl GeometricProduct<Translator> for Motor {
5812 type Output = Motor;
5813
5814 fn geometric_product(self, other: Translator) -> Motor {
5815 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.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()[0], self.group0()[0], self.group0()[0]]) * other.group0() } }
5816 }
5817}
5818
5819impl RegressiveProduct<Translator> for Motor {
5820 type Output = Translator;
5821
5822 fn regressive_product(self, other: Translator) -> Translator {
5823 Translator { groups: TranslatorGroups { 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()[3]) * Simd32x4::from(other.group0()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group0() + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5824 }
5825}
5826
5827impl OuterProduct<Translator> for Motor {
5828 type Output = Motor;
5829
5830 fn outer_product(self, other: Translator) -> Motor {
5831 Motor { groups: MotorGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: 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]) + 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(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 1, 2, 3) } }
5832 }
5833}
5834
5835impl InnerProduct<Translator> for Motor {
5836 type Output = Motor;
5837
5838 fn inner_product(self, other: Translator) -> Motor {
5839 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: 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()[0], self.group0()[0], self.group0()[0]]) * other.group0() } }
5840 }
5841}
5842
5843impl LeftContraction<Translator> for Motor {
5844 type Output = Translator;
5845
5846 fn left_contraction(self, other: Translator) -> Translator {
5847 Translator { groups: TranslatorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + 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.group1(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) } }
5848 }
5849}
5850
5851impl RightContraction<Translator> for Motor {
5852 type Output = Motor;
5853
5854 fn right_contraction(self, other: Translator) -> Motor {
5855 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: self.group1() * Simd32x4::from(other.group0()[0]) } }
5856 }
5857}
5858
5859impl ScalarProduct<Translator> for Motor {
5860 type Output = f32;
5861
5862 fn scalar_product(self, other: Translator) -> f32 {
5863 self.group0()[0] * other.group0()[0] + self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2] + self.group1()[3] * other.group0()[3]
5864 }
5865}
5866
5867impl Add<Motor> for Motor {
5868 type Output = Motor;
5869
5870 fn add(self, other: Motor) -> Motor {
5871 Motor { groups: MotorGroups { g0: self.group0() + other.group0(), g1: self.group1() + other.group1() } }
5872 }
5873}
5874
5875impl AddAssign<Motor> for Motor {
5876 fn add_assign(&mut self, other: Motor) {
5877 *self = (*self).add(other);
5878 }
5879}
5880
5881impl Sub<Motor> for Motor {
5882 type Output = Motor;
5883
5884 fn sub(self, other: Motor) -> Motor {
5885 Motor { groups: MotorGroups { g0: self.group0() - other.group0(), g1: self.group1() - other.group1() } }
5886 }
5887}
5888
5889impl SubAssign<Motor> for Motor {
5890 fn sub_assign(&mut self, other: Motor) {
5891 *self = (*self).sub(other);
5892 }
5893}
5894
5895impl Mul<Motor> for Motor {
5896 type Output = Motor;
5897
5898 fn mul(self, other: Motor) -> Motor {
5899 Motor { groups: MotorGroups { g0: self.group0() * other.group0(), g1: self.group1() * other.group1() } }
5900 }
5901}
5902
5903impl MulAssign<Motor> for Motor {
5904 fn mul_assign(&mut self, other: Motor) {
5905 *self = (*self).mul(other);
5906 }
5907}
5908
5909impl Div<Motor> for Motor {
5910 type Output = Motor;
5911
5912 fn div(self, other: Motor) -> Motor {
5913 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]), 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]) } }
5914 }
5915}
5916
5917impl DivAssign<Motor> for Motor {
5918 fn div_assign(&mut self, other: Motor) {
5919 *self = (*self).div(other);
5920 }
5921}
5922
5923impl GeometricProduct<Motor> for Motor {
5924 type Output = Motor;
5925
5926 fn geometric_product(self, other: Motor) -> Motor {
5927 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]) + 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([1.0, 1.0, -1.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]) * 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]) } }
5928 }
5929}
5930
5931impl RegressiveProduct<Motor> for Motor {
5932 type Output = Motor;
5933
5934 fn regressive_product(self, other: Motor) -> Motor {
5935 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group1(), 1, 0, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[0]) * other.group0() + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]), g1: Simd32x4::from(self.group1()[0]) * other.group1() + self.group1() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5936 }
5937}
5938
5939impl OuterProduct<Motor> for Motor {
5940 type Output = Motor;
5941
5942 fn outer_product(self, other: Motor) -> Motor {
5943 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]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group1()[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]) * 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]) } }
5944 }
5945}
5946
5947impl InnerProduct<Motor> for Motor {
5948 type Output = Motor;
5949
5950 fn inner_product(self, other: Motor) -> Motor {
5951 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]) + 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, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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]) + swizzle!(self.group0(), 1, 1, 0, 0) * swizzle!(other.group0(), 1, 0, 0, 0) * Simd32x4::from([-1.0, 1.0, 0.0, 0.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + 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]) * 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]) + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
5952 }
5953}
5954
5955impl LeftContraction<Motor> for Motor {
5956 type Output = Motor;
5957
5958 fn left_contraction(self, other: Motor) -> Motor {
5959 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]) + 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, 1, 1) * Simd32x4::from([1.0, 1.0, 0.0, 0.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]) + 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() + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
5960 }
5961}
5962
5963impl RightContraction<Motor> for Motor {
5964 type Output = Motor;
5965
5966 fn right_contraction(self, other: Motor) -> Motor {
5967 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.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]) * Simd32x4::from(other.group1()[2]) * Simd32x4::from([1.0, 0.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group1()[3]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + self.group1() * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 1.0, 1.0]) } }
5968 }
5969}
5970
5971impl ScalarProduct<Motor> for Motor {
5972 type Output = f32;
5973
5974 fn scalar_product(self, other: Motor) -> f32 {
5975 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]
5976 }
5977}
5978
5979impl Add<PointAndPlane> for Motor {
5980 type Output = MultiVector;
5981
5982 fn add(self, other: PointAndPlane) -> MultiVector {
5983 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]), g2: Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]), g3: self.group1() } }
5984 }
5985}
5986
5987impl Sub<PointAndPlane> for Motor {
5988 type Output = MultiVector;
5989
5990 fn sub(self, other: PointAndPlane) -> MultiVector {
5991 MultiVector { groups: MultiVectorGroups { g0: self.group0(), g1: Simd32x4::from(0.0) - Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]), g2: Simd32x4::from(0.0) - Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]), g3: self.group1() } }
5992 }
5993}
5994
5995impl GeometricProduct<PointAndPlane> for Motor {
5996 type Output = PointAndPlane;
5997
5998 fn geometric_product(self, other: PointAndPlane) -> PointAndPlane {
5999 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[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]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.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.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
6000 }
6001}
6002
6003impl RegressiveProduct<PointAndPlane> for Motor {
6004 type Output = PointAndPlane;
6005
6006 fn regressive_product(self, other: PointAndPlane) -> PointAndPlane {
6007 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group0(), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group1() + 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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
6008 }
6009}
6010
6011impl OuterProduct<PointAndPlane> for Motor {
6012 type Output = PointAndPlane;
6013
6014 fn outer_product(self, other: PointAndPlane) -> PointAndPlane {
6015 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 2, 2, 0, 2) * Simd32x4::from([1.0, 0.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 3, 3, 3, 0) * Simd32x4::from([1.0, 0.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() } }
6016 }
6017}
6018
6019impl InnerProduct<PointAndPlane> for Motor {
6020 type Output = PointAndPlane;
6021
6022 fn inner_product(self, other: PointAndPlane) -> PointAndPlane {
6023 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * other.group0() + Simd32x4::from(self.group1()[0]) * other.group1() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.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.group1()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) } }
6024 }
6025}
6026
6027impl LeftContraction<PointAndPlane> for Motor {
6028 type Output = PointAndPlane;
6029
6030 fn left_contraction(self, other: PointAndPlane) -> PointAndPlane {
6031 PointAndPlane { groups: PointAndPlaneGroups { 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, 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()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) } }
6032 }
6033}
6034
6035impl RightContraction<PointAndPlane> for Motor {
6036 type Output = PointAndPlane;
6037
6038 fn right_contraction(self, other: PointAndPlane) -> PointAndPlane {
6039 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * other.group1() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group1(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group1(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group0() * 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.group1()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group1(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
6040 }
6041}
6042
6043impl SquaredMagnitude for Motor {
6044 type Output = f32;
6045
6046 fn squared_magnitude(self) -> f32 {
6047 self.scalar_product(self.reversal())
6048 }
6049}
6050
6051impl Magnitude for Motor {
6052 type Output = f32;
6053
6054 fn magnitude(self) -> f32 {
6055 self.squared_magnitude().sqrt()
6056 }
6057}
6058
6059impl Mul<f32> for Motor {
6060 type Output = Motor;
6061
6062 fn mul(self, other: f32) -> Motor {
6063 self.geometric_product(other)
6064 }
6065}
6066
6067impl MulAssign<f32> for Motor {
6068 fn mul_assign(&mut self, other: f32) {
6069 *self = (*self).mul(other);
6070 }
6071}
6072
6073impl Signum for Motor {
6074 type Output = Motor;
6075
6076 fn signum(self) -> Motor {
6077 self.geometric_product(1.0 / self.magnitude())
6078 }
6079}
6080
6081impl Inverse for Motor {
6082 type Output = Motor;
6083
6084 fn inverse(self) -> Motor {
6085 self.reversal().geometric_product(1.0 / self.squared_magnitude())
6086 }
6087}
6088
6089impl Zero for PointAndPlane {
6090 fn zero() -> Self {
6091 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(0.0), g1: Simd32x4::from(0.0) } }
6092 }
6093}
6094
6095impl One for PointAndPlane {
6096 fn one() -> Self {
6097 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(0.0), g1: Simd32x4::from(0.0) } }
6098 }
6099}
6100
6101impl Neg for PointAndPlane {
6102 type Output = PointAndPlane;
6103
6104 fn neg(self) -> PointAndPlane {
6105 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(-1.0), g1: self.group1() * Simd32x4::from(-1.0) } }
6106 }
6107}
6108
6109impl Automorphism for PointAndPlane {
6110 type Output = PointAndPlane;
6111
6112 fn automorphism(self) -> PointAndPlane {
6113 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(-1.0), g1: self.group1() * Simd32x4::from(-1.0) } }
6114 }
6115}
6116
6117impl Reversal for PointAndPlane {
6118 type Output = PointAndPlane;
6119
6120 fn reversal(self) -> PointAndPlane {
6121 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(-1.0), g1: self.group1() } }
6122 }
6123}
6124
6125impl Conjugation for PointAndPlane {
6126 type Output = PointAndPlane;
6127
6128 fn conjugation(self) -> PointAndPlane {
6129 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0(), g1: self.group1() * Simd32x4::from(-1.0) } }
6130 }
6131}
6132
6133impl Dual for PointAndPlane {
6134 type Output = PointAndPlane;
6135
6136 fn dual(self) -> PointAndPlane {
6137 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group1(), g1: self.group0() * Simd32x4::from(-1.0) } }
6138 }
6139}
6140
6141impl GeometricProduct<f32> for PointAndPlane {
6142 type Output = PointAndPlane;
6143
6144 fn geometric_product(self, other: f32) -> PointAndPlane {
6145 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
6146 }
6147}
6148
6149impl OuterProduct<f32> for PointAndPlane {
6150 type Output = PointAndPlane;
6151
6152 fn outer_product(self, other: f32) -> PointAndPlane {
6153 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
6154 }
6155}
6156
6157impl InnerProduct<f32> for PointAndPlane {
6158 type Output = PointAndPlane;
6159
6160 fn inner_product(self, other: f32) -> PointAndPlane {
6161 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
6162 }
6163}
6164
6165impl RightContraction<f32> for PointAndPlane {
6166 type Output = PointAndPlane;
6167
6168 fn right_contraction(self, other: f32) -> PointAndPlane {
6169 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other), g1: self.group1() * Simd32x4::from(other) } }
6170 }
6171}
6172
6173impl Add<MultiVector> for PointAndPlane {
6174 type Output = MultiVector;
6175
6176 fn add(self, other: MultiVector) -> MultiVector {
6177 MultiVector { groups: MultiVectorGroups { g0: other.group0(), g1: Simd32x4::from([self.group1()[0], self.group0()[1], self.group0()[2], self.group0()[3]]) + other.group1(), g2: Simd32x4::from([self.group0()[0], self.group1()[1], self.group1()[2], self.group1()[3]]) + other.group2(), g3: other.group3() } }
6178 }
6179}
6180
6181impl Sub<MultiVector> for PointAndPlane {
6182 type Output = MultiVector;
6183
6184 fn sub(self, other: MultiVector) -> MultiVector {
6185 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: Simd32x4::from([self.group1()[0], self.group0()[1], self.group0()[2], self.group0()[3]]) - other.group1(), g2: Simd32x4::from([self.group0()[0], self.group1()[1], self.group1()[2], self.group1()[3]]) - other.group2(), g3: Simd32x4::from(0.0) - other.group3() } }
6186 }
6187}
6188
6189impl GeometricProduct<MultiVector> for PointAndPlane {
6190 type Output = MultiVector;
6191
6192 fn geometric_product(self, other: MultiVector) -> MultiVector {
6193 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(self.group0()[0]) * other.group2() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + 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([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.group2(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * other.group3() + 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]) + Simd32x4::from(self.group1()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]), g2: Simd32x4::from(self.group0()[0]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * swizzle!(other.group3(), 1, 0, 3, 2) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group3(), 2, 3, 0, 1) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group3(), 3, 2, 1, 0) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) - Simd32x4::from(self.group1()[0]) * other.group3() + 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]), g3: Simd32x4::from(0.0) - Simd32x4::from(self.group0()[0]) * other.group1() + Simd32x4::from(self.group0()[1]) * swizzle!(other.group2(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group2(), 2, 3, 0, 1) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group2(), 3, 2, 1, 0) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * other.group2() + 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]) } }
6194 }
6195}
6196
6197impl ScalarProduct<MultiVector> for PointAndPlane {
6198 type Output = f32;
6199
6200 fn scalar_product(self, other: MultiVector) -> f32 {
6201 0.0 - self.group0()[0] * other.group2()[0] + self.group0()[1] * other.group1()[1] + self.group0()[2] * other.group1()[2] + self.group0()[3] * other.group1()[3] - self.group1()[0] * other.group1()[0] + self.group1()[1] * other.group2()[1] + self.group1()[2] * other.group2()[2] + self.group1()[3] * other.group2()[3]
6202 }
6203}
6204
6205impl GeometricProduct<Rotor> for PointAndPlane {
6206 type Output = PointAndPlane;
6207
6208 fn geometric_product(self, other: Rotor) -> PointAndPlane {
6209 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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, 1, 1, 1) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]), g1: 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]) + 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(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
6210 }
6211}
6212
6213impl OuterProduct<Rotor> for PointAndPlane {
6214 type Output = PointAndPlane;
6215
6216 fn outer_product(self, other: Rotor) -> PointAndPlane {
6217 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group0()[1]) * Simd32x4::from([1.0, 0.0, 0.0, 0.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]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: self.group1() * Simd32x4::from(other.group0()[0]) } }
6218 }
6219}
6220
6221impl InnerProduct<Rotor> for PointAndPlane {
6222 type Output = PointAndPlane;
6223
6224 fn inner_product(self, other: Rotor) -> PointAndPlane {
6225 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: 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]) + 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(), 0, 0, 3, 2) * Simd32x4::from([0.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 0, 1) * Simd32x4::from([0.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 0) * Simd32x4::from([0.0, 1.0, -1.0, 1.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
6226 }
6227}
6228
6229impl RightContraction<Rotor> for PointAndPlane {
6230 type Output = PointAndPlane;
6231
6232 fn right_contraction(self, other: Rotor) -> PointAndPlane {
6233 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: 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]) + 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(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
6234 }
6235}
6236
6237impl Into<Point> for PointAndPlane {
6238 fn into(self) -> Point {
6239 Point { groups: PointGroups { g0: self.group0() } }
6240 }
6241}
6242
6243impl Add<Point> for PointAndPlane {
6244 type Output = PointAndPlane;
6245
6246 fn add(self, other: Point) -> PointAndPlane {
6247 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() + other.group0(), g1: self.group1() } }
6248 }
6249}
6250
6251impl AddAssign<Point> for PointAndPlane {
6252 fn add_assign(&mut self, other: Point) {
6253 *self = (*self).add(other);
6254 }
6255}
6256
6257impl Sub<Point> for PointAndPlane {
6258 type Output = PointAndPlane;
6259
6260 fn sub(self, other: Point) -> PointAndPlane {
6261 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() - other.group0(), g1: self.group1() } }
6262 }
6263}
6264
6265impl SubAssign<Point> for PointAndPlane {
6266 fn sub_assign(&mut self, other: Point) {
6267 *self = (*self).sub(other);
6268 }
6269}
6270
6271impl GeometricProduct<Point> for PointAndPlane {
6272 type Output = Motor;
6273
6274 fn geometric_product(self, other: Point) -> Motor {
6275 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.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.group0()[0], self.group1()[0], self.group1()[0], self.group1()[0]]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from([self.group1()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
6276 }
6277}
6278
6279impl RightContraction<Point> for PointAndPlane {
6280 type Output = f32;
6281
6282 fn right_contraction(self, other: Point) -> f32 {
6283 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]
6284 }
6285}
6286
6287impl ScalarProduct<Point> for PointAndPlane {
6288 type Output = f32;
6289
6290 fn scalar_product(self, other: Point) -> f32 {
6291 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]
6292 }
6293}
6294
6295impl GeometricProduct<IdealPoint> for PointAndPlane {
6296 type Output = PointAndPlane;
6297
6298 fn geometric_product(self, other: IdealPoint) -> PointAndPlane {
6299 PointAndPlane { groups: PointAndPlaneGroups { 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]) + 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()[2], other.group0()[2], other.group0()[2], other.group0()[0]]) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + swizzle!(self.group0(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]), g1: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[0]]) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) + 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]) + Simd32x4::from([self.group1()[1], self.group0()[0], self.group0()[1], 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]) } }
6300 }
6301}
6302
6303impl RegressiveProduct<IdealPoint> for PointAndPlane {
6304 type Output = Plane;
6305
6306 fn regressive_product(self, other: IdealPoint) -> Plane {
6307 Plane { groups: PlaneGroups { 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]) } }
6308 }
6309}
6310
6311impl InnerProduct<IdealPoint> for PointAndPlane {
6312 type Output = Plane;
6313
6314 fn inner_product(self, other: IdealPoint) -> Plane {
6315 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[2], other.group0()[2], other.group0()[0]]) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group0()[0], other.group0()[1]]) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) + 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]) + Simd32x4::from([self.group1()[1], self.group0()[0], self.group0()[1], 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]) } }
6316 }
6317}
6318
6319impl LeftContraction<IdealPoint> for PointAndPlane {
6320 type Output = Plane;
6321
6322 fn left_contraction(self, other: IdealPoint) -> Plane {
6323 Plane { groups: PlaneGroups { g0: 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]) + swizzle!(self.group1(), 1, 0, 0, 0) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group0()[1], other.group0()[2]]) * Simd32x4::from(-1.0) } }
6324 }
6325}
6326
6327impl Into<Plane> for PointAndPlane {
6328 fn into(self) -> Plane {
6329 Plane { groups: PlaneGroups { g0: self.group1() } }
6330 }
6331}
6332
6333impl Add<Plane> for PointAndPlane {
6334 type Output = PointAndPlane;
6335
6336 fn add(self, other: Plane) -> PointAndPlane {
6337 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0(), g1: self.group1() + other.group0() } }
6338 }
6339}
6340
6341impl AddAssign<Plane> for PointAndPlane {
6342 fn add_assign(&mut self, other: Plane) {
6343 *self = (*self).add(other);
6344 }
6345}
6346
6347impl Sub<Plane> for PointAndPlane {
6348 type Output = PointAndPlane;
6349
6350 fn sub(self, other: Plane) -> PointAndPlane {
6351 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0(), g1: self.group1() - other.group0() } }
6352 }
6353}
6354
6355impl SubAssign<Plane> for PointAndPlane {
6356 fn sub_assign(&mut self, other: Plane) {
6357 *self = (*self).sub(other);
6358 }
6359}
6360
6361impl GeometricProduct<Plane> for PointAndPlane {
6362 type Output = Motor;
6363
6364 fn geometric_product(self, other: Plane) -> Motor {
6365 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from(other.group0()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group1()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[1]) * swizzle!(other.group0(), 1, 1, 3, 2) * Simd32x4::from([-1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 2, 3, 2, 1) * Simd32x4::from([-1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 3, 2, 1, 3) * Simd32x4::from([-1.0, -1.0, 1.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.group0()[0], self.group1()[0], self.group1()[0], self.group1()[0]]) * other.group0() * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
6366 }
6367}
6368
6369impl RegressiveProduct<Plane> for PointAndPlane {
6370 type Output = f32;
6371
6372 fn regressive_product(self, other: Plane) -> f32 {
6373 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]
6374 }
6375}
6376
6377impl LeftContraction<Plane> for PointAndPlane {
6378 type Output = f32;
6379
6380 fn left_contraction(self, other: Plane) -> f32 {
6381 0.0 - self.group1()[0] * other.group0()[0] + self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2] + self.group1()[3] * other.group0()[3]
6382 }
6383}
6384
6385impl ScalarProduct<Plane> for PointAndPlane {
6386 type Output = f32;
6387
6388 fn scalar_product(self, other: Plane) -> f32 {
6389 0.0 - self.group1()[0] * other.group0()[0] + self.group1()[1] * other.group0()[1] + self.group1()[2] * other.group0()[2] + self.group1()[3] * other.group0()[3]
6390 }
6391}
6392
6393impl GeometricProduct<Line> for PointAndPlane {
6394 type Output = PointAndPlane;
6395
6396 fn geometric_product(self, other: Line) -> PointAndPlane {
6397 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[0], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[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]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[0], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
6398 }
6399}
6400
6401impl RegressiveProduct<Line> for PointAndPlane {
6402 type Output = Plane;
6403
6404 fn regressive_product(self, other: Line) -> Plane {
6405 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[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]) } }
6406 }
6407}
6408
6409impl OuterProduct<Line> for PointAndPlane {
6410 type Output = Point;
6411
6412 fn outer_product(self, other: Line) -> Point {
6413 Point { groups: PointGroups { g0: Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group0()[2], other.group0()[1]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
6414 }
6415}
6416
6417impl InnerProduct<Line> for PointAndPlane {
6418 type Output = Plane;
6419
6420 fn inner_product(self, other: Line) -> Plane {
6421 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[0], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
6422 }
6423}
6424
6425impl LeftContraction<Line> for PointAndPlane {
6426 type Output = Plane;
6427
6428 fn left_contraction(self, other: Line) -> Plane {
6429 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[0], other.group0()[0], other.group1()[2], other.group1()[1]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[1], other.group1()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[2], other.group1()[1], other.group1()[0], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[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]) } }
6430 }
6431}
6432
6433impl RightContraction<Line> for PointAndPlane {
6434 type Output = Plane;
6435
6436 fn right_contraction(self, other: Line) -> Plane {
6437 Plane { groups: PlaneGroups { g0: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[0], other.group1()[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.group1()[1], other.group0()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[2], other.group0()[1], other.group0()[0], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group1()[0], other.group1()[1], other.group1()[2]]) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) } }
6438 }
6439}
6440
6441impl GeometricProduct<Translator> for PointAndPlane {
6442 type Output = PointAndPlane;
6443
6444 fn geometric_product(self, other: Translator) -> PointAndPlane {
6445 PointAndPlane { groups: PointAndPlaneGroups { 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]) + Simd32x4::from(self.group1()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + Simd32x4::from([self.group0()[1], self.group0()[1], self.group1()[1], self.group1()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group0() * 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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) } }
6446 }
6447}
6448
6449impl RegressiveProduct<Translator> for PointAndPlane {
6450 type Output = Plane;
6451
6452 fn regressive_product(self, other: Translator) -> Plane {
6453 Plane { groups: PlaneGroups { 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()[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, 1, 2, 3) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) } }
6454 }
6455}
6456
6457impl OuterProduct<Translator> for PointAndPlane {
6458 type Output = PointAndPlane;
6459
6460 fn outer_product(self, other: Translator) -> PointAndPlane {
6461 PointAndPlane { groups: PointAndPlaneGroups { g0: 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(), 3, 3, 3, 1) * Simd32x4::from([0.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: self.group1() * Simd32x4::from(other.group0()[0]) } }
6462 }
6463}
6464
6465impl InnerProduct<Translator> for PointAndPlane {
6466 type Output = PointAndPlane;
6467
6468 fn inner_product(self, other: Translator) -> PointAndPlane {
6469 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[0]) * other.group0() * 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()[1], self.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 1, 0, 3, 2) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) } }
6470 }
6471}
6472
6473impl LeftContraction<Translator> for PointAndPlane {
6474 type Output = Plane;
6475
6476 fn left_contraction(self, other: Translator) -> Plane {
6477 Plane { groups: PlaneGroups { g0: 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.group1(), 1, 0, 0, 0) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from(-1.0) } }
6478 }
6479}
6480
6481impl RightContraction<Translator> for PointAndPlane {
6482 type Output = PointAndPlane;
6483
6484 fn right_contraction(self, other: Translator) -> PointAndPlane {
6485 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[2]) * swizzle!(other.group0(), 3, 3, 3, 1) * Simd32x4::from([0.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * swizzle!(other.group0(), 2, 2, 1, 2) * Simd32x4::from([0.0, 1.0, -1.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.group1()[1], self.group0()[1], self.group0()[1]]) * swizzle!(other.group0(), 0, 0, 3, 2) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) } }
6486 }
6487}
6488
6489impl Add<Motor> for PointAndPlane {
6490 type Output = MultiVector;
6491
6492 fn add(self, other: Motor) -> MultiVector {
6493 MultiVector { groups: MultiVectorGroups { g0: other.group0(), g1: Simd32x4::from([self.group1()[0], self.group0()[1], self.group0()[2], self.group0()[3]]), g2: Simd32x4::from([self.group0()[0], self.group1()[1], self.group1()[2], self.group1()[3]]), g3: other.group1() } }
6494 }
6495}
6496
6497impl Sub<Motor> for PointAndPlane {
6498 type Output = MultiVector;
6499
6500 fn sub(self, other: Motor) -> MultiVector {
6501 MultiVector { groups: MultiVectorGroups { g0: Simd32x4::from(0.0) - other.group0(), g1: Simd32x4::from([self.group1()[0], self.group0()[1], self.group0()[2], self.group0()[3]]), g2: Simd32x4::from([self.group0()[0], self.group1()[1], self.group1()[2], self.group1()[3]]), g3: Simd32x4::from(0.0) - other.group1() } }
6502 }
6503}
6504
6505impl GeometricProduct<Motor> for PointAndPlane {
6506 type Output = PointAndPlane;
6507
6508 fn geometric_product(self, other: Motor) -> PointAndPlane {
6509 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) - Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group1()[0], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group1()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
6510 }
6511}
6512
6513impl RegressiveProduct<Motor> for PointAndPlane {
6514 type Output = PointAndPlane;
6515
6516 fn regressive_product(self, other: Motor) -> PointAndPlane {
6517 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group1()[0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group1()[1], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[2], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + Simd32x4::from([self.group1()[0], self.group0()[0], self.group0()[0], self.group0()[0]]) * other.group1() } }
6518 }
6519}
6520
6521impl OuterProduct<Motor> for PointAndPlane {
6522 type Output = PointAndPlane;
6523
6524 fn outer_product(self, other: Motor) -> PointAndPlane {
6525 PointAndPlane { groups: PointAndPlaneGroups { g0: Simd32x4::from(self.group1()[0]) * swizzle!(other.group0(), 1, 1, 2, 3) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 0.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[2], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 0.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[3]]) * Simd32x4::from([1.0, -1.0, 1.0, 0.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: self.group1() * Simd32x4::from(other.group0()[0]) } }
6526 }
6527}
6528
6529impl InnerProduct<Motor> for PointAndPlane {
6530 type Output = PointAndPlane;
6531
6532 fn inner_product(self, other: Motor) -> PointAndPlane {
6533 PointAndPlane { groups: PointAndPlaneGroups { g0: 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]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 1.0, 0.0, 0.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 1.0, 0.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from(other.group1()[0]) * Simd32x4::from([0.0, 0.0, 0.0, 1.0]) + self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group1()[0], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group0()[0], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group0()[0]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) } }
6534 }
6535}
6536
6537impl LeftContraction<Motor> for PointAndPlane {
6538 type Output = PointAndPlane;
6539
6540 fn left_contraction(self, other: Motor) -> PointAndPlane {
6541 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group1() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]), g1: Simd32x4::from(self.group1()[0]) * swizzle!(other.group1(), 1, 1, 2, 3) * Simd32x4::from([0.0, -1.0, -1.0, -1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[1], other.group1()[1], other.group0()[3], other.group0()[2]]) * Simd32x4::from([-1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group0()[3], other.group1()[2], other.group0()[1]]) * Simd32x4::from([-1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group0()[2], other.group0()[1], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, -1.0, 0.0]) + self.group0() * Simd32x4::from(other.group1()[0]) * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
6542 }
6543}
6544
6545impl RightContraction<Motor> for PointAndPlane {
6546 type Output = PointAndPlane;
6547
6548 fn right_contraction(self, other: Motor) -> PointAndPlane {
6549 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * Simd32x4::from(other.group0()[0]), g1: Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group0()[1], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 0.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group1()[3], other.group0()[2], other.group1()[1]]) * Simd32x4::from([1.0, -1.0, 0.0, 1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group1()[2], other.group1()[1], other.group0()[3]]) * Simd32x4::from([1.0, 1.0, -1.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()[0], self.group0()[0], self.group0()[0]]) * other.group0() * Simd32x4::from([1.0, -1.0, -1.0, -1.0]) } }
6550 }
6551}
6552
6553impl Add<PointAndPlane> for PointAndPlane {
6554 type Output = PointAndPlane;
6555
6556 fn add(self, other: PointAndPlane) -> PointAndPlane {
6557 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() + other.group0(), g1: self.group1() + other.group1() } }
6558 }
6559}
6560
6561impl AddAssign<PointAndPlane> for PointAndPlane {
6562 fn add_assign(&mut self, other: PointAndPlane) {
6563 *self = (*self).add(other);
6564 }
6565}
6566
6567impl Sub<PointAndPlane> for PointAndPlane {
6568 type Output = PointAndPlane;
6569
6570 fn sub(self, other: PointAndPlane) -> PointAndPlane {
6571 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() - other.group0(), g1: self.group1() - other.group1() } }
6572 }
6573}
6574
6575impl SubAssign<PointAndPlane> for PointAndPlane {
6576 fn sub_assign(&mut self, other: PointAndPlane) {
6577 *self = (*self).sub(other);
6578 }
6579}
6580
6581impl Mul<PointAndPlane> for PointAndPlane {
6582 type Output = PointAndPlane;
6583
6584 fn mul(self, other: PointAndPlane) -> PointAndPlane {
6585 PointAndPlane { groups: PointAndPlaneGroups { g0: self.group0() * other.group0(), g1: self.group1() * other.group1() } }
6586 }
6587}
6588
6589impl MulAssign<PointAndPlane> for PointAndPlane {
6590 fn mul_assign(&mut self, other: PointAndPlane) {
6591 *self = (*self).mul(other);
6592 }
6593}
6594
6595impl Div<PointAndPlane> for PointAndPlane {
6596 type Output = PointAndPlane;
6597
6598 fn div(self, other: PointAndPlane) -> PointAndPlane {
6599 PointAndPlane { groups: PointAndPlaneGroups { 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]) } }
6600 }
6601}
6602
6603impl DivAssign<PointAndPlane> for PointAndPlane {
6604 fn div_assign(&mut self, other: PointAndPlane) {
6605 *self = (*self).div(other);
6606 }
6607}
6608
6609impl GeometricProduct<PointAndPlane> for PointAndPlane {
6610 type Output = Motor;
6611
6612 fn geometric_product(self, other: PointAndPlane) -> Motor {
6613 Motor { groups: MotorGroups { g0: Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) * Simd32x4::from([-1.0, 1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([1.0, -1.0, 1.0, 1.0]), g1: Simd32x4::from(0.0) - Simd32x4::from(self.group0()[0]) * Simd32x4::from([other.group1()[0], other.group0()[1], other.group0()[2], other.group0()[3]]) + Simd32x4::from(self.group0()[1]) * Simd32x4::from([other.group1()[1], other.group0()[0], other.group1()[3], other.group1()[2]]) * Simd32x4::from([-1.0, 1.0, -1.0, 1.0]) + Simd32x4::from(self.group0()[2]) * Simd32x4::from([other.group1()[2], other.group1()[3], other.group0()[0], other.group1()[1]]) * Simd32x4::from([-1.0, 1.0, 1.0, -1.0]) + Simd32x4::from(self.group0()[3]) * Simd32x4::from([other.group1()[3], other.group1()[2], other.group1()[1], other.group0()[0]]) * Simd32x4::from([-1.0, -1.0, 1.0, 1.0]) + Simd32x4::from(self.group1()[0]) * Simd32x4::from([other.group0()[0], other.group1()[1], other.group1()[2], other.group1()[3]]) + Simd32x4::from(self.group1()[1]) * Simd32x4::from([other.group0()[1], other.group1()[0], other.group0()[3], other.group0()[2]]) * Simd32x4::from([1.0, -1.0, 1.0, -1.0]) + Simd32x4::from(self.group1()[2]) * Simd32x4::from([other.group0()[2], other.group0()[3], other.group1()[0], other.group0()[1]]) * Simd32x4::from([1.0, -1.0, -1.0, 1.0]) + Simd32x4::from(self.group1()[3]) * Simd32x4::from([other.group0()[3], other.group0()[2], other.group0()[1], other.group1()[0]]) * Simd32x4::from([1.0, 1.0, -1.0, -1.0]) } }
6614 }
6615}
6616
6617impl ScalarProduct<PointAndPlane> for PointAndPlane {
6618 type Output = f32;
6619
6620 fn scalar_product(self, other: PointAndPlane) -> f32 {
6621 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] - self.group1()[0] * other.group1()[0] + self.group1()[1] * other.group1()[1] + self.group1()[2] * other.group1()[2] + self.group1()[3] * other.group1()[3]
6622 }
6623}
6624
6625impl SquaredMagnitude for PointAndPlane {
6626 type Output = f32;
6627
6628 fn squared_magnitude(self) -> f32 {
6629 self.scalar_product(self.reversal())
6630 }
6631}
6632
6633impl Magnitude for PointAndPlane {
6634 type Output = f32;
6635
6636 fn magnitude(self) -> f32 {
6637 self.squared_magnitude().sqrt()
6638 }
6639}
6640
6641impl Mul<f32> for PointAndPlane {
6642 type Output = PointAndPlane;
6643
6644 fn mul(self, other: f32) -> PointAndPlane {
6645 self.geometric_product(other)
6646 }
6647}
6648
6649impl MulAssign<f32> for PointAndPlane {
6650 fn mul_assign(&mut self, other: f32) {
6651 *self = (*self).mul(other);
6652 }
6653}
6654
6655impl Signum for PointAndPlane {
6656 type Output = PointAndPlane;
6657
6658 fn signum(self) -> PointAndPlane {
6659 self.geometric_product(1.0 / self.magnitude())
6660 }
6661}
6662
6663impl Inverse for PointAndPlane {
6664 type Output = PointAndPlane;
6665
6666 fn inverse(self) -> PointAndPlane {
6667 self.reversal().geometric_product(1.0 / self.squared_magnitude())
6668 }
6669}
6670
6671impl GeometricQuotient<IdealPoint> for IdealPoint {
6672 type Output = Rotor;
6673
6674 fn geometric_quotient(self, other: IdealPoint) -> Rotor {
6675 self.geometric_product(other.inverse())
6676 }
6677}
6678
6679impl GeometricQuotient<Line> for IdealPoint {
6680 type Output = Motor;
6681
6682 fn geometric_quotient(self, other: Line) -> Motor {
6683 self.geometric_product(other.inverse())
6684 }
6685}
6686
6687impl Transformation<Line> for IdealPoint {
6688 type Output = Line;
6689
6690 fn transformation(self, other: Line) -> Line {
6691 self.geometric_product(other).geometric_product(self.reversal()).into()
6692 }
6693}
6694
6695impl GeometricQuotient<Motor> for IdealPoint {
6696 type Output = Motor;
6697
6698 fn geometric_quotient(self, other: Motor) -> Motor {
6699 self.geometric_product(other.inverse())
6700 }
6701}
6702
6703impl Transformation<Motor> for IdealPoint {
6704 type Output = Motor;
6705
6706 fn transformation(self, other: Motor) -> Motor {
6707 self.geometric_product(other).geometric_product(self.reversal())
6708 }
6709}
6710
6711impl GeometricQuotient<MultiVector> for IdealPoint {
6712 type Output = MultiVector;
6713
6714 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6715 self.geometric_product(other.inverse())
6716 }
6717}
6718
6719impl Transformation<MultiVector> for IdealPoint {
6720 type Output = MultiVector;
6721
6722 fn transformation(self, other: MultiVector) -> MultiVector {
6723 self.geometric_product(other).geometric_product(self.reversal())
6724 }
6725}
6726
6727impl GeometricQuotient<PointAndPlane> for IdealPoint {
6728 type Output = PointAndPlane;
6729
6730 fn geometric_quotient(self, other: PointAndPlane) -> PointAndPlane {
6731 self.geometric_product(other.inverse())
6732 }
6733}
6734
6735impl Transformation<PointAndPlane> for IdealPoint {
6736 type Output = PointAndPlane;
6737
6738 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
6739 self.geometric_product(other).geometric_product(self.reversal())
6740 }
6741}
6742
6743impl GeometricQuotient<f32> for IdealPoint {
6744 type Output = IdealPoint;
6745
6746 fn geometric_quotient(self, other: f32) -> IdealPoint {
6747 self.geometric_product(other.inverse())
6748 }
6749}
6750
6751impl Transformation<f32> for IdealPoint {
6752 type Output = f32;
6753
6754 fn transformation(self, other: f32) -> f32 {
6755 self.geometric_product(other).geometric_product(self.reversal()).into()
6756 }
6757}
6758
6759impl GeometricQuotient<IdealPoint> for Line {
6760 type Output = Motor;
6761
6762 fn geometric_quotient(self, other: IdealPoint) -> Motor {
6763 self.geometric_product(other.inverse())
6764 }
6765}
6766
6767impl Transformation<IdealPoint> for Line {
6768 type Output = IdealPoint;
6769
6770 fn transformation(self, other: IdealPoint) -> IdealPoint {
6771 self.geometric_product(other).geometric_product(self.reversal()).into()
6772 }
6773}
6774
6775impl GeometricQuotient<Line> for Line {
6776 type Output = Motor;
6777
6778 fn geometric_quotient(self, other: Line) -> Motor {
6779 self.geometric_product(other.inverse())
6780 }
6781}
6782
6783impl Transformation<Line> for Line {
6784 type Output = Line;
6785
6786 fn transformation(self, other: Line) -> Line {
6787 self.geometric_product(other).geometric_product(self.reversal()).into()
6788 }
6789}
6790
6791impl GeometricQuotient<Motor> for Line {
6792 type Output = Motor;
6793
6794 fn geometric_quotient(self, other: Motor) -> Motor {
6795 self.geometric_product(other.inverse())
6796 }
6797}
6798
6799impl Transformation<Motor> for Line {
6800 type Output = Motor;
6801
6802 fn transformation(self, other: Motor) -> Motor {
6803 self.geometric_product(other).geometric_product(self.reversal())
6804 }
6805}
6806
6807impl GeometricQuotient<MultiVector> for Line {
6808 type Output = MultiVector;
6809
6810 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6811 self.geometric_product(other.inverse())
6812 }
6813}
6814
6815impl Transformation<MultiVector> for Line {
6816 type Output = MultiVector;
6817
6818 fn transformation(self, other: MultiVector) -> MultiVector {
6819 self.geometric_product(other).geometric_product(self.reversal())
6820 }
6821}
6822
6823impl GeometricQuotient<Plane> for Line {
6824 type Output = PointAndPlane;
6825
6826 fn geometric_quotient(self, other: Plane) -> PointAndPlane {
6827 self.geometric_product(other.inverse())
6828 }
6829}
6830
6831impl Transformation<Plane> for Line {
6832 type Output = Plane;
6833
6834 fn transformation(self, other: Plane) -> Plane {
6835 self.geometric_product(other).geometric_product(self.reversal()).into()
6836 }
6837}
6838
6839impl GeometricQuotient<Point> for Line {
6840 type Output = PointAndPlane;
6841
6842 fn geometric_quotient(self, other: Point) -> PointAndPlane {
6843 self.geometric_product(other.inverse())
6844 }
6845}
6846
6847impl Transformation<Point> for Line {
6848 type Output = Point;
6849
6850 fn transformation(self, other: Point) -> Point {
6851 self.geometric_product(other).geometric_product(self.reversal()).into()
6852 }
6853}
6854
6855impl GeometricQuotient<PointAndPlane> for Line {
6856 type Output = PointAndPlane;
6857
6858 fn geometric_quotient(self, other: PointAndPlane) -> PointAndPlane {
6859 self.geometric_product(other.inverse())
6860 }
6861}
6862
6863impl Transformation<PointAndPlane> for Line {
6864 type Output = PointAndPlane;
6865
6866 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
6867 self.geometric_product(other).geometric_product(self.reversal())
6868 }
6869}
6870
6871impl GeometricQuotient<Rotor> for Line {
6872 type Output = Motor;
6873
6874 fn geometric_quotient(self, other: Rotor) -> Motor {
6875 self.geometric_product(other.inverse())
6876 }
6877}
6878
6879impl Transformation<Rotor> for Line {
6880 type Output = Rotor;
6881
6882 fn transformation(self, other: Rotor) -> Rotor {
6883 self.geometric_product(other).geometric_product(self.reversal()).into()
6884 }
6885}
6886
6887impl GeometricQuotient<f32> for Line {
6888 type Output = Line;
6889
6890 fn geometric_quotient(self, other: f32) -> Line {
6891 self.geometric_product(other.inverse())
6892 }
6893}
6894
6895impl Transformation<f32> for Line {
6896 type Output = f32;
6897
6898 fn transformation(self, other: f32) -> f32 {
6899 self.geometric_product(other).geometric_product(self.reversal()).into()
6900 }
6901}
6902
6903impl GeometricQuotient<Translator> for Line {
6904 type Output = Motor;
6905
6906 fn geometric_quotient(self, other: Translator) -> Motor {
6907 self.geometric_product(other.inverse())
6908 }
6909}
6910
6911impl Transformation<Translator> for Line {
6912 type Output = Translator;
6913
6914 fn transformation(self, other: Translator) -> Translator {
6915 self.geometric_product(other).geometric_product(self.reversal()).into()
6916 }
6917}
6918
6919impl GeometricQuotient<IdealPoint> for Motor {
6920 type Output = Motor;
6921
6922 fn geometric_quotient(self, other: IdealPoint) -> Motor {
6923 self.geometric_product(other.inverse())
6924 }
6925}
6926
6927impl Transformation<IdealPoint> for Motor {
6928 type Output = IdealPoint;
6929
6930 fn transformation(self, other: IdealPoint) -> IdealPoint {
6931 self.geometric_product(other).geometric_product(self.reversal()).into()
6932 }
6933}
6934
6935impl GeometricQuotient<Line> for Motor {
6936 type Output = Motor;
6937
6938 fn geometric_quotient(self, other: Line) -> Motor {
6939 self.geometric_product(other.inverse())
6940 }
6941}
6942
6943impl Transformation<Line> for Motor {
6944 type Output = Line;
6945
6946 fn transformation(self, other: Line) -> Line {
6947 self.geometric_product(other).geometric_product(self.reversal()).into()
6948 }
6949}
6950
6951impl Powi for Motor {
6952 type Output = Motor;
6953
6954 fn powi(self, exponent: isize) -> Motor {
6955 if exponent == 0 {
6956 return Motor::one();
6957 }
6958 let mut x: Motor = if exponent < 0 { self.inverse() } else { self };
6959 let mut y: Motor = Motor::one();
6960 let mut n: isize = exponent.abs();
6961 while 1 < n {
6962 if n & 1 == 1 {
6963 y = x.geometric_product(y);
6964 }
6965 x = x.geometric_product(x);
6966 n = n >> 1;
6967 }
6968 x.geometric_product(y)
6969 }
6970}
6971
6972impl GeometricQuotient<Motor> for Motor {
6973 type Output = Motor;
6974
6975 fn geometric_quotient(self, other: Motor) -> Motor {
6976 self.geometric_product(other.inverse())
6977 }
6978}
6979
6980impl Transformation<Motor> for Motor {
6981 type Output = Motor;
6982
6983 fn transformation(self, other: Motor) -> Motor {
6984 self.geometric_product(other).geometric_product(self.reversal())
6985 }
6986}
6987
6988impl GeometricQuotient<MultiVector> for Motor {
6989 type Output = MultiVector;
6990
6991 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
6992 self.geometric_product(other.inverse())
6993 }
6994}
6995
6996impl Transformation<MultiVector> for Motor {
6997 type Output = MultiVector;
6998
6999 fn transformation(self, other: MultiVector) -> MultiVector {
7000 self.geometric_product(other).geometric_product(self.reversal())
7001 }
7002}
7003
7004impl GeometricQuotient<Plane> for Motor {
7005 type Output = PointAndPlane;
7006
7007 fn geometric_quotient(self, other: Plane) -> PointAndPlane {
7008 self.geometric_product(other.inverse())
7009 }
7010}
7011
7012impl Transformation<Plane> for Motor {
7013 type Output = Plane;
7014
7015 fn transformation(self, other: Plane) -> Plane {
7016 self.geometric_product(other).geometric_product(self.reversal()).into()
7017 }
7018}
7019
7020impl GeometricQuotient<Point> for Motor {
7021 type Output = PointAndPlane;
7022
7023 fn geometric_quotient(self, other: Point) -> PointAndPlane {
7024 self.geometric_product(other.inverse())
7025 }
7026}
7027
7028impl Transformation<Point> for Motor {
7029 type Output = Point;
7030
7031 fn transformation(self, other: Point) -> Point {
7032 self.geometric_product(other).geometric_product(self.reversal()).into()
7033 }
7034}
7035
7036impl GeometricQuotient<PointAndPlane> for Motor {
7037 type Output = PointAndPlane;
7038
7039 fn geometric_quotient(self, other: PointAndPlane) -> PointAndPlane {
7040 self.geometric_product(other.inverse())
7041 }
7042}
7043
7044impl Transformation<PointAndPlane> for Motor {
7045 type Output = PointAndPlane;
7046
7047 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7048 self.geometric_product(other).geometric_product(self.reversal())
7049 }
7050}
7051
7052impl GeometricQuotient<Rotor> for Motor {
7053 type Output = Motor;
7054
7055 fn geometric_quotient(self, other: Rotor) -> Motor {
7056 self.geometric_product(other.inverse())
7057 }
7058}
7059
7060impl Transformation<Rotor> for Motor {
7061 type Output = Rotor;
7062
7063 fn transformation(self, other: Rotor) -> Rotor {
7064 self.geometric_product(other).geometric_product(self.reversal()).into()
7065 }
7066}
7067
7068impl GeometricQuotient<f32> for Motor {
7069 type Output = Motor;
7070
7071 fn geometric_quotient(self, other: f32) -> Motor {
7072 self.geometric_product(other.inverse())
7073 }
7074}
7075
7076impl Transformation<f32> for Motor {
7077 type Output = f32;
7078
7079 fn transformation(self, other: f32) -> f32 {
7080 self.geometric_product(other).geometric_product(self.reversal()).into()
7081 }
7082}
7083
7084impl GeometricQuotient<Translator> for Motor {
7085 type Output = Motor;
7086
7087 fn geometric_quotient(self, other: Translator) -> Motor {
7088 self.geometric_product(other.inverse())
7089 }
7090}
7091
7092impl Transformation<Translator> for Motor {
7093 type Output = Translator;
7094
7095 fn transformation(self, other: Translator) -> Translator {
7096 self.geometric_product(other).geometric_product(self.reversal()).into()
7097 }
7098}
7099
7100impl GeometricQuotient<IdealPoint> for MultiVector {
7101 type Output = MultiVector;
7102
7103 fn geometric_quotient(self, other: IdealPoint) -> MultiVector {
7104 self.geometric_product(other.inverse())
7105 }
7106}
7107
7108impl Transformation<IdealPoint> for MultiVector {
7109 type Output = IdealPoint;
7110
7111 fn transformation(self, other: IdealPoint) -> IdealPoint {
7112 self.geometric_product(other).geometric_product(self.reversal()).into()
7113 }
7114}
7115
7116impl GeometricQuotient<Line> for MultiVector {
7117 type Output = MultiVector;
7118
7119 fn geometric_quotient(self, other: Line) -> MultiVector {
7120 self.geometric_product(other.inverse())
7121 }
7122}
7123
7124impl Transformation<Line> for MultiVector {
7125 type Output = Line;
7126
7127 fn transformation(self, other: Line) -> Line {
7128 self.geometric_product(other).geometric_product(self.reversal()).into()
7129 }
7130}
7131
7132impl GeometricQuotient<Motor> for MultiVector {
7133 type Output = MultiVector;
7134
7135 fn geometric_quotient(self, other: Motor) -> MultiVector {
7136 self.geometric_product(other.inverse())
7137 }
7138}
7139
7140impl Transformation<Motor> for MultiVector {
7141 type Output = Motor;
7142
7143 fn transformation(self, other: Motor) -> Motor {
7144 self.geometric_product(other).geometric_product(self.reversal()).into()
7145 }
7146}
7147
7148impl Powi for MultiVector {
7149 type Output = MultiVector;
7150
7151 fn powi(self, exponent: isize) -> MultiVector {
7152 if exponent == 0 {
7153 return MultiVector::one();
7154 }
7155 let mut x: MultiVector = if exponent < 0 { self.inverse() } else { self };
7156 let mut y: MultiVector = MultiVector::one();
7157 let mut n: isize = exponent.abs();
7158 while 1 < n {
7159 if n & 1 == 1 {
7160 y = x.geometric_product(y);
7161 }
7162 x = x.geometric_product(x);
7163 n = n >> 1;
7164 }
7165 x.geometric_product(y)
7166 }
7167}
7168
7169impl GeometricQuotient<MultiVector> for MultiVector {
7170 type Output = MultiVector;
7171
7172 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7173 self.geometric_product(other.inverse())
7174 }
7175}
7176
7177impl Transformation<MultiVector> for MultiVector {
7178 type Output = MultiVector;
7179
7180 fn transformation(self, other: MultiVector) -> MultiVector {
7181 self.geometric_product(other).geometric_product(self.reversal())
7182 }
7183}
7184
7185impl GeometricQuotient<Plane> for MultiVector {
7186 type Output = MultiVector;
7187
7188 fn geometric_quotient(self, other: Plane) -> MultiVector {
7189 self.geometric_product(other.inverse())
7190 }
7191}
7192
7193impl Transformation<Plane> for MultiVector {
7194 type Output = Plane;
7195
7196 fn transformation(self, other: Plane) -> Plane {
7197 self.geometric_product(other).geometric_product(self.reversal()).into()
7198 }
7199}
7200
7201impl GeometricQuotient<Point> for MultiVector {
7202 type Output = MultiVector;
7203
7204 fn geometric_quotient(self, other: Point) -> MultiVector {
7205 self.geometric_product(other.inverse())
7206 }
7207}
7208
7209impl Transformation<Point> for MultiVector {
7210 type Output = Point;
7211
7212 fn transformation(self, other: Point) -> Point {
7213 self.geometric_product(other).geometric_product(self.reversal()).into()
7214 }
7215}
7216
7217impl GeometricQuotient<PointAndPlane> for MultiVector {
7218 type Output = MultiVector;
7219
7220 fn geometric_quotient(self, other: PointAndPlane) -> MultiVector {
7221 self.geometric_product(other.inverse())
7222 }
7223}
7224
7225impl Transformation<PointAndPlane> for MultiVector {
7226 type Output = PointAndPlane;
7227
7228 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7229 self.geometric_product(other).geometric_product(self.reversal()).into()
7230 }
7231}
7232
7233impl GeometricQuotient<Rotor> for MultiVector {
7234 type Output = MultiVector;
7235
7236 fn geometric_quotient(self, other: Rotor) -> MultiVector {
7237 self.geometric_product(other.inverse())
7238 }
7239}
7240
7241impl Transformation<Rotor> for MultiVector {
7242 type Output = Rotor;
7243
7244 fn transformation(self, other: Rotor) -> Rotor {
7245 self.geometric_product(other).geometric_product(self.reversal()).into()
7246 }
7247}
7248
7249impl GeometricQuotient<f32> for MultiVector {
7250 type Output = MultiVector;
7251
7252 fn geometric_quotient(self, other: f32) -> MultiVector {
7253 self.geometric_product(other.inverse())
7254 }
7255}
7256
7257impl Transformation<f32> for MultiVector {
7258 type Output = f32;
7259
7260 fn transformation(self, other: f32) -> f32 {
7261 self.geometric_product(other).geometric_product(self.reversal()).into()
7262 }
7263}
7264
7265impl GeometricQuotient<Translator> for MultiVector {
7266 type Output = MultiVector;
7267
7268 fn geometric_quotient(self, other: Translator) -> MultiVector {
7269 self.geometric_product(other.inverse())
7270 }
7271}
7272
7273impl Transformation<Translator> for MultiVector {
7274 type Output = Translator;
7275
7276 fn transformation(self, other: Translator) -> Translator {
7277 self.geometric_product(other).geometric_product(self.reversal()).into()
7278 }
7279}
7280
7281impl GeometricQuotient<Line> for Plane {
7282 type Output = PointAndPlane;
7283
7284 fn geometric_quotient(self, other: Line) -> PointAndPlane {
7285 self.geometric_product(other.inverse())
7286 }
7287}
7288
7289impl Transformation<Line> for Plane {
7290 type Output = Line;
7291
7292 fn transformation(self, other: Line) -> Line {
7293 self.geometric_product(other).geometric_product(self.reversal()).into()
7294 }
7295}
7296
7297impl GeometricQuotient<Motor> for Plane {
7298 type Output = PointAndPlane;
7299
7300 fn geometric_quotient(self, other: Motor) -> PointAndPlane {
7301 self.geometric_product(other.inverse())
7302 }
7303}
7304
7305impl Transformation<Motor> for Plane {
7306 type Output = Motor;
7307
7308 fn transformation(self, other: Motor) -> Motor {
7309 self.geometric_product(other).geometric_product(self.reversal())
7310 }
7311}
7312
7313impl GeometricQuotient<MultiVector> for Plane {
7314 type Output = MultiVector;
7315
7316 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7317 self.geometric_product(other.inverse())
7318 }
7319}
7320
7321impl Transformation<MultiVector> for Plane {
7322 type Output = MultiVector;
7323
7324 fn transformation(self, other: MultiVector) -> MultiVector {
7325 self.geometric_product(other).geometric_product(self.reversal())
7326 }
7327}
7328
7329impl GeometricQuotient<PointAndPlane> for Plane {
7330 type Output = Motor;
7331
7332 fn geometric_quotient(self, other: PointAndPlane) -> Motor {
7333 self.geometric_product(other.inverse())
7334 }
7335}
7336
7337impl Transformation<PointAndPlane> for Plane {
7338 type Output = PointAndPlane;
7339
7340 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7341 self.geometric_product(other).geometric_product(self.reversal())
7342 }
7343}
7344
7345impl GeometricQuotient<Rotor> for Plane {
7346 type Output = PointAndPlane;
7347
7348 fn geometric_quotient(self, other: Rotor) -> PointAndPlane {
7349 self.geometric_product(other.inverse())
7350 }
7351}
7352
7353impl Transformation<Rotor> for Plane {
7354 type Output = Rotor;
7355
7356 fn transformation(self, other: Rotor) -> Rotor {
7357 self.geometric_product(other).geometric_product(self.reversal()).into()
7358 }
7359}
7360
7361impl GeometricQuotient<f32> for Plane {
7362 type Output = Plane;
7363
7364 fn geometric_quotient(self, other: f32) -> Plane {
7365 self.geometric_product(other.inverse())
7366 }
7367}
7368
7369impl GeometricQuotient<Line> for Point {
7370 type Output = PointAndPlane;
7371
7372 fn geometric_quotient(self, other: Line) -> PointAndPlane {
7373 self.geometric_product(other.inverse())
7374 }
7375}
7376
7377impl Transformation<Line> for Point {
7378 type Output = Line;
7379
7380 fn transformation(self, other: Line) -> Line {
7381 self.geometric_product(other).geometric_product(self.reversal()).into()
7382 }
7383}
7384
7385impl GeometricQuotient<Motor> for Point {
7386 type Output = PointAndPlane;
7387
7388 fn geometric_quotient(self, other: Motor) -> PointAndPlane {
7389 self.geometric_product(other.inverse())
7390 }
7391}
7392
7393impl Transformation<Motor> for Point {
7394 type Output = Motor;
7395
7396 fn transformation(self, other: Motor) -> Motor {
7397 self.geometric_product(other).geometric_product(self.reversal())
7398 }
7399}
7400
7401impl GeometricQuotient<MultiVector> for Point {
7402 type Output = MultiVector;
7403
7404 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7405 self.geometric_product(other.inverse())
7406 }
7407}
7408
7409impl Transformation<MultiVector> for Point {
7410 type Output = MultiVector;
7411
7412 fn transformation(self, other: MultiVector) -> MultiVector {
7413 self.geometric_product(other).geometric_product(self.reversal())
7414 }
7415}
7416
7417impl GeometricQuotient<PointAndPlane> for Point {
7418 type Output = Motor;
7419
7420 fn geometric_quotient(self, other: PointAndPlane) -> Motor {
7421 self.geometric_product(other.inverse())
7422 }
7423}
7424
7425impl Transformation<PointAndPlane> for Point {
7426 type Output = PointAndPlane;
7427
7428 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7429 self.geometric_product(other).geometric_product(self.reversal())
7430 }
7431}
7432
7433impl GeometricQuotient<Rotor> for Point {
7434 type Output = PointAndPlane;
7435
7436 fn geometric_quotient(self, other: Rotor) -> PointAndPlane {
7437 self.geometric_product(other.inverse())
7438 }
7439}
7440
7441impl Transformation<Rotor> for Point {
7442 type Output = Rotor;
7443
7444 fn transformation(self, other: Rotor) -> Rotor {
7445 self.geometric_product(other).geometric_product(self.reversal()).into()
7446 }
7447}
7448
7449impl GeometricQuotient<f32> for Point {
7450 type Output = Point;
7451
7452 fn geometric_quotient(self, other: f32) -> Point {
7453 self.geometric_product(other.inverse())
7454 }
7455}
7456
7457impl GeometricQuotient<IdealPoint> for PointAndPlane {
7458 type Output = PointAndPlane;
7459
7460 fn geometric_quotient(self, other: IdealPoint) -> PointAndPlane {
7461 self.geometric_product(other.inverse())
7462 }
7463}
7464
7465impl Transformation<IdealPoint> for PointAndPlane {
7466 type Output = IdealPoint;
7467
7468 fn transformation(self, other: IdealPoint) -> IdealPoint {
7469 self.geometric_product(other).geometric_product(self.reversal()).into()
7470 }
7471}
7472
7473impl GeometricQuotient<Line> for PointAndPlane {
7474 type Output = PointAndPlane;
7475
7476 fn geometric_quotient(self, other: Line) -> PointAndPlane {
7477 self.geometric_product(other.inverse())
7478 }
7479}
7480
7481impl Transformation<Line> for PointAndPlane {
7482 type Output = Line;
7483
7484 fn transformation(self, other: Line) -> Line {
7485 self.geometric_product(other).geometric_product(self.reversal()).into()
7486 }
7487}
7488
7489impl GeometricQuotient<Motor> for PointAndPlane {
7490 type Output = PointAndPlane;
7491
7492 fn geometric_quotient(self, other: Motor) -> PointAndPlane {
7493 self.geometric_product(other.inverse())
7494 }
7495}
7496
7497impl Transformation<Motor> for PointAndPlane {
7498 type Output = Motor;
7499
7500 fn transformation(self, other: Motor) -> Motor {
7501 self.geometric_product(other).geometric_product(self.reversal())
7502 }
7503}
7504
7505impl GeometricQuotient<MultiVector> for PointAndPlane {
7506 type Output = MultiVector;
7507
7508 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7509 self.geometric_product(other.inverse())
7510 }
7511}
7512
7513impl Transformation<MultiVector> for PointAndPlane {
7514 type Output = MultiVector;
7515
7516 fn transformation(self, other: MultiVector) -> MultiVector {
7517 self.geometric_product(other).geometric_product(self.reversal())
7518 }
7519}
7520
7521impl GeometricQuotient<Plane> for PointAndPlane {
7522 type Output = Motor;
7523
7524 fn geometric_quotient(self, other: Plane) -> Motor {
7525 self.geometric_product(other.inverse())
7526 }
7527}
7528
7529impl Transformation<Plane> for PointAndPlane {
7530 type Output = Plane;
7531
7532 fn transformation(self, other: Plane) -> Plane {
7533 self.geometric_product(other).geometric_product(self.reversal()).into()
7534 }
7535}
7536
7537impl GeometricQuotient<Point> for PointAndPlane {
7538 type Output = Motor;
7539
7540 fn geometric_quotient(self, other: Point) -> Motor {
7541 self.geometric_product(other.inverse())
7542 }
7543}
7544
7545impl Transformation<Point> for PointAndPlane {
7546 type Output = Point;
7547
7548 fn transformation(self, other: Point) -> Point {
7549 self.geometric_product(other).geometric_product(self.reversal()).into()
7550 }
7551}
7552
7553impl GeometricQuotient<PointAndPlane> for PointAndPlane {
7554 type Output = Motor;
7555
7556 fn geometric_quotient(self, other: PointAndPlane) -> Motor {
7557 self.geometric_product(other.inverse())
7558 }
7559}
7560
7561impl Transformation<PointAndPlane> for PointAndPlane {
7562 type Output = PointAndPlane;
7563
7564 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7565 self.geometric_product(other).geometric_product(self.reversal())
7566 }
7567}
7568
7569impl GeometricQuotient<Rotor> for PointAndPlane {
7570 type Output = PointAndPlane;
7571
7572 fn geometric_quotient(self, other: Rotor) -> PointAndPlane {
7573 self.geometric_product(other.inverse())
7574 }
7575}
7576
7577impl Transformation<Rotor> for PointAndPlane {
7578 type Output = Rotor;
7579
7580 fn transformation(self, other: Rotor) -> Rotor {
7581 self.geometric_product(other).geometric_product(self.reversal()).into()
7582 }
7583}
7584
7585impl GeometricQuotient<f32> for PointAndPlane {
7586 type Output = PointAndPlane;
7587
7588 fn geometric_quotient(self, other: f32) -> PointAndPlane {
7589 self.geometric_product(other.inverse())
7590 }
7591}
7592
7593impl Transformation<f32> for PointAndPlane {
7594 type Output = f32;
7595
7596 fn transformation(self, other: f32) -> f32 {
7597 self.geometric_product(other).geometric_product(self.reversal()).into()
7598 }
7599}
7600
7601impl GeometricQuotient<Translator> for PointAndPlane {
7602 type Output = PointAndPlane;
7603
7604 fn geometric_quotient(self, other: Translator) -> PointAndPlane {
7605 self.geometric_product(other.inverse())
7606 }
7607}
7608
7609impl Transformation<Translator> for PointAndPlane {
7610 type Output = Translator;
7611
7612 fn transformation(self, other: Translator) -> Translator {
7613 self.geometric_product(other).geometric_product(self.reversal()).into()
7614 }
7615}
7616
7617impl GeometricQuotient<Line> for Rotor {
7618 type Output = Motor;
7619
7620 fn geometric_quotient(self, other: Line) -> Motor {
7621 self.geometric_product(other.inverse())
7622 }
7623}
7624
7625impl Transformation<Line> for Rotor {
7626 type Output = Line;
7627
7628 fn transformation(self, other: Line) -> Line {
7629 self.geometric_product(other).geometric_product(self.reversal()).into()
7630 }
7631}
7632
7633impl GeometricQuotient<Motor> for Rotor {
7634 type Output = Motor;
7635
7636 fn geometric_quotient(self, other: Motor) -> Motor {
7637 self.geometric_product(other.inverse())
7638 }
7639}
7640
7641impl Transformation<Motor> for Rotor {
7642 type Output = Motor;
7643
7644 fn transformation(self, other: Motor) -> Motor {
7645 self.geometric_product(other).geometric_product(self.reversal())
7646 }
7647}
7648
7649impl GeometricQuotient<MultiVector> for Rotor {
7650 type Output = MultiVector;
7651
7652 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7653 self.geometric_product(other.inverse())
7654 }
7655}
7656
7657impl Transformation<MultiVector> for Rotor {
7658 type Output = MultiVector;
7659
7660 fn transformation(self, other: MultiVector) -> MultiVector {
7661 self.geometric_product(other).geometric_product(self.reversal())
7662 }
7663}
7664
7665impl GeometricQuotient<Plane> for Rotor {
7666 type Output = PointAndPlane;
7667
7668 fn geometric_quotient(self, other: Plane) -> PointAndPlane {
7669 self.geometric_product(other.inverse())
7670 }
7671}
7672
7673impl Transformation<Plane> for Rotor {
7674 type Output = Plane;
7675
7676 fn transformation(self, other: Plane) -> Plane {
7677 self.geometric_product(other).geometric_product(self.reversal()).into()
7678 }
7679}
7680
7681impl GeometricQuotient<Point> for Rotor {
7682 type Output = PointAndPlane;
7683
7684 fn geometric_quotient(self, other: Point) -> PointAndPlane {
7685 self.geometric_product(other.inverse())
7686 }
7687}
7688
7689impl Transformation<Point> for Rotor {
7690 type Output = Point;
7691
7692 fn transformation(self, other: Point) -> Point {
7693 self.geometric_product(other).geometric_product(self.reversal()).into()
7694 }
7695}
7696
7697impl GeometricQuotient<PointAndPlane> for Rotor {
7698 type Output = PointAndPlane;
7699
7700 fn geometric_quotient(self, other: PointAndPlane) -> PointAndPlane {
7701 self.geometric_product(other.inverse())
7702 }
7703}
7704
7705impl Transformation<PointAndPlane> for Rotor {
7706 type Output = PointAndPlane;
7707
7708 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7709 self.geometric_product(other).geometric_product(self.reversal())
7710 }
7711}
7712
7713impl Powi for Rotor {
7714 type Output = Rotor;
7715
7716 fn powi(self, exponent: isize) -> Rotor {
7717 if exponent == 0 {
7718 return Rotor::one();
7719 }
7720 let mut x: Rotor = if exponent < 0 { self.inverse() } else { self };
7721 let mut y: Rotor = Rotor::one();
7722 let mut n: isize = exponent.abs();
7723 while 1 < n {
7724 if n & 1 == 1 {
7725 y = x.geometric_product(y);
7726 }
7727 x = x.geometric_product(x);
7728 n = n >> 1;
7729 }
7730 x.geometric_product(y)
7731 }
7732}
7733
7734impl GeometricQuotient<Rotor> for Rotor {
7735 type Output = Rotor;
7736
7737 fn geometric_quotient(self, other: Rotor) -> Rotor {
7738 self.geometric_product(other.inverse())
7739 }
7740}
7741
7742impl Transformation<Rotor> for Rotor {
7743 type Output = Rotor;
7744
7745 fn transformation(self, other: Rotor) -> Rotor {
7746 self.geometric_product(other).geometric_product(self.reversal())
7747 }
7748}
7749
7750impl GeometricQuotient<f32> for Rotor {
7751 type Output = Rotor;
7752
7753 fn geometric_quotient(self, other: f32) -> Rotor {
7754 self.geometric_product(other.inverse())
7755 }
7756}
7757
7758impl Transformation<f32> for Rotor {
7759 type Output = f32;
7760
7761 fn transformation(self, other: f32) -> f32 {
7762 self.geometric_product(other).geometric_product(self.reversal()).into()
7763 }
7764}
7765
7766impl GeometricQuotient<Translator> for Rotor {
7767 type Output = Motor;
7768
7769 fn geometric_quotient(self, other: Translator) -> Motor {
7770 self.geometric_product(other.inverse())
7771 }
7772}
7773
7774impl Transformation<Translator> for Rotor {
7775 type Output = Translator;
7776
7777 fn transformation(self, other: Translator) -> Translator {
7778 self.geometric_product(other).geometric_product(self.reversal()).into()
7779 }
7780}
7781
7782impl GeometricQuotient<IdealPoint> for f32 {
7783 type Output = IdealPoint;
7784
7785 fn geometric_quotient(self, other: IdealPoint) -> IdealPoint {
7786 self.geometric_product(other.inverse())
7787 }
7788}
7789
7790impl Transformation<IdealPoint> for f32 {
7791 type Output = IdealPoint;
7792
7793 fn transformation(self, other: IdealPoint) -> IdealPoint {
7794 self.geometric_product(other).geometric_product(self.reversal())
7795 }
7796}
7797
7798impl GeometricQuotient<Line> for f32 {
7799 type Output = Line;
7800
7801 fn geometric_quotient(self, other: Line) -> Line {
7802 self.geometric_product(other.inverse())
7803 }
7804}
7805
7806impl Transformation<Line> for f32 {
7807 type Output = Line;
7808
7809 fn transformation(self, other: Line) -> Line {
7810 self.geometric_product(other).geometric_product(self.reversal())
7811 }
7812}
7813
7814impl GeometricQuotient<Motor> for f32 {
7815 type Output = Motor;
7816
7817 fn geometric_quotient(self, other: Motor) -> Motor {
7818 self.geometric_product(other.inverse())
7819 }
7820}
7821
7822impl Transformation<Motor> for f32 {
7823 type Output = Motor;
7824
7825 fn transformation(self, other: Motor) -> Motor {
7826 self.geometric_product(other).geometric_product(self.reversal())
7827 }
7828}
7829
7830impl GeometricQuotient<MultiVector> for f32 {
7831 type Output = MultiVector;
7832
7833 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7834 self.geometric_product(other.inverse())
7835 }
7836}
7837
7838impl Transformation<MultiVector> for f32 {
7839 type Output = MultiVector;
7840
7841 fn transformation(self, other: MultiVector) -> MultiVector {
7842 self.geometric_product(other).geometric_product(self.reversal())
7843 }
7844}
7845
7846impl GeometricQuotient<Plane> for f32 {
7847 type Output = Plane;
7848
7849 fn geometric_quotient(self, other: Plane) -> Plane {
7850 self.geometric_product(other.inverse())
7851 }
7852}
7853
7854impl Transformation<Plane> for f32 {
7855 type Output = Plane;
7856
7857 fn transformation(self, other: Plane) -> Plane {
7858 self.geometric_product(other).geometric_product(self.reversal())
7859 }
7860}
7861
7862impl GeometricQuotient<Point> for f32 {
7863 type Output = Point;
7864
7865 fn geometric_quotient(self, other: Point) -> Point {
7866 self.geometric_product(other.inverse())
7867 }
7868}
7869
7870impl Transformation<Point> for f32 {
7871 type Output = Point;
7872
7873 fn transformation(self, other: Point) -> Point {
7874 self.geometric_product(other).geometric_product(self.reversal())
7875 }
7876}
7877
7878impl GeometricQuotient<PointAndPlane> for f32 {
7879 type Output = PointAndPlane;
7880
7881 fn geometric_quotient(self, other: PointAndPlane) -> PointAndPlane {
7882 self.geometric_product(other.inverse())
7883 }
7884}
7885
7886impl Transformation<PointAndPlane> for f32 {
7887 type Output = PointAndPlane;
7888
7889 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7890 self.geometric_product(other).geometric_product(self.reversal())
7891 }
7892}
7893
7894impl GeometricQuotient<Rotor> for f32 {
7895 type Output = Rotor;
7896
7897 fn geometric_quotient(self, other: Rotor) -> Rotor {
7898 self.geometric_product(other.inverse())
7899 }
7900}
7901
7902impl Transformation<Rotor> for f32 {
7903 type Output = Rotor;
7904
7905 fn transformation(self, other: Rotor) -> Rotor {
7906 self.geometric_product(other).geometric_product(self.reversal())
7907 }
7908}
7909
7910impl GeometricQuotient<Translator> for f32 {
7911 type Output = Translator;
7912
7913 fn geometric_quotient(self, other: Translator) -> Translator {
7914 self.geometric_product(other.inverse())
7915 }
7916}
7917
7918impl Transformation<Translator> for f32 {
7919 type Output = Translator;
7920
7921 fn transformation(self, other: Translator) -> Translator {
7922 self.geometric_product(other).geometric_product(self.reversal())
7923 }
7924}
7925
7926impl GeometricQuotient<Line> for Translator {
7927 type Output = Motor;
7928
7929 fn geometric_quotient(self, other: Line) -> Motor {
7930 self.geometric_product(other.inverse())
7931 }
7932}
7933
7934impl Transformation<Line> for Translator {
7935 type Output = Line;
7936
7937 fn transformation(self, other: Line) -> Line {
7938 self.geometric_product(other).geometric_product(self.reversal()).into()
7939 }
7940}
7941
7942impl GeometricQuotient<Motor> for Translator {
7943 type Output = Motor;
7944
7945 fn geometric_quotient(self, other: Motor) -> Motor {
7946 self.geometric_product(other.inverse())
7947 }
7948}
7949
7950impl Transformation<Motor> for Translator {
7951 type Output = Motor;
7952
7953 fn transformation(self, other: Motor) -> Motor {
7954 self.geometric_product(other).geometric_product(self.reversal())
7955 }
7956}
7957
7958impl GeometricQuotient<MultiVector> for Translator {
7959 type Output = MultiVector;
7960
7961 fn geometric_quotient(self, other: MultiVector) -> MultiVector {
7962 self.geometric_product(other.inverse())
7963 }
7964}
7965
7966impl Transformation<MultiVector> for Translator {
7967 type Output = MultiVector;
7968
7969 fn transformation(self, other: MultiVector) -> MultiVector {
7970 self.geometric_product(other).geometric_product(self.reversal())
7971 }
7972}
7973
7974impl GeometricQuotient<PointAndPlane> for Translator {
7975 type Output = PointAndPlane;
7976
7977 fn geometric_quotient(self, other: PointAndPlane) -> PointAndPlane {
7978 self.geometric_product(other.inverse())
7979 }
7980}
7981
7982impl Transformation<PointAndPlane> for Translator {
7983 type Output = PointAndPlane;
7984
7985 fn transformation(self, other: PointAndPlane) -> PointAndPlane {
7986 self.geometric_product(other).geometric_product(self.reversal())
7987 }
7988}
7989
7990impl GeometricQuotient<Rotor> for Translator {
7991 type Output = Motor;
7992
7993 fn geometric_quotient(self, other: Rotor) -> Motor {
7994 self.geometric_product(other.inverse())
7995 }
7996}
7997
7998impl Transformation<Rotor> for Translator {
7999 type Output = Rotor;
8000
8001 fn transformation(self, other: Rotor) -> Rotor {
8002 self.geometric_product(other).geometric_product(self.reversal()).into()
8003 }
8004}
8005
8006impl GeometricQuotient<f32> for Translator {
8007 type Output = Translator;
8008
8009 fn geometric_quotient(self, other: f32) -> Translator {
8010 self.geometric_product(other.inverse())
8011 }
8012}
8013