2013-11-06 22:52:00 +01:00
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Linear Math Quaternions
|
|
|
|
|
// <20> Dan Andersson 2013
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#ifndef LINEARALGEBRA_QUATERNION_H
|
|
|
|
|
#define LINEARALGEBRA_QUATERNION_H
|
|
|
|
|
|
|
|
|
|
#include "Vector.h"
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
namespace LinearAlgebra
|
|
|
|
|
{
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
struct Quaternion
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
union
|
|
|
|
|
{
|
2013-11-09 01:23:30 +01:00
|
|
|
|
struct{ Vector3<ScalarType> imaginary; ScalarType real; };
|
|
|
|
|
ScalarType element[4];
|
|
|
|
|
char byte[sizeof(ScalarType[2])];
|
2013-11-06 22:52:00 +01:00
|
|
|
|
};
|
|
|
|
|
|
2013-12-19 21:39:20 +01:00
|
|
|
|
static const Quaternion<ScalarType> null;
|
|
|
|
|
static const Quaternion<ScalarType> identity;
|
|
|
|
|
|
2013-11-06 22:52:00 +01:00
|
|
|
|
Quaternion( );
|
2013-11-09 01:23:30 +01:00
|
|
|
|
Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
operator ScalarType* ( );
|
|
|
|
|
operator const ScalarType* ( ) const;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
operator char* ( );
|
|
|
|
|
operator const char* ( ) const;
|
2013-11-09 01:23:30 +01:00
|
|
|
|
ScalarType & operator [] ( int i );
|
|
|
|
|
const ScalarType & operator [] ( int i ) const;
|
|
|
|
|
|
|
|
|
|
Quaternion<ScalarType> & operator = ( const Quaternion<ScalarType> &quaternion );
|
2014-02-18 12:03:54 +01:00
|
|
|
|
Quaternion<ScalarType> & operator *= ( const Quaternion<ScalarType> &quaternion );
|
2013-11-09 01:23:30 +01:00
|
|
|
|
Quaternion<ScalarType> & operator *= ( const ScalarType &scalar );
|
|
|
|
|
Quaternion<ScalarType> & operator /= ( const ScalarType &scalar );
|
|
|
|
|
Quaternion<ScalarType> & operator += ( const Quaternion<ScalarType> &quaternion );
|
|
|
|
|
Quaternion<ScalarType> & operator -= ( const Quaternion<ScalarType> &quaternion );
|
|
|
|
|
Quaternion<ScalarType> operator * ( const Quaternion<ScalarType> &quaternion ) const;
|
|
|
|
|
Quaternion<ScalarType> operator * ( const Vector3<ScalarType> &vector ) const;
|
|
|
|
|
Quaternion<ScalarType> operator * ( const ScalarType &scalar ) const;
|
|
|
|
|
Quaternion<ScalarType> operator / ( const ScalarType &scalar ) const;
|
|
|
|
|
Quaternion<ScalarType> operator + ( const Quaternion<ScalarType> &quaternion ) const;
|
|
|
|
|
Quaternion<ScalarType> operator - ( const Quaternion<ScalarType> &quaternion ) const;
|
|
|
|
|
Quaternion<ScalarType> operator - ( ) const;
|
|
|
|
|
|
2014-02-19 14:51:37 +01:00
|
|
|
|
Quaternion<ScalarType> & Conjugate( );
|
|
|
|
|
Quaternion<ScalarType> & Normalize( );
|
|
|
|
|
Quaternion<ScalarType> & Inverse( );
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
Quaternion<ScalarType> GetConjugate( ) const;
|
2014-02-19 14:51:37 +01:00
|
|
|
|
Quaternion<ScalarType> GetNormalized( ) const;
|
|
|
|
|
Quaternion<ScalarType> GetInversed( ) const;
|
|
|
|
|
ScalarType GetNorm( ) const;
|
|
|
|
|
ScalarType GetModulus( ) const;
|
|
|
|
|
|
2013-11-06 22:52:00 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Body
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2013-12-19 21:39:20 +01:00
|
|
|
|
template<typename ScalarType> const Quaternion<ScalarType> Quaternion<ScalarType>::null = Quaternion<ScalarType>( Vector3<ScalarType>((ScalarType)0), (ScalarType)0 );
|
|
|
|
|
template<typename ScalarType> const Quaternion<ScalarType> Quaternion<ScalarType>::identity = Quaternion<ScalarType>( Vector3<ScalarType>((ScalarType)0), (ScalarType)1 );
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
2013-12-19 21:39:20 +01:00
|
|
|
|
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real )
|
|
|
|
|
{
|
|
|
|
|
this->imaginary = imaginary;
|
|
|
|
|
this->real = real;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType>::operator ScalarType* ( )
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return this->element;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return this->element;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType>::operator char* ( )
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return this->byte;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType>::operator const char* ( ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return this->byte;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return this->element[i];
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return this->element[i];
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
this->imaginary = quaternion.imaginary;
|
|
|
|
|
this->real = quaternion.real;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-18 12:03:54 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator *= ( const Quaternion<ScalarType> &quaternion )
|
|
|
|
|
{
|
|
|
|
|
return *this = *this * quaternion;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator *= ( const ScalarType &scalar )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
this->imaginary *= scalar;
|
|
|
|
|
this->real *= scalar;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator /= ( const ScalarType &scalar )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
this->imaginary /= scalar;
|
|
|
|
|
this->real /= scalar;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator += ( const Quaternion<ScalarType> &quaternion )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
this->imaginary += quaternion.imaginary;
|
|
|
|
|
this->real += quaternion.real;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator -= ( const Quaternion<ScalarType> &quaternion )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
this->imaginary -= quaternion.imaginary;
|
|
|
|
|
this->real -= quaternion.real;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const Quaternion<ScalarType> &quaternion ) const
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
2013-11-09 01:23:30 +01:00
|
|
|
|
Vector3<ScalarType> im = this->imaginary.Cross( quaternion.imaginary );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
im += (quaternion.imaginary * this->real);
|
|
|
|
|
im += (this->imaginary * quaternion.real);
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
ScalarType re = this->real * quaternion.real;
|
|
|
|
|
re -= this->imaginary.Dot( quaternion.imaginary );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
return Quaternion<ScalarType>( im, re );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const Vector3<ScalarType> &vector ) const
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
2013-11-09 01:23:30 +01:00
|
|
|
|
Vector3<ScalarType> im = this->imaginary.Cross( vector );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
im += (vector * this->real);
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
ScalarType re = this->imaginary.Dot( vector ) * -1;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
return Quaternion<ScalarType>( im, re );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return Quaternion<ScalarType>(*this) *= scalar;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return Quaternion<ScalarType>(*this) /= scalar;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return Quaternion<ScalarType>(*this) += quaternion;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return Quaternion<ScalarType>(*this) -= quaternion;
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return Quaternion<ScalarType>(-this->imaginary, -this->real);
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
2014-02-19 14:51:37 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> & Quaternion<ScalarType>::Conjugate( )
|
|
|
|
|
{
|
|
|
|
|
this->imaginary = -this->imaginary;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> & Quaternion<ScalarType>::Normalize( )
|
|
|
|
|
{
|
|
|
|
|
return *this /= this->GetModulus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> & Quaternion<ScalarType>::Inverse( )
|
|
|
|
|
{
|
|
|
|
|
return this->Conjugate() /= this->GetNorm();
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 01:23:30 +01:00
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
|
2013-12-19 21:39:20 +01:00
|
|
|
|
{
|
|
|
|
|
return Quaternion<ScalarType>(-this->imaginary, this->real );
|
|
|
|
|
}
|
2014-02-19 14:51:37 +01:00
|
|
|
|
|
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetNormalized( ) const
|
|
|
|
|
{
|
|
|
|
|
return *this / this->GetModulus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetInversed( ) const
|
|
|
|
|
{
|
|
|
|
|
return this->GetConjugate() /= this->GetNorm();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline ScalarType Quaternion<ScalarType>::GetNorm( ) const
|
|
|
|
|
{
|
|
|
|
|
return this->imaginary.Dot(this->imaginary) + this->real * this->real;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename ScalarType>
|
|
|
|
|
inline ScalarType Quaternion<ScalarType>::GetModulus( ) const
|
|
|
|
|
{
|
|
|
|
|
return (ScalarType)::std::sqrt( this->GetNorm() );
|
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|