libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
transform.hpp
1#pragma once
2
3#ifndef LIBXR_NO_EIGEN
4
5#include <Eigen/Core>
6#include <Eigen/Dense>
7#include <cmath>
8
9namespace LibXR
10{
11
12using DefaultScalar = LIBXR_DEFAULT_SCALAR;
13
14template <typename Scalar = DefaultScalar>
15class Position;
16template <typename Scalar = DefaultScalar>
17class Axis;
18template <typename Scalar = DefaultScalar>
19class RotationMatrix;
20template <typename Scalar = DefaultScalar>
21class EulerAngle;
22template <typename Scalar = DefaultScalar>
23class Quaternion;
24
37template <typename Scalar>
38class Position : public Eigen::Matrix<Scalar, 3, 1>
39{
40 public:
45 Position() : Eigen::Matrix<Scalar, 3, 1>(0, 0, 0) {}
46
54 Position(Scalar x, Scalar y, Scalar z) : Eigen::Matrix<Scalar, 3, 1>(x, y, z) {}
55
60 Position(const Eigen::Matrix<Scalar, 3, 1>& p) : Eigen::Matrix<Scalar, 3, 1>(p) {}
61
66 Position(const Position& p) : Eigen::Matrix<Scalar, 3, 1>(p) {}
67
74 template <typename T, std::enable_if_t<std::is_same<T, Scalar>::value ||
75 std::is_same<T, float>::value ||
76 std::is_same<T, double>::value,
77 int> = 0>
78 Position(const T (&data)[3]) : Eigen::Matrix<Scalar, 3, 1>(data)
79 {
80 }
81
88 Position& operator=(const Eigen::Matrix<Scalar, 3, 1>& p)
89 {
90 this->data()[0] = p[0];
91 this->data()[1] = p[1];
92 this->data()[2] = p[2];
93 return *this;
94 }
95
102 {
103 if (this != &p)
104 {
105 this->data()[0] = p[0];
106 this->data()[1] = p[1];
107 this->data()[2] = p[2];
108 }
109
110 return *this;
111 }
112
122 template <
123 typename Rotation,
124 std::enable_if_t<std::is_same<Rotation, RotationMatrix<Scalar>>::value ||
125 std::is_same<Rotation, Eigen::Matrix<Scalar, 3, 3>>::value ||
126 std::is_same<Rotation, Quaternion<Scalar>>::value ||
127 std::is_same<Rotation, Eigen::Quaternion<Scalar>>::value,
128 int> = 0>
129 Eigen::Matrix<Scalar, 3, 1> operator*(const Rotation& R) const
130 {
131 return R * (*this);
132 }
133
141 template <
142 typename Rotation,
143 std::enable_if_t<std::is_same<Rotation, RotationMatrix<Scalar>>::value ||
144 std::is_same<Rotation, Eigen::Matrix<Scalar, 3, 3>>::value ||
145 std::is_same<Rotation, Quaternion<Scalar>>::value ||
146 std::is_same<Rotation, Eigen::Quaternion<Scalar>>::value,
147 int> = 0>
148 const Position& operator*=(const Rotation& R)
149 {
150 *this = R * (*this);
151 return *this;
152 }
153
159 Eigen::Matrix<Scalar, 3, 1> operator/(const RotationMatrix<Scalar>& R) const
160 {
161 return (-R) * (*this);
162 }
163
171 {
172 *this = (-q) * (*this);
173 return *this;
174 }
175
182 const Position& operator/=(const Eigen::Matrix<Scalar, 3, 3>& R)
183 {
184 *this = R.transpose() * Eigen::Map<const Eigen::Matrix<Scalar, 3, 1>>(this->data());
185 return *this;
186 }
187
194 const Position& operator/=(const Eigen::Quaternion<Scalar>& q)
195 {
196 *this = q.conjugate() * Eigen::Map<const Eigen::Matrix<Scalar, 3, 1>>(this->data());
197 return *this;
198 }
199
205 const Position& operator*=(Scalar s)
206 {
207 *this = s * (*this);
208 return *this;
209 }
210
216 const Position& operator/=(Scalar s)
217 {
218 (*this)[0] /= s;
219 (*this)[1] /= s;
220 (*this)[2] /= s;
221 return *this;
222 }
223
230 Eigen::Quaternion<Scalar> operator/(const Position<>& p)
231 {
232 return Eigen::Quaternion<Scalar>::FromTwoVectors(p, *this);
233 }
234};
235
248template <typename Scalar>
249class Axis : public Eigen::Matrix<Scalar, 3, 1>
250{
251 public:
256 Axis() : Eigen::Matrix<Scalar, 3, 1>(0, 0, 0) {}
257
266 Axis(Scalar x, Scalar y, Scalar z) : Eigen::Matrix<Scalar, 3, 1>(x, y, z) {}
267
274 Axis(const Axis& p) : Eigen::Matrix<Scalar, 3, 1>(p) {}
275
282 static Axis X() { return Axis(1., 0., 0.); }
283
290 static Axis Y() { return Axis(0., 1., 0.); }
291
298 static Axis Z() { return Axis(0., 0., 1.); }
299
314 Axis<Scalar>& operator=(const Eigen::Matrix<Scalar, 3, 1>& p)
315 {
316 this->data()[0] = p[0];
317 this->data()[1] = p[1];
318 this->data()[2] = p[2];
319 return *this;
320 }
321
334 {
335 if (this != &p)
336 {
337 this->data()[0] = p[0];
338 this->data()[1] = p[1];
339 this->data()[2] = p[2];
340 }
341 return *this;
342 }
343};
344
370template <typename Scalar>
372{
373 public:
374 Scalar data_[3];
375
378 EulerAngle() : data_{0, 0, 0} {}
379
387 EulerAngle(Scalar roll, Scalar pitch, Scalar yaw) : data_{roll, pitch, yaw} {}
388
394 EulerAngle(const Eigen::Matrix<Scalar, 3, 1>& p) : data_{p.x(), p.y(), p.z()} {}
395
400 EulerAngle(const EulerAngle& p) : data_{p.data_[0], p.data_[1], p.data_[2]} {}
401
402 Scalar& Roll() noexcept { return data_[0]; }
403 const Scalar& Roll() const noexcept { return data_[0]; }
404 Scalar& Pitch() noexcept { return data_[1]; }
405 const Scalar& Pitch() const noexcept { return data_[1]; }
406 Scalar& Yaw() noexcept { return data_[2]; }
407 const Scalar& Yaw() const noexcept { return data_[2]; }
408
416 template <typename T, std::enable_if_t<std::is_same<T, Scalar>::value ||
417 std::is_same<T, float>::value ||
418 std::is_same<T, double>::value,
419 int> = 0>
420 EulerAngle(const T (&data)[3]) : data_{data[0], data[1], data[2]}
421 {
422 }
423
425 operator Eigen::Matrix<Scalar, 3, 1>() const
426 {
427 return Eigen::Map<const Eigen::Matrix<Scalar, 3, 1>>(data_);
428 }
429
431 Scalar operator()(int i) const { return data_[i]; }
432
435 EulerAngle& operator=(const Eigen::Matrix<Scalar, 3, 1>& p)
436 {
437 data_[0] = p(0);
438 data_[1] = p(1);
439 data_[2] = p(2);
440 return *this;
441 }
442
446 {
447 if (this != &p)
448 {
449 data_[0] = p.data_[0];
450 data_[1] = p.data_[1];
451 data_[2] = p.data_[2];
452 }
453 return *this;
454 }
455
458 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrix() const { return ToRotationMatrixZYX(); }
459
460 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrixZYX() const
461 {
462 Scalar ca = std::cos(Yaw()), cb = std::cos(Pitch()), cc = std::cos(Roll());
463 Scalar sa = std::sin(Yaw()), sb = std::sin(Pitch()), sc = std::sin(Roll());
464
465 return (Eigen::Matrix<Scalar, 3, 3>() << ca * cb, ca * sb * sc - cc * sa,
466 sa * sc + ca * cc * sb, cb * sa, ca * cc + sa * sb * sc,
467 cc * sa * sb - ca * sc, -sb, cb * sc, cb * cc)
468 .finished();
469 }
470
471 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrixZXY() const
472 {
473 Scalar ca = std::cos(Yaw()), cb = std::cos(Roll()), cc = std::cos(Pitch());
474 Scalar sa = std::sin(Yaw()), sb = std::sin(Roll()), sc = std::sin(Pitch());
475
476 return (Eigen::Matrix<Scalar, 3, 3>() << ca * cc - sa * sb * sc, -cb * sa,
477 ca * sc + cc * sa * sb, cc * sa + ca * sb * sc, ca * cb,
478 sa * sc - ca * cc * sb, -cb * sc, sb, cb * cc)
479 .finished();
480 }
481
482 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrixYXZ() const
483 {
484 Scalar ca = std::cos(Pitch()), cb = std::cos(Roll()), cc = std::cos(Yaw());
485 Scalar sa = std::sin(Pitch()), sb = std::sin(Roll()), sc = std::sin(Yaw());
486
487 return (Eigen::Matrix<Scalar, 3, 3>() << ca * cc + sa * sb * sc,
488 cc * sa * sb - ca * sc, cb * sa, cb * sc, cb * cc, -sb,
489 ca * sb * sc - cc * sa, sa * sc + ca * cc * sb, ca * cb)
490 .finished();
491 }
492
493 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrixYZX() const
494 {
495 Scalar ca = std::cos(Pitch()), cb = std::cos(Yaw()), cc = std::cos(Roll());
496 Scalar sa = std::sin(Pitch()), sb = std::sin(Yaw()), sc = std::sin(Roll());
497
498 return (Eigen::Matrix<Scalar, 3, 3>() << ca * cb, sa * sc - ca * cc * sb,
499 cc * sa + ca * sb * sc, sb, cb * cc, -cb * sc, -cb * sa,
500 ca * sc + cc * sa * sb, ca * cc - sa * sb * sc)
501 .finished();
502 }
503
504 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrixXYZ() const
505 {
506 Scalar ca = std::cos(Roll()), cb = std::cos(Pitch()), cc = std::cos(Yaw());
507 Scalar sa = std::sin(Roll()), sb = std::sin(Pitch()), sc = std::sin(Yaw());
508
509 return (Eigen::Matrix<Scalar, 3, 3>() << cb * cc, -cb * sc, sb,
510 ca * sc + cc * sa * sb, ca * cc - sa * sb * sc, -cb * sa,
511 sa * sc - ca * cc * sb, cc * sa + ca * sb * sc, ca * cb)
512 .finished();
513 }
514
515 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrixXZY() const
516 {
517 Scalar ca = std::cos(Roll()), cb = std::cos(Yaw()), cc = std::cos(Pitch());
518 Scalar sa = std::sin(Roll()), sb = std::sin(Yaw()), sc = std::sin(Pitch());
519
520 return (Eigen::Matrix<Scalar, 3, 3>() << cb * cc, -sb, cb * sc,
521 sa * sc + ca * cc * sb, ca * cb, ca * sb * sc - cc * sa,
522 cc * sa * sb - ca * sc, cb * sa, ca * cc + sa * sb * sc)
523 .finished();
524 }
525
528 Eigen::Quaternion<Scalar> ToQuaternion() const { return ToQuaternionZYX(); }
529
530#if 0
531 Eigen::Quaternion<Scalar> ToQuaternionXYZ() const {
532 Eigen::AngleAxisd rollAngle(Roll(), Eigen::Vector3d::UnitX());
533 Eigen::AngleAxisd pitchAngle(Pitch(), Eigen::Vector3d::UnitY());
534 Eigen::AngleAxisd yawAngle(Yaw(), Eigen::Vector3d::UnitZ());
535 return rollAngle * pitchAngle * yawAngle;
536 }
537
538 Eigen::Quaternion<Scalar> ToQuaternionXZY() const {
539 Eigen::AngleAxisd rollAngle(Roll(), Eigen::Vector3d::UnitX());
540 Eigen::AngleAxisd yawAngle(Yaw(), Eigen::Vector3d::UnitZ());
541 Eigen::AngleAxisd pitchAngle(Pitch(), Eigen::Vector3d::UnitY());
542 return rollAngle * yawAngle * pitchAngle;
543 }
544
545 Eigen::Quaternion<Scalar> ToQuaternionYXZ() const {
546 Eigen::AngleAxisd pitchAngle(Pitch(), Eigen::Vector3d::UnitY());
547 Eigen::AngleAxisd rollAngle(Roll(), Eigen::Vector3d::UnitX());
548 Eigen::AngleAxisd yawAngle(Yaw(), Eigen::Vector3d::UnitZ());
549 return pitchAngle * rollAngle * yawAngle;
550 }
551
552 Eigen::Quaternion<Scalar> ToQuaternionYZX() const {
553 Eigen::AngleAxisd pitchAngle(Pitch(), Eigen::Vector3d::UnitY());
554 Eigen::AngleAxisd yawAngle(Yaw(), Eigen::Vector3d::UnitZ());
555 Eigen::AngleAxisd rollAngle(Roll(), Eigen::Vector3d::UnitX());
556 return pitchAngle * yawAngle * rollAngle;
557 }
558
559 Eigen::Quaternion<Scalar> ToQuaternionZXY() const {
560 Eigen::AngleAxisd yawAngle(Yaw(), Eigen::Vector3d::UnitZ());
561 Eigen::AngleAxisd rollAngle(Roll(), Eigen::Vector3d::UnitX());
562 Eigen::AngleAxisd pitchAngle(Pitch(), Eigen::Vector3d::UnitY());
563 return yawAngle * rollAngle * pitchAngle;
564 }
565
566 Eigen::Quaternion<Scalar> ToQuaternionZYX() const {
567 Eigen::AngleAxisd yawAngle(Yaw(), Eigen::Vector3d::UnitZ());
568 Eigen::AngleAxisd pitchAngle(Pitch(), Eigen::Vector3d::UnitY());
569 Eigen::AngleAxisd rollAngle(Roll(), Eigen::Vector3d::UnitX());
570 return yawAngle * pitchAngle * rollAngle;
571 }
572#endif
573
576 Eigen::Quaternion<Scalar> ToQuaternionXYZ() const
577 {
578 return Eigen::Quaternion<Scalar>(ToRotationMatrixXYZ());
579 }
580
581 Eigen::Quaternion<Scalar> ToQuaternionXZY() const
582 {
583 return Eigen::Quaternion<Scalar>(ToRotationMatrixXZY());
584 }
585
586 Eigen::Quaternion<Scalar> ToQuaternionYXZ() const
587 {
588 return Eigen::Quaternion<Scalar>(ToRotationMatrixYXZ());
589 }
590
591 Eigen::Quaternion<Scalar> ToQuaternionYZX() const
592 {
593 return Eigen::Quaternion<Scalar>(ToRotationMatrixYZX());
594 }
595
596 Eigen::Quaternion<Scalar> ToQuaternionZXY() const
597 {
598 return Eigen::Quaternion<Scalar>(ToRotationMatrixZXY());
599 }
600
601 Eigen::Quaternion<Scalar> ToQuaternionZYX() const
602 {
603 return Eigen::Quaternion<Scalar>(ToRotationMatrixZYX());
604 }
605};
606
621template <typename Scalar>
622class RotationMatrix : public Eigen::Matrix<Scalar, 3, 3>
623{
624 public:
629 RotationMatrix() : Eigen::Matrix<Scalar, 3, 3>()
630 {
631 (*this) << 1, 0, 0, 0, 1, 0, 0, 0, 1;
632 }
633
648 RotationMatrix(Scalar r00, Scalar r01, Scalar r02, Scalar r10, Scalar r11, Scalar r12,
649 Scalar r20, Scalar r21, Scalar r22)
650 : Eigen::Matrix<Scalar, 3, 3>()
651 {
652 (*this) << r00, r01, r02, r10, r11, r12, r20, r21, r22;
653 }
654
661 RotationMatrix(const Eigen::Matrix<Scalar, 3, 3>& R) : Eigen::Matrix<Scalar, 3, 3>{R} {}
662
669 RotationMatrix(const Eigen::Quaternion<Scalar>& q)
670 : Eigen::Matrix<Scalar, 3, 3>{q.toRotationMatrix()}
671 {
672 }
673
681
682 template <typename T, std::enable_if_t<std::is_same<T, Scalar>::value ||
683 std::is_same<T, float>::value ||
684 std::is_same<T, double>::value,
685 int> = 0>
686 RotationMatrix(const T (&data)[9]) : Eigen::Matrix<Scalar, 3, 3>()
687 {
688 (*this) << data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
689 data[8];
690 }
691
692 template <typename T, std::enable_if_t<std::is_same<T, Scalar>::value ||
693 std::is_same<T, float>::value ||
694 std::is_same<T, double>::value,
695 int> = 0>
696 RotationMatrix(const T (&data)[3][3]) : Eigen::Matrix<Scalar, 3, 3>()
697 {
698 (*this) << data[0][0], data[0][1], data[0][2], data[1][0], data[1][1], data[1][2],
699 data[2][0], data[2][1], data[2][2];
700 }
701
708 Eigen::Matrix<Scalar, 3, 3> operator-() const { return this->transpose(); }
709
720 {
721 if (this != &R)
722 {
723 this->data()[0] = R.data()[0];
724 this->data()[1] = R.data()[1];
725 this->data()[2] = R.data()[2];
726 this->data()[3] = R.data()[3];
727 this->data()[4] = R.data()[4];
728 this->data()[5] = R.data()[5];
729 this->data()[6] = R.data()[6];
730 this->data()[7] = R.data()[7];
731 this->data()[8] = R.data()[8];
732 }
733 return *this;
734 }
735
736 RotationMatrix& operator=(const Eigen::Matrix<Scalar, 3, 3>& R)
737 {
738 this->data()[0] = R.data()[0];
739 this->data()[1] = R.data()[1];
740 this->data()[2] = R.data()[2];
741 this->data()[3] = R.data()[3];
742 this->data()[4] = R.data()[4];
743 this->data()[5] = R.data()[5];
744 this->data()[6] = R.data()[6];
745 this->data()[7] = R.data()[7];
746 this->data()[8] = R.data()[8];
747 return *this;
748 }
749
750 RotationMatrix& operator=(const Eigen::Quaternion<Scalar>& q)
751 {
752 *this = q.toRotationMatrix();
753 return *this;
754 }
755
756 RotationMatrix& operator=(const Quaternion<Scalar>& q)
757 {
758 *this = q.ToRotationMatrix();
759 return *this;
760 }
761
762 Position<Scalar> operator*(const Position<Scalar>& p) const
763 {
764 return Position<Scalar>((*this) * Eigen::Matrix<Scalar, 3, 1>(p));
765 }
766
774 Eigen::Matrix<Scalar, 3, 1> operator*(const Eigen::Matrix<Scalar, 3, 1>& p) const
775 {
776 return static_cast<Eigen::Matrix<Scalar, 3, 3>>(*this) * p;
777 }
778
787 {
788 const Eigen::Matrix<Scalar, 3, 3>& a =
789 static_cast<const Eigen::Matrix<Scalar, 3, 3>&>(*this);
790 const Eigen::Matrix<Scalar, 3, 3>& b =
791 static_cast<const Eigen::Matrix<Scalar, 3, 3>&>(rhs);
792 return RotationMatrix(a * b);
793 }
794
805 Eigen::Matrix<Scalar, 3, 1> ToEulerAngle() const { return ToEulerAngleZYX(); }
806
807 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleZYX() const
808 {
809 const Eigen::Matrix<Scalar, 3, 3>& r = (*this);
810
811 Scalar roll = std::atan2(r(2, 1), r(2, 2));
812 Scalar yaw = std::atan2(r(1, 0), r(0, 0));
813 Scalar pitch = std::asin(-r(2, 0));
814
815 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
816 }
817
818 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleXZY() const
819 {
820 const Eigen::Matrix<Scalar, 3, 3>& r = (*this);
821
822 Scalar roll = std::atan2(r(2, 1), r(1, 1));
823 Scalar yaw = std::asin(-r(0, 1));
824 Scalar pitch = std::atan2(r(0, 2), r(0, 0));
825
826 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
827 }
828
829 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleYZX() const
830 {
831 const Eigen::Matrix<Scalar, 3, 3>& r = (*this);
832
833 Scalar pitch = std::atan2(-r(2, 0), r(0, 0));
834 Scalar yaw = std::asin(r(1, 0));
835 Scalar roll = std::atan2(-r(1, 2), r(1, 1));
836
837 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
838 }
839
840 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleYXZ() const
841 {
842 const Eigen::Matrix<Scalar, 3, 3>& r = (*this);
843
844 Scalar pitch = std::atan2(r(0, 2), r(2, 2));
845 Scalar roll = std::asin(-r(1, 2));
846 Scalar yaw = std::atan2(r(1, 0), r(1, 1));
847
848 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
849 }
850
851 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleZXY() const
852 {
853 const Eigen::Matrix<Scalar, 3, 3>& r = (*this);
854
855 Scalar roll = std::asin(r(2, 1));
856 Scalar yaw = std::atan2(-r(0, 1), r(1, 1));
857 Scalar pitch = std::atan2(-r(2, 0), r(2, 2));
858
859 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
860 }
861
862 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleXYZ() const
863 {
864 const Eigen::Matrix<Scalar, 3, 3>& r = (*this);
865
866 Scalar yaw = std::atan2(-r(0, 1), r(0, 0));
867 Scalar pitch = std::asin(r(0, 2));
868 Scalar roll = std::atan2(-r(1, 2), r(2, 2));
869
870 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
871 }
872};
873
887template <typename Scalar>
888class Quaternion : public Eigen::Quaternion<Scalar>
889{
890 public:
895 Quaternion() : Eigen::Quaternion<Scalar>(1, 0, 0, 0) {}
896
904 Quaternion(Scalar w, Scalar x, Scalar y, Scalar z)
905 : Eigen::Quaternion<Scalar>(w, x, y, z)
906 {
907 }
908
913 Quaternion(const Eigen::Quaternion<Scalar>& q) : Eigen::Quaternion<Scalar>(q) {}
914
920 : Eigen::Quaternion<Scalar>(
921 Eigen::Quaternion<Scalar>(static_cast<Eigen::Matrix<Scalar, 3, 3>>(R)))
922 {
923 }
924
930 Quaternion(const Eigen::Matrix<Scalar, 3, 3> R)
931 : Eigen::Quaternion<Scalar>(
932 Eigen::Quaternion<Scalar>(static_cast<Eigen::Matrix<Scalar, 3, 3>>(R)))
933 {
934 }
935
940 template <typename T, std::enable_if_t<std::is_same<T, Scalar>::value ||
941 std::is_same<T, float>::value ||
942 std::is_same<T, double>::value,
943 int> = 0>
944 Quaternion(const T (&data)[4])
945 : Eigen::Quaternion<Scalar>(
946 static_cast<Scalar>(data[0]), static_cast<Scalar>(data[1]),
947 static_cast<Scalar>(data[2]), static_cast<Scalar>(data[3]))
948 {
949 }
950
956 Scalar operator()(int i) const
957 {
958 switch (i)
959 {
960 case 3:
961 return this->w();
962 case 0:
963 return this->x();
964 case 1:
965 return this->y();
966 case 2:
967 return this->z();
968 default:
969 return 0;
970 }
971 }
972
978 Quaternion& operator=(const Eigen::Quaternion<Scalar>& q)
979 {
980 *this = Quaternion(q);
981 return *this;
982 }
983
988 Quaternion operator-() const { return Quaternion((*this).conjugate()); }
989
996 {
997 return Quaternion(this->w() + q.w(), this->x() + q.x(), this->y() + q.y(),
998 this->z() + q.z());
999 }
1000
1001 Quaternion operator+(const Eigen::Quaternion<Scalar>& q) const
1002 {
1003 return Quaternion(this->w() + q.w(), this->x() + q.x(), this->y() + q.y(),
1004 this->z() + q.z());
1005 }
1006
1007 Quaternion operator-(const Quaternion& q) const
1008 {
1009 return Quaternion(this->w() - q.w(), this->x() - q.x(), this->y() - q.y(),
1010 this->z() - q.z());
1011 }
1012
1013 Quaternion operator-(const Eigen::Quaternion<Scalar>& q) const
1014 {
1015 return Quaternion(this->w() - q.w(), this->x() - q.x(), this->y() - q.y(),
1016 this->z() - q.z());
1017 }
1018
1025 {
1026 return Eigen::Quaternion<Scalar>(*this) * Eigen::Quaternion<Scalar>(q);
1027 }
1028
1029 Quaternion operator*(const Eigen::Quaternion<Scalar>& q) const
1030 {
1031 return Eigen::Quaternion<Scalar>(*this) * q;
1032 }
1033
1040 Quaternion operator/(const Quaternion& q) const { return (*this) * (-q); }
1041
1042 Quaternion operator/(const Eigen::Quaternion<Scalar>& q) const
1043 {
1044 return Eigen::Quaternion<Scalar>(*this) * q.conjugate();
1045 }
1046
1047 template <typename Q,
1048 std::enable_if_t<std::is_same<Q, Quaternion>::value ||
1049 std::is_same<Q, Eigen::Quaternion<Scalar>>::value,
1050 int> = 0>
1051 const Quaternion& operator+=(const Q& q)
1052 {
1053 *this = *this + q;
1054 return *this;
1055 }
1056
1057 template <typename Q,
1058 std::enable_if_t<std::is_same<Q, Quaternion>::value ||
1059 std::is_same<Q, Eigen::Quaternion<Scalar>>::value,
1060 int> = 0>
1061 const Quaternion& operator-=(const Q& q)
1062 {
1063 *this = *this - q;
1064 return *this;
1065 }
1066
1073 {
1074 return Eigen::Quaternion<Scalar>(*this) * Eigen::Matrix<Scalar, 3, 1>(p);
1075 }
1076
1089 Eigen::Matrix<Scalar, 3, 1> ToEulerAngle() const { return ToEulerAngleZYX(); }
1090
1091 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleYZX() const
1092 {
1093 Scalar roll = std::atan2(2 * this->w() * this->x() - 2 * this->y() * this->z(),
1094 1 - 2 * (this->x() * this->x() + this->z() * this->z()));
1095 Scalar pitch = std::atan2(2 * this->w() * this->y() - 2 * this->x() * this->z(),
1096 1 - 2 * (this->y() * this->y() + this->z() * this->z()));
1097 Scalar yaw = std::asin(2 * (this->w() * this->z() + this->x() * this->y()));
1098 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
1099 }
1100
1101 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleZYX() const
1102 {
1103 Scalar yaw = std::atan2(2 * (this->w() * this->z() + this->x() * this->y()),
1104 1 - 2 * (this->z() * this->z() + this->y() * this->y()));
1105 Scalar pitch = std::asin(2 * (this->w() * this->y() - this->x() * this->z()));
1106 Scalar roll = std::atan2(2 * (this->w() * this->x() + this->y() * this->z()),
1107 1 - 2 * (this->y() * this->y() + this->x() * this->x()));
1108 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
1109 }
1110
1111 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleYXZ() const
1112 {
1113 Scalar roll = std::asin(2 * (this->w() * this->x() - this->y() * this->z()));
1114 Scalar yaw = std::atan2(2 * (this->w() * this->z() + this->x() * this->y()),
1115 1 - 2 * (this->z() * this->z() + this->x() * this->x()));
1116 Scalar pitch = std::atan2(2 * (this->x() * this->z() + this->w() * this->y()),
1117 1 - 2 * (this->y() * this->y() + this->x() * this->x()));
1118 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
1119 }
1120
1121 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleZXY() const
1122 {
1123 Scalar pitch = std::atan2(-2 * (this->x() * this->z() - this->w() * this->y()),
1124 1 - 2 * (this->y() * this->y() + this->x() * this->x()));
1125 Scalar roll = std::asin(2 * (this->w() * this->x() + this->y() * this->z()));
1126 Scalar yaw = std::atan2(-2 * (this->x() * this->y() - this->w() * this->z()),
1127 1 - 2 * (this->z() * this->z() + this->x() * this->x()));
1128 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
1129 }
1130
1131 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleXZY() const
1132 {
1133 Scalar pitch = std::atan2(2 * (this->w() * this->y() + this->x() * this->z()),
1134 1 - 2 * (this->z() * this->z() + this->y() * this->y()));
1135 Scalar yaw = std::asin(2 * (this->w() * this->z() - this->x() * this->y()));
1136 Scalar roll = std::atan2(2 * (this->w() * this->x() + this->y() * this->z()),
1137 1 - 2 * (this->z() * this->z() + this->x() * this->x()));
1138 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
1139 }
1140
1141 Eigen::Matrix<Scalar, 3, 1> ToEulerAngleXYZ() const
1142 {
1143 Scalar yaw = std::atan2(-2 * (this->x() * this->y() - this->w() * this->z()),
1144 1 - 2 * (this->z() * this->z() + this->y() * this->y()));
1145 Scalar pitch = std::asin(2 * (this->w() * this->y() + this->x() * this->z()));
1146 Scalar roll = std::atan2(-2 * (this->y() * this->z() - this->w() * this->x()),
1147 1 - 2 * (this->y() * this->y() + this->x() * this->x()));
1148 return Eigen::Matrix<Scalar, 3, 1>(roll, pitch, yaw);
1149 }
1150
1161 Eigen::Matrix<Scalar, 3, 3> ToRotationMatrix() const
1162 {
1163 return Eigen::Matrix<Scalar, 3, 3>(*this);
1164 }
1165};
1166
1173template <typename Scalar = DefaultScalar>
1175{
1176 public:
1181
1184 Transform() = default;
1185
1196
1204 {
1205 rotation = q;
1206 return *this;
1207 }
1208
1216 Transform& operator=(const Eigen::AngleAxis<Scalar>& a)
1217 {
1218 rotation = Eigen::Quaternion<Scalar>(a);
1219 return *this;
1220 }
1221
1229 {
1230 translation = p;
1231 return *this;
1232 }
1233
1241 {
1242 return Transform(Eigen::Quaternion<Scalar>(rotation * t.rotation),
1243 Eigen::Matrix<Scalar, 3, 1>(translation + rotation * t.translation));
1244 }
1245
1254 {
1255 return Transform(rotation / t.rotation,
1256 Eigen::Matrix<Scalar, 3, 1>(translation - t.translation));
1257 }
1258};
1259
1260} // namespace LibXR
1261
1262#endif
三维坐标轴类,继承自 Eigen::Matrix<Scalar, 3, 1>。 A 3D axis class, inheriting from Eigen::Matrix<Scalar,...
static Axis X()
返回 X 轴单位向量 (1,0,0)。 Returns the unit vector along the X-axis (1,0,0).
Axis< Scalar > & operator=(const Eigen::Matrix< Scalar, 3, 1 > &p)
赋值运算符重载,将 Eigen::Matrix<Scalar, 3, 1> 赋值给 Axis 对象。 Overloaded assignment operator to assign an Eigen:...
static Axis Z()
返回 Z 轴单位向量 (0,0,1)。 Returns the unit vector along the Z-axis (0,0,1).
Axis()
默认构造函数,将向量初始化为 (0,0,0)。 Default constructor initializing the vector to (0,0,0).
static Axis Y()
返回 Y 轴单位向量 (0,1,0)。 Returns the unit vector along the Y-axis (0,1,0).
Axis(Scalar x, Scalar y, Scalar z)
通过 (x, y, z) 坐标值构造轴向量。 Constructs an axis vector using (x, y, z) coordinates.
Axis< Scalar > & operator=(const Axis &p)
赋值运算符重载,将另一个 Axis 对象赋值给当前对象。 Overloaded assignment operator to assign another Axis object to this obj...
Axis(const Axis &p)
拷贝构造函数,复制另一个 Axis 对象。 Copy constructor to duplicate another Axis object.
表示欧拉角的类,用于描述3D旋转。 Class representing Euler angles for 3D rotation.
Eigen::Matrix< Scalar, 3, 3 > ToRotationMatrix() const
转换为旋转矩阵,默认使用 ZYX 顺序。 Converts to a rotation matrix using the ZYX order by default.
EulerAngle & operator=(const Eigen::Matrix< Scalar, 3, 1 > &p)
赋值运算符,从 Eigen 3D 向量赋值。 Assignment operator from an Eigen 3D vector.
Eigen::Quaternion< Scalar > ToQuaternion() const
转换为四元数,默认使用 ZYX 顺序。 Converts to a quaternion using the ZYX order by default.
Scalar data_[3]
存储欧拉角的数组 / Array storing Euler angles.
EulerAngle(const Eigen::Matrix< Scalar, 3, 1 > &p)
通过 Eigen 3D 向量构造欧拉角对象。 Constructs an Euler angle object using an Eigen 3D vector.
EulerAngle()
默认构造函数,初始化所有角度为零。 Default constructor initializing all angles to zero.
Eigen::Quaternion< Scalar > ToQuaternionXYZ() const
按 XYZ 顺序转换为四元数。 Converts to a quaternion using the XYZ order.
EulerAngle & operator=(const EulerAngle &p)
赋值运算符,从另一个 EulerAngle 赋值。 Assignment operator from another EulerAngle.
EulerAngle(Scalar roll, Scalar pitch, Scalar yaw)
使用指定角度构造欧拉角对象。 Constructs an Euler angle object with given angles.
EulerAngle(const T(&data)[3])
通过 3 元素数组构造欧拉角对象。 Constructs an Euler angle object using a 3-element array.
Scalar operator()(int i) const
获取欧拉角的某个分量 / Retrieves a specific Euler angle component.
EulerAngle(const EulerAngle &p)
拷贝构造函数 / Copy constructor.
三维空间中的位置向量 / 3D position vector
Definition transform.hpp:39
const Position & operator/=(const Eigen::Quaternion< Scalar > &q)
逆四元数变换并更新当前向量 / Apply inverse quaternion transformation and update the current vector
const Position & operator*=(Scalar s)
按标量缩放当前向量 / Scale the current vector by a scalar
Position()
默认构造函数,初始化为 (0,0,0) / Default constructor initializing to (0,0,0)
Definition transform.hpp:45
Position & operator=(const Position &p)
拷贝赋值运算符 / Copy assignment operator
Eigen::Matrix< Scalar, 3, 1 > operator*(const Rotation &R) const
返回旋转作用于当前向量的结果 R * p,不修改当前对象 / Returns the rotated vector R * p without modifying this object
Position(Scalar x, Scalar y, Scalar z)
构造函数,指定 x, y, z 坐标 / Constructor specifying x, y, z coordinates
Definition transform.hpp:54
const Position & operator/=(Scalar s)
按标量除法缩放当前向量 / Scale the current vector by dividing with a scalar
Position(const T(&data)[3])
从 3 元素数组构造 / Constructs from a 3-element array
Definition transform.hpp:78
Eigen::Quaternion< Scalar > operator/(const Position<> &p)
计算从另一个 Position 到当前 Position 的旋转四元数 / Compute the quaternion rotation from another Position to the cu...
const Position & operator/=(const Eigen::Matrix< Scalar, 3, 3 > &R)
逆旋转矩阵变换并更新当前向量 / Apply inverse rotation matrix transformation and update the current vector
Position(const Position &p)
复制构造函数 / Copy constructor
Definition transform.hpp:66
Position(const Eigen::Matrix< Scalar, 3, 1 > &p)
从 Eigen 3x1 向量构造 / Constructs from an Eigen 3x1 vector
Definition transform.hpp:60
const Position & operator/=(const Quaternion< Scalar > &q)
逆四元数旋转并更新当前向量 / Apply inverse quaternion rotation and update the current vector
const Position & operator*=(const Rotation &R)
旋转并更新当前向量 / Rotate and update the current vector
Position & operator=(const Eigen::Matrix< Scalar, 3, 1 > &p)
赋值运算符,将 Eigen 向量赋值给 Position / Assignment operator to assign an Eigen vector to Position
Definition transform.hpp:88
Eigen::Matrix< Scalar, 3, 1 > operator/(const RotationMatrix< Scalar > &R) const
旋转矩阵的逆变换 / Inverse transformation using a rotation matrix
四元数表示与运算,继承自 Eigen::Quaternion / Quaternion representation and operations, inheriting from Eigen::Qua...
Eigen::Matrix< Scalar, 3, 1 > ToEulerAngle() const
获取四元数的欧拉角表示(默认使用 ZYX 旋转顺序) Get the Euler angles representation of the quaternion (default ZYX order)
Quaternion(const Eigen::Quaternion< Scalar > &q)
复制构造函数 / Copy constructor
Quaternion operator-() const
取共轭四元数 / Get the conjugate quaternion
Quaternion operator+(const Quaternion &q) const
四元数加法 / Quaternion addition
Scalar operator()(int i) const
获取四元数的分量 / Retrieve a specific component of the quaternion
Quaternion(const RotationMatrix< Scalar > &R)
通过旋转矩阵构造四元数 / Construct a quaternion from a rotation matrix
Quaternion operator*(const Quaternion &q) const
四元数乘法 / Quaternion multiplication
Quaternion(Scalar w, Scalar x, Scalar y, Scalar z)
通过四个分量初始化四元数 / Construct a quaternion using four components
Quaternion(const Eigen::Matrix< Scalar, 3, 3 > R)
通过 3x3 旋转矩阵构造四元数 / Construct a quaternion from a 3x3 rotation matrix
Quaternion()
默认构造函数,初始化为单位四元数 / Default constructor initializing to an identity quaternion
Quaternion operator/(const Quaternion &q) const
四元数除法(即左乘其共轭) / Quaternion division (multiplication by its conjugate)
Quaternion(const T(&data)[4])
通过四维数组初始化四元数 / Construct a quaternion from a 4-element array
Quaternion & operator=(const Eigen::Quaternion< Scalar > &q)
赋值运算符 / Assignment operator
Position< Scalar > operator*(const Position< Scalar > &p) const
旋转三维向量 / Rotate a 3D vector
Eigen::Matrix< Scalar, 3, 3 > ToRotationMatrix() const
将四元数转换为 3x3 旋转矩阵 / Convert the quaternion to a 3x3 rotation matrix
旋转矩阵类,继承自 Eigen::Matrix<Scalar, 3, 3>。 Rotation matrix class, inheriting from Eigen::Matrix<Scalar,...
RotationMatrix(const Eigen::Quaternion< Scalar > &q)
通过 Eigen 四元数构造旋转矩阵。 Constructs a rotation matrix from an Eigen quaternion.
RotationMatrix(Scalar r00, Scalar r01, Scalar r02, Scalar r10, Scalar r11, Scalar r12, Scalar r20, Scalar r21, Scalar r22)
通过 9 个矩阵元素的值构造旋转矩阵。 Constructs a rotation matrix using 9 matrix elements.
Eigen::Matrix< Scalar, 3, 1 > operator*(const Eigen::Matrix< Scalar, 3, 1 > &p) const
计算旋转矩阵与三维向量的乘积。 Computes the product of the rotation matrix and a 3D vector.
RotationMatrix operator*(const RotationMatrix &rhs) const
计算两个旋转矩阵的乘积。 Computes the product of two rotation matrices.
RotationMatrix & operator=(const RotationMatrix &R)
赋值运算符,将 RotationMatrix 赋值给当前对象。 Overloaded assignment operator to assign a RotationMatrix to the curr...
Eigen::Matrix< Scalar, 3, 1 > ToEulerAngle() const
将旋转矩阵转换为欧拉角(默认使用 ZYX 顺序)。 Converts the rotation matrix to Euler angles (default ZYX order).
RotationMatrix()
默认构造函数,初始化单位旋转矩阵。 Default constructor initializing an identity rotation matrix.
Eigen::Matrix< Scalar, 3, 3 > operator-() const
计算旋转矩阵的转置(逆矩阵)。 Computes the transpose (inverse) of the rotation matrix.
RotationMatrix(const Quaternion< Scalar > &q)
通过 Quaternion 四元数构造旋转矩阵。 Constructs a rotation matrix from a Quaternion object.
RotationMatrix(const Eigen::Matrix< Scalar, 3, 3 > &R)
通过 Eigen 3x3 矩阵构造旋转矩阵。 Constructs a rotation matrix from an Eigen 3x3 matrix.
表示三维空间中的刚体变换,包括旋转和位移。 Represents rigid body transformations in 3D space, including rotation and trans...
Transform operator+(const Transform &t) const
计算当前变换与另一个变换的组合。 Computes the composition of the current transformation with another transformation.
Transform & operator=(const Position< Scalar > &p)
赋值运算符,将平移部分设置为给定的位移。 Assignment operator setting the translation component to the given position.
Transform & operator=(const Eigen::AngleAxis< Scalar > &a)
赋值运算符,将旋转部分设置为给定的旋转轴-角度表示。 Assignment operator setting the rotation component using an axis-angle rep...
Transform()=default
默认构造函数,创建单位变换。 Default constructor creating an identity transformation.
Quaternion< Scalar > rotation
Transform operator-(const Transform &t) const
计算当前变换与另一个变换的相对变换。 Computes the relative transformation between the current transformation and anothe...
Position< Scalar > translation
Transform & operator=(const Quaternion< Scalar > &q)
赋值运算符,将旋转部分设置为给定的四元数。 Assignment operator setting the rotation component to the given quaternion.
Transform(const Quaternion< Scalar > &rotation, const Position< Scalar > &translation)
使用给定的旋转和位移构造变换。 Constructs a transformation with the given rotation and translation.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14