Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Quaternions

Overview
Header File
Synopsis
Template Class quaternion
Quaternion Specializations
Quaternion Member Typedefs
Quaternion Member Functions
Quaternion Non-Member Operators
Quaternion Value Operations
Quaternion Creation Functions
Quaternion Transcendentals
Test Program
Acknowledgements
History
To Do

Overview

Quaternions are a relative of complex numbers.

Quaternions are in fact part of a small hierarchy of structures built upon the real numbers, which comprise only the set of real numbers (traditionally named R), the set of complex numbers (traditionally named C), the set of quaternions (traditionally named H) and the set of octonions (traditionally named O), which possess interesting mathematical properties (chief among which is the fact that they are division algebras, i.e. where the following property is true: if y is an element of that algebra and is not equal to zero, then yx = yx', where x and x' denote elements of that algebra, implies that x = x'). Each member of the hierarchy is a super-set of the former.

One of the most important aspects of quaternions is that they provide an efficient way to parameterize rotations in R3 (the usual three-dimensional space) and R4 .

In practical terms, a quaternion is simply a quadruple of real numbers ( α,β,γ,δ ), which we can write in the form q = α + βi + γj + δk , where i is the same object as for complex numbers, and j and k are distinct objects which play essentially the same kind of role as i.

An addition and a multiplication is defined on the set of quaternions, which generalize their real and complex counterparts. The main novelty here is that the multiplication is not commutative (i.e. there are quaternions x and y such that xy ≠ yx). A good mnemotechnical way of remembering things is by using the formula i*i = j*j = k*k = -1.

Quaternions (and their kin) are described in far more details in this other document (with errata and addenda).

Some traditional constructs, such as the exponential, carry over without too much change into the realms of quaternions, but other, such as taking a square root, do not.

Header File

The interface and implementation are both supplied by the header file quaternion.hpp.

Synopsis

namespace boost{ namespace math{

template<typename T> class quaternion;
template<>           class quaternion<float>;
template<>           class quaternion<double>; 
template<>           class quaternion<long double>; 

// operators
template<typename T> quaternion<T> operator + (T const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator + (quaternion<T> const & lhs, T const & rhs);
template<typename T> quaternion<T> operator + (::std::complex<T> const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator + (quaternion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T> quaternion<T> operator + (quaternion<T> const & lhs, quaternion<T> const & rhs);

template<typename T> quaternion<T> operator - (T const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator - (quaternion<T> const & lhs, T const & rhs);
template<typename T> quaternion<T> operator - (::std::complex<T> const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator - (quaternion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T> quaternion<T> operator - (quaternion<T> const & lhs, quaternion<T> const & rhs);

template<typename T> quaternion<T> operator * (T const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator * (quaternion<T> const & lhs, T const & rhs);
template<typename T> quaternion<T> operator * (::std::complex<T> const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator * (quaternion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T> quaternion<T> operator * (quaternion<T> const & lhs, quaternion<T> const & rhs);

template<typename T> quaternion<T> operator / (T const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator / (quaternion<T> const & lhs, T const & rhs);
template<typename T> quaternion<T> operator / (::std::complex<T> const & lhs, quaternion<T> const & rhs);
template<typename T> quaternion<T> operator / (quaternion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T> quaternion<T> operator / (quaternion<T> const & lhs, quaternion<T> const & rhs); 

template<typename T> quaternion<T> operator + (quaternion<T> const & q);
template<typename T> quaternion<T> operator - (quaternion<T> const & q); 

template<typename T> bool operator == (T const & lhs, quaternion<T> const & rhs);
template<typename T> bool operator == (quaternion<T> const & lhs, T const & rhs);
template<typename T> bool operator == (::std::complex<T> const & lhs, quaternion<T> const & rhs);
template<typename T> bool operator == (quaternion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T> bool operator == (quaternion<T> const & lhs, quaternion<T> const & rhs);

template<typename T> bool operator != (T const & lhs, quaternion<T> const & rhs);
template<typename T> bool operator != (quaternion<T> const & lhs, T const & rhs);
template<typename T> bool operator != (::std::complex<T> const & lhs, quaternion<T> const & rhs);
template<typename T> bool operator != (quaternion<T> const & lhs, ::std::complex<T> const & rhs);
template<typename T> bool operator != (quaternion<T> const & lhs, quaternion<T> const & rhs); 

template<typename T, typename charT, class traits>
::std::basic_istream<charT,traits>& operator >> (::std::basic_istream<charT,traits> & is, quaternion<T> & q);

template<typename T, typename charT, class traits>
::std::basic_ostream<charT,traits>& operator operator << (::std::basic_ostream<charT,traits> & os, quaternion<T> const & q);

// values
template<typename T>	T              real(quaternion<T> const & q);
template<typename T>	quaternion<T>  unreal(quaternion<T> const & q);

template<typename T>	T              sup(quaternion<T> const & q);
template<typename T>	T              l1(quaternion<T> const & q);
template<typename T>	T              abs(quaternion<T> const & q);
template<typename T>	T              norm(quaternion<T>const  & q);
template<typename T>	quaternion<T>  conj(quaternion<T> const & q);

template<typename T>	quaternion<T>  spherical(T const & rho, T const & theta, T const & phi1, T const & phi2);
template<typename T>	quaternion<T>  semipolar(T const & rho, T const & alpha, T const & theta1, T const & theta2);
template<typename T>	quaternion<T>  multipolar(T const & rho1, T const & theta1, T const & rho2, T const & theta2);
template<typename T>	quaternion<T>  cylindrospherical(T const & t, T const & radius, T const & longitude, T const & latitude);
template<typename T>	quaternion<T>  cylindrical(T const & r, T const & angle, T const & h1, T const & h2);

// transcendentals
template<typename T>	quaternion<T>  exp(quaternion<T> const & q);
template<typename T>	quaternion<T>  cos(quaternion<T> const & q);
template<typename T>	quaternion<T>  sin(quaternion<T> const & q);
template<typename T>	quaternion<T>  tan(quaternion<T> const & q);
template<typename T>	quaternion<T>  cosh(quaternion<T> const & q);
template<typename T>	quaternion<T>  sinh(quaternion<T> const & q);
template<typename T>	quaternion<T>  tanh(quaternion<T> const & q);
template<typename T>	quaternion<T>  pow(quaternion<T> const & q, int n);

} // namespace math
} // namespace boost

Template Class quaternion

namespace boost{ namespace math{

template<typename T>
class quaternion
{
public:

   typedef T value_type;

   explicit quaternion(T const & requested_a = T(), T const & requested_b = T(), T const & requested_c = T(), T const & requested_d = T());
   explicit quaternion(::std::complex<T> const & z0, ::std::complex<T> const & z1 = ::std::complex<T>());
   template<typename X> 
   explicit quaternion(quaternion<X> const & a_recopier);

   T                  real() const;
   quaternion<T>      unreal() const;
   T                  R_component_1() const;
   T                  R_component_2() const;
   T                  R_component_3() const;
   T                  R_component_4() const;
   ::std::complex<T>  C_component_1() const;
   ::std::complex<T>  C_component_2() const;

   quaternion<T>&     operator = (quaternion<T> const  & a_affecter);
   template<typename X>	
   quaternion<T>&     operator = (quaternion<X> const  & a_affecter);
   quaternion<T>&     operator = (T const  & a_affecter);
   quaternion<T>&     operator = (::std::complex<T> const & a_affecter);

   quaternion<T>&     operator += (T const & rhs);
   quaternion<T>&     operator += (::std::complex<T> const & rhs);
   template<typename X>
   quaternion<T>&     operator += (quaternion<X> const & rhs);

   quaternion<T>&     operator -= (T const & rhs);
   quaternion<T>&     operator -= (::std::complex<T> const & rhs);
   template<typename X>
   quaternion<T>&     operator -= (quaternion<X> const & rhs);

   quaternion<T>&     operator *= (T const & rhs);
   quaternion<T>&     operator *= (::std::complex<T> const & rhs);
   template<typename X>
   quaternion<T>&     operator *= (quaternion<X> const & rhs);

   quaternion<T>&     operator /= (T const & rhs);
   quaternion<T>&     operator /= (::std::complex<T> const & rhs);
   template<typename X>
   quaternion<T>&     operator /= (quaternion<X> const & rhs);
};

} // namespace math
} // namespace boost

Quaternion Specializations

namespace boost{ namespace math{

template<>
class quaternion<float>
{
public:
   typedef float value_type;
	
   explicit quaternion(float const & requested_a = 0.0f, float const & requested_b = 0.0f, float const & requested_c = 0.0f, float const & requested_d = 0.0f);
   explicit quaternion(::std::complex<float> const & z0, ::std::complex<float> const & z1 = ::std::complex<float>());
   explicit quaternion(quaternion<double> const & a_recopier);
   explicit quaternion(quaternion<long double> const & a_recopier);
	
   float                  real() const;
   quaternion<float>      unreal() const;
   float                  R_component_1() const;
   float                  R_component_2() const;
   float                  R_component_3() const;
   float                  R_component_4() const;
   ::std::complex<float>  C_component_1() const;
   ::std::complex<float>  C_component_2() const;

   quaternion<float>&     operator = (quaternion<float> const  & a_affecter);
   template<typename X>	
   quaternion<float>&     operator = (quaternion<X> const  & a_affecter);
   quaternion<float>&     operator = (float const  & a_affecter);
   quaternion<float>&     operator = (::std::complex<float> const & a_affecter);

   quaternion<float>&     operator += (float const & rhs);
   quaternion<float>&     operator += (::std::complex<float> const & rhs);
   template<typename X>
   quaternion<float>&     operator += (quaternion<X> const & rhs);

   quaternion<float>&     operator -= (float const & rhs);
   quaternion<float>&     operator -= (::std::complex<float> const & rhs);
   template<typename X>
   quaternion<float>&     operator -= (quaternion<X> const & rhs);

   quaternion<float>&     operator *= (float const & rhs);
   quaternion<float>&     operator *= (::std::complex<float> const & rhs);
   template<typename X>
   quaternion<float>&     operator *= (quaternion<X> const & rhs);

   quaternion<float>&     operator /= (float const & rhs);
   quaternion<float>&     operator /= (::std::complex<float> const & rhs);
   template<typename X>
   quaternion<float>&     operator /= (quaternion<X> const & rhs);
};

template<>
class quaternion<double>
{
public:
   typedef double value_type;
	
   explicit quaternion(double const & requested_a = 0.0, double const & requested_b = 0.0, double const & requested_c = 0.0, double const & requested_d = 0.0);
   explicit quaternion(::std::complex<double> const & z0, ::std::complex<double> const & z1 = ::std::complex<double>());
   explicit quaternion(quaternion<float> const & a_recopier);
   explicit quaternion(quaternion<long double> const & a_recopier);
	
   double                  real() const;
   quaternion<double>      unreal() const;
   double                  R_component_1() const;
   double                  R_component_2() const;
   double                  R_component_3() const;
   double                  R_component_4() const;
   ::std::complex<double>  C_component_1() const;
   ::std::complex<double>  C_component_2() const;

   quaternion<double>&     operator = (quaternion<double> const  & a_affecter);
   template<typename X>	
   quaternion<double>&     operator = (quaternion<X> const  & a_affecter);
   quaternion<double>&     operator = (double const  & a_affecter);
   quaternion<double>&     operator = (::std::complex<double> const & a_affecter);

   quaternion<double>&     operator += (double const & rhs);
   quaternion<double>&     operator += (::std::complex<double> const & rhs);
   template<typename X>
   quaternion<double>&     operator += (quaternion<X> const & rhs);

   quaternion<double>&     operator -= (double const & rhs);
   quaternion<double>&     operator -= (::std::complex<double> const & rhs);
   template<typename X>
   quaternion<double>&     operator -= (quaternion<X> const & rhs);

   quaternion<double>&     operator *= (double const & rhs);
   quaternion<double>&     operator *= (::std::complex<double> const & rhs);
   template<typename X>
   quaternion<double>&     operator *= (quaternion<X> const & rhs);

   quaternion<double>&     operator /= (double const & rhs);
   quaternion<double>&     operator /= (::std::complex<double> const & rhs);
   template<typename X>
   quaternion<double>&     operator /= (quaternion<X> const & rhs);
};

template<>
class quaternion<long double>
{
public:
   typedef long double value_type;
	
   explicit quaternion(long double const & requested_a = 0.0L, long double const & requested_b = 0.0L, long double const & requested_c = 0.0L, long double const & requested_d = 0.0L);
   explicit quaternion(::std::complex<long double> const & z0, ::std::complex<long double> const & z1 = ::std::complex<long double>());
   explicit quaternion(quaternion<float> const & a_recopier);
   explicit quaternion(quaternion<double> const & a_recopier);
	
   long double                  real() const;
   quaternion<long double>      unreal() const;
   long double                  R_component_1() const;
   long double                  R_component_2() const;
   long double                  R_component_3() const;
   long double                  R_component_4() const;
   ::std::complex<long double>  C_component_1() const;
   ::std::complex<long double>  C_component_2() const;

   quaternion<long double>&     operator = (quaternion<long double> const  & a_affecter);
   template<typename X>	
   quaternion<long double>&     operator = (quaternion<X> const  & a_affecter);
   quaternion<long double>&     operator = (long double const  & a_affecter);
   quaternion<long double>&     operator = (::std::complex<long double> const & a_affecter);

   quaternion<long double>&     operator += (long double const & rhs);
   quaternion<long double>&     operator += (::std::complex<long double> const & rhs);
   template<typename X>
   quaternion<long double>&     operator += (quaternion<X> const & rhs);

   quaternion<long double>&     operator -= (long double const & rhs);
   quaternion<long double>&     operator -= (::std::complex<long double> const & rhs);
   template<typename X>
   quaternion<long double>&     operator -= (quaternion<X> const & rhs);

   quaternion<long double>&     operator *= (long double const & rhs);
   quaternion<long double>&     operator *= (::std::complex<long double> const & rhs);
   template<typename X>
   quaternion<long double>&     operator *= (quaternion<X> const & rhs);

   quaternion<long double>&     operator /= (long double const & rhs);
   quaternion<long double>&     operator /= (::std::complex<long double> const & rhs);
   template<typename X>
   quaternion<long double>&     operator /= (quaternion<X> const & rhs);
};

} // namespace math
} // namespace boost

Quaternion Member Typedefs

value_type

Template version:

typedef T value_type;

Float specialization version:

typedef float value_type;

Double specialization version:

typedef double value_type;

Long double specialization version:

typedef long double value_type;

These provide easy acces to the type the template is built upon.

Quaternion Member Functions

Constructors

Template version:

explicit quaternion(T const & requested_a = T(), T const & requested_b =