![]() |
Home | Libraries | People | FAQ | More |
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.
The interface and implementation are both supplied by the header file quaternion.hpp.
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
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
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
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.