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