12#ifndef CL_QUATERNION_HPP
13#define CL_QUATERNION_HPP
18#include <initializer_list>
31 template <
typename T >
47 mData{ T ( 0 ), T ( 0 ), T ( 0 ), T ( 0 ) }
59 mData [ 0 ] = T ( 0 );
60 mData [ 1 ] = aVector( 0 );
61 mData [ 2 ] = aVector( 1 );
62 mData [ 3 ] = aVector( 2 );
70 Quaternion (
const Vector < T > & aAxis,
const T aAngle )
75 T tNorm = std::sqrt( aAxis( 0 ) * aAxis( 0 ) + aAxis( 1 ) * aAxis( 1 ) + aAxis( 2 ) * aAxis( 2 ) );
78 T tHalfAngle = aAngle * T ( 0.5 );
79 T tSinHalf = std::sin( tHalfAngle ) / tNorm;
81 mData [ 0 ] = std::cos( tHalfAngle );
82 mData [ 1 ] = aAxis( 0 ) * tSinHalf;
83 mData [ 2 ] = aAxis( 1 ) * tSinHalf;
84 mData [ 3 ] = aAxis( 2 ) * tSinHalf;
93 return { T ( 1 ), T ( 0 ), T ( 0 ), T ( 0 ) };
180 BELFEM_ASSERT ( initList.size() == 4,
"Initializer list must be of length 4" );
182 for (
const T &
value : initList )
184 mData [ tCount++ ] =
value;
191 mData [ 0 ] += aOther.mData [ 0 ];
192 mData [ 1 ] += aOther.mData [ 1 ];
193 mData [ 2 ] += aOther.mData [ 2 ];
194 mData [ 3 ] += aOther.mData [ 3 ];
200 mData [ 0 ] -= aOther.mData [ 0 ];
201 mData [ 1 ] -= aOther.mData [ 1 ];
202 mData [ 2 ] -= aOther.mData [ 2 ];
203 mData [ 3 ] -= aOther.mData [ 3 ];
209 mData [ 0 ] *= aScalar;
210 mData [ 1 ] *= aScalar;
211 mData [ 2 ] *= aScalar;
212 mData [ 3 ] *= aScalar;
219 mData [ 0 ] /= aScalar;
220 mData [ 1 ] /= aScalar;
221 mData [ 2 ] /= aScalar;
222 mData [ 3 ] /= aScalar;
233 T a2 = aOther.mData [ 0 ];
234 T b2 = aOther.mData [ 1 ];
235 T c2 = aOther.mData [ 2 ];
236 T d2 = aOther.mData [ 3 ];
238 mData [ 0 ] = a1 * a2 - b1 * b2 - c1 * c2 - d1 * d2;
239 mData [ 1 ] = a1 * b2 + b1 * a2 + c1 * d2 - d1 * c2;
240 mData [ 2 ] = a1 * c2 - b1 * d2 + c1 * a2 + d1 * b2;
241 mData [ 3 ] = a1 * d2 + b1 * c2 - c1 * b2 + d1 * a2;
251 return std::sqrt ( mData [ 0 ] * mData [ 0 ] + mData [ 1 ] * mData [ 1 ] + mData [ 2 ] * mData [ 2 ] + mData [ 3 ] * mData [ 3 ] );
257 return { mData [ 0 ], -mData [ 1 ], -mData [ 2 ], -mData [ 3 ] };
263 T tSqNorm = mData [ 0 ] * mData [ 0 ] + mData [ 1 ] * mData [ 1 ] + mData [ 2 ] * mData [ 2 ] + mData [ 3 ] * mData [ 3 ];
265 return conj() / tSqNorm;
286 rotate(
const Vector < T > & aVector )
const
289 "rotate() requires a unit quaternion" );
299 Vector < T > tOut( 3 );
300 tOut( 0 ) = tResult.
b();
301 tOut( 1 ) = tResult.
c();
302 tOut( 2 ) = tResult.
d();
308 template <
typename T >
309 Quaternion < T >
operator+ (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
311 Quaternion < T > aResult = aLHS;
316 template <
typename T >
317 Quaternion < T >
operator- (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
319 Quaternion < T > aResult = aLHS;
324 template <
typename T >
325 Quaternion < T >
operator* (
const Quaternion < T > & aLHS, T aScalar )
327 Quaternion < T > aResult = aLHS;
332 template <
typename T >
333 Quaternion < T >
operator* ( T aScalar,
const Quaternion < T > & aRHS )
335 return aRHS * aScalar;
338 template <
typename T >
339 Quaternion < T >
operator/ (
const Quaternion < T > & aLHS, T aScalar )
341 Quaternion < T > aResult = aLHS;
346 template <
typename T >
347 Quaternion < T >
operator* (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
349 Quaternion < T > aResult = aLHS;
357 template <
typename T >
358 bool operator== (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
371 template <
typename T >
372 bool operator!= (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
374 return ! ( aLHS == aRHS );
377 template <
typename T >
378 T
dot (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
380 return aLHS.
a() * aRHS.
a() + aLHS.
b() * aRHS.
b() + aLHS.
c() * aRHS.
c() + aLHS.
d() * aRHS.
d();
383 template <
typename T >
384 Quaternion < T >
cross (
const Quaternion < T > & aLHS,
const Quaternion < T > & aRHS )
386 return { T ( 0 ), aLHS.
c() * aRHS.
d() - aLHS.
d() * aRHS.
c(), aLHS.
d() * aRHS.
b() - aLHS.
b() * aRHS.
d(), aLHS.
b() * aRHS.
c() - aLHS.
c() * aRHS.
b() };
399 template <
typename T >
400 Quaternion < T >
slerp (
const Quaternion < T > & aQ1,
const Quaternion < T > & aQ2, T aT )
403 "slerp: aQ1 must be a unit quaternion" );
405 "slerp: aQ2 must be a unit quaternion" );
408 T tCosTheta =
dot( aQ1, aQ2 );
411 Quaternion < T > tQ2 = aQ2;
412 if ( tCosTheta < T ( 0 ) )
414 tQ2 = aQ2 * T ( -1 );
415 tCosTheta = -tCosTheta;
421 Quaternion < T > tResult = aQ1 * ( T ( 1 ) - aT ) + tQ2 * aT;
427 T tTheta = std::acos( tCosTheta );
428 T tSinTheta = std::sin( tTheta );
430 T tW1 = std::sin( ( T ( 1 ) - aT ) * tTheta ) / tSinTheta;
431 T tW2 = std::sin( aT * tTheta ) / tSinTheta;
433 return aQ1 * tW1 + tQ2 * tW2;
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
#define BELFEM_ASSERT(aCheck,...)
Definition assert.hpp:244
Scalar-first quaternion value type for 3D rotations.
Definition cl_Quaternion.hpp:33
Quaternion()
Definition cl_Quaternion.hpp:46
Quaternion< T > conj() const
Definition cl_Quaternion.hpp:255
T * end()
Definition cl_Quaternion.hpp:164
const T & a() const
Definition cl_Quaternion.hpp:115
T & a()
Definition cl_Quaternion.hpp:110
Quaternion & operator/=(T aScalar)
Definition cl_Quaternion.hpp:216
Quaternion & operator+=(const Quaternion &aOther)
Definition cl_Quaternion.hpp:189
T * begin()
Definition cl_Quaternion.hpp:154
Quaternion(const Vector< T > &aAxis, const T aAngle)
Construct a rotation quaternion from axis and angle.
Definition cl_Quaternion.hpp:70
Quaternion< T > inv() const
Definition cl_Quaternion.hpp:261
Quaternion & operator-=(const Quaternion &aOther)
Definition cl_Quaternion.hpp:198
const T & d() const
Definition cl_Quaternion.hpp:145
const T * data() const
Definition cl_Quaternion.hpp:105
Quaternion & operator=(std::initializer_list< T > initList)
Definition cl_Quaternion.hpp:178
Quaternion< T > & normalize()
Definition cl_Quaternion.hpp:269
Vector< T > rotate(const Vector< T > &aVector) const
Rotate a 3D vector by this unit quaternion.
Definition cl_Quaternion.hpp:286
Quaternion & operator*=(T aScalar)
Definition cl_Quaternion.hpp:207
const T * end() const
Definition cl_Quaternion.hpp:169
static Quaternion identity()
Definition cl_Quaternion.hpp:91
const T & c() const
Definition cl_Quaternion.hpp:135
T * data()
Definition cl_Quaternion.hpp:100
const T & b() const
Definition cl_Quaternion.hpp:125
T & d()
Definition cl_Quaternion.hpp:140
T & c()
Definition cl_Quaternion.hpp:130
Quaternion(T a, T b, T c, T d)
Definition cl_Quaternion.hpp:51
T & b()
Definition cl_Quaternion.hpp:120
const T * begin() const
Definition cl_Quaternion.hpp:159
T norm() const
Definition cl_Quaternion.hpp:249
Quaternion(const Vector< T > &aVector)
Definition cl_Quaternion.hpp:56
size_t length() const
get the length of the vector
Definition cl_AR_Vector.hpp:257
auto dot(const Vector< T > &aA, const Vector< T > &aB) -> decltype(arma::dot(aA.vector_data(), aB.vector_data()))
Scalar product of two vectors.
Definition fn_AR_dot.hpp:24
USER GUIDES:
Definition cl_Capacitor.cpp:16
auto operator+(const Matrix< T > &aA, const Matrix< T > &aB) -> decltype(aA.matrix_data()+aB.matrix_data())
Definition op_MatrixPlus.hpp:23
std::pair< real, unit > value
Definition typedefs.hpp:74
bool operator!=(const Quaternion< T > &aLHS, const Quaternion< T > &aRHS)
Definition cl_Quaternion.hpp:372
Quaternion< T > slerp(const Quaternion< T > &aQ1, const Quaternion< T > &aQ2, T aT)
Spherical linear interpolation between two quaternions.
Definition cl_Quaternion.hpp:400
constexpr real BELFEM_EPSILON
Definition typedefs.hpp:90
auto operator/(const Vector< T > &aA, const T &aB) -> decltype(aA.vector_data()/aB)
Definition op_VectorDivide.hpp:23
auto cross(const ET &aA, const ET &aB) -> decltype(arma::cross(aA, aB))
Definition fn_AR_cross.hpp:23
auto operator*(const Matrix< T > &aA, const Matrix< T > &aB) -> decltype(aA.matrix_data() *aB.matrix_data())
Definition op_MatrixTimes.hpp:24
auto operator-(const Matrix< T > &aA, const Matrix< T > &aB) -> decltype(aA.matrix_data() - aB.matrix_data())
Definition op_MatrixMinus.hpp:23
bool operator==(const Matrix< T > &aA, const Matrix< T > &aB)
Definition op_AR_MatrixEqualEqual.hpp:23