Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
DualQuaternion.hpp
1 #pragma once
2 
3 #include <Core/Math/LinearAlgebra.hpp> // Quaternion operators
4 #include <Core/RaCore.hpp>
5 #include <Core/Types.hpp>
6 
7 namespace Ra {
8 namespace Core {
14 
17 
19 {
20 
21  public:
22  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
23 
25  inline DualQuaternion() {}
26 
28  inline DualQuaternion( const Quaternion& q0, const Quaternion& qe ) : m_q0( q0 ), m_qe( qe ) {}
29 
32  explicit inline DualQuaternion( const Core::Transform& tr );
33 
35  DualQuaternion( const DualQuaternion& other ) = default;
36  DualQuaternion& operator=( const DualQuaternion& ) = default;
37 
39 
40  inline const Quaternion& getQ0() const;
41  inline void setQ0( const Quaternion& q0 );
42  inline const Quaternion& getQe() const;
43  inline void setQe( const Quaternion& qe );
44 
46 
47  inline DualQuaternion operator+( const DualQuaternion& other ) const;
48  inline DualQuaternion operator*( Scalar scalar ) const;
49 
50  inline DualQuaternion& operator+=( const DualQuaternion& other );
51  inline DualQuaternion& operator*=( Scalar scalar );
52 
54 
57  inline void setFromTransform( const Transform& t );
58 
60  inline Transform getTransform() const;
61 
64  inline void normalize();
65 
68  inline Vector3 transform( const Vector3& p ) const;
69 
71  inline Vector3 rotate( const Vector3& p ) const;
72 
74  inline Vector3 translate( const Vector3& p ) const;
75 
76  private:
78  Quaternion m_q0;
80  Quaternion m_qe;
81 };
82 
84 inline DualQuaternion operator*( Scalar scalar, const DualQuaternion& dq );
85 
86 inline const Quaternion& DualQuaternion::getQ0() const {
87  return m_q0;
88 }
89 
90 inline void DualQuaternion::setQ0( const Quaternion& q0 ) {
91  m_q0 = q0;
92 }
93 
94 inline const Quaternion& DualQuaternion::getQe() const {
95  return m_qe;
96 }
97 
98 inline void DualQuaternion::setQe( const Quaternion& qe ) {
99  m_qe = qe;
100 }
101 
103  return DualQuaternion( m_q0 + other.m_q0, m_qe + other.m_qe );
104 }
105 
106 inline DualQuaternion DualQuaternion::operator*( Scalar scalar ) const {
107  return DualQuaternion( scalar * m_q0, scalar * m_qe );
108 }
109 
110 inline DualQuaternion& DualQuaternion::operator+=( const DualQuaternion& other ) {
111  *this = *this + other;
112  return *this;
113 }
114 
115 inline DualQuaternion& DualQuaternion::operator*=( Scalar scalar ) {
116  *this = *this * scalar;
117  return *this;
118 }
119 
121  const Scalar norm = m_q0.norm();
122  CORE_ASSERT( norm != 0, "Normalizing a null quaternion." );
123  m_q0 = m_q0 / norm;
124  m_qe = m_qe / norm;
125 }
126 
127 inline Vector3 DualQuaternion::transform( const Vector3& p ) const {
128  CORE_ASSERT( Ra::Core::Math::areApproxEqual( m_q0.norm(), 1_ra ),
129  "Dual quaternion not normalized" );
130  return translate( rotate( p ) );
131 }
132 
133 inline Vector3 DualQuaternion::rotate( const Vector3& p ) const {
134  CORE_ASSERT( Ra::Core::Math::areApproxEqual( m_q0.norm(), 1_ra ),
135  "Dual quaternion not normalized" );
136  return m_q0.toRotationMatrix() * p;
137 }
138 
139 inline Vector3 DualQuaternion::translate( const Vector3& p ) const {
140  Vector3 v0 = m_q0.vec();
141  Vector3 ve = m_qe.vec();
142  return p + ( ( ve * m_q0.w() - v0 * m_qe.w() + v0.cross( ve ) ) * 2_ra );
143 }
144 
145 inline DualQuaternion::DualQuaternion( const Core::Transform& tr ) {
146  setFromTransform( tr );
147 }
148 
149 inline Transform DualQuaternion::getTransform() const {
150  // Assume the dual quat is normalized.
151  CORE_ASSERT( Ra::Core::Math::areApproxEqual( m_q0.norm(), 1_ra ),
152  "Dual quaternion not normalized" );
153 
154  Transform result;
155  result.linear() = m_q0.toRotationMatrix();
156  result.translation() = ( 2_ra * m_q0 * m_qe.conjugate() ).vec();
157  return result;
158 }
159 
160 inline void DualQuaternion::setFromTransform( const Transform& t ) {
161  m_q0 = Quaternion( t.rotation() );
162  Core::Vector4 trans = Core::Vector4::Zero();
163  trans.head<3>() = t.translation();
164  m_qe = 0.5f * Quaternion( trans ) * m_q0;
165 }
166 
167 inline DualQuaternion operator*( Scalar scalar, const DualQuaternion& dq ) {
168  return dq * scalar;
169 }
170 
171 } // namespace Core
172 } // namespace Ra
void setFromTransform(const Transform &t)
Other methods.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW DualQuaternion()
Construct an uninitialized dual quaternion.
Vector3 transform(const Vector3 &p) const
DualQuaternion(const DualQuaternion &other)=default
Default copy constructor and assignment operator.
Transform getTransform() const
Return the corresponding rigid transform. Assume a unit dual quaternion.
DualQuaternion operator+(const DualQuaternion &other) const
Operators.
Vector3 translate(const Vector3 &p) const
Apply only the translational part of the dual quaternion to the given vector.
const Quaternion & getQ0() const
Getters and setters.
Vector3 rotate(const Vector3 &p) const
Apply only the rotational part of the dual quaternion to the given vector.
DualQuaternion(const Quaternion &q0, const Quaternion &qe)
Construct a dual-quaternion from two quaternions.
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type areApproxEqual(T x, T y, T espilonBoostFactor=T(10))
Compare two numbers such that |x-y| < espilon*epsilonBoostFactor.
Definition: Math.hpp:42
Definition: Cage.cpp:3