template<class T>
Magnum::Math::Quaternion class

Quaternion.

Template parameters
T Underlying data type

Represents 3D rotation. Usually denoted as the following in equations, with $ \boldsymbol{q}_V $ being the vector() part and $ q_S $ being the scalar() part:

\[ q = [\boldsymbol{q}_V, q_S] \]

See 2D and 3D transformations for a brief introduction.

Public types

using Type = T
Underlying data type.

Public static functions

static auto rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) -> Quaternion<T>
Rotation quaternion.
static auto fromMatrix(const Matrix3x3<T>& matrix) -> Quaternion<T>
Create quaternion from rotation matrix.

Constructors, destructors, conversion operators

Quaternion(IdentityInitT = IdentityInit) constexpr noexcept
Default constructor.
Quaternion(ZeroInitT) explicit constexpr noexcept
Construct zero-initialized quaternion.
Quaternion(NoInitT) explicit noexcept
Construct without initializing the contents.
Quaternion(const Vector3<T>& vector, T scalar) constexpr noexcept
Construct quaternion from vector and scalar.
Quaternion(const Vector3<T>& vector) explicit constexpr noexcept
Construct quaternion from vector.
template<class U>
Quaternion(const Quaternion<U>& other) explicit constexpr noexcept
Construct dual complex number from another of different type.
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::from(std::declval<U>()))>
Quaternion(const U& other) explicit constexpr
Construct quaternion from external representation.
Quaternion(const Quaternion<T>&) noexcept defaulted constexpr
Copy constructor.
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::to(std::declval<Quaternion<T>>()))>
operator U() const explicit constexpr
Convert quaternion to external representation.

Public functions

auto operator==(const Quaternion<T>& other) const -> bool
Equality comparison.
auto operator!=(const Quaternion<T>& other) const -> bool
Non-equality comparison.
auto isNormalized() const -> bool
Whether the quaternion is normalized.
auto vector() -> Vector3<T>&
Vector part ( $ \boldsymbol{q}_V $ )
auto vector() const -> const Vector3<T> constexpr
auto scalar() -> T&
Scalar part ( $ q_S $ )
auto scalar() const -> T constexpr
auto angle() const -> Rad<T>
Rotation angle of unit quaternion.
auto axis() const -> Vector3<T>
Rotation axis of unit quaternion.
auto toMatrix() const -> Matrix3x3<T>
Convert quaternion to rotation matrix.
auto operator+=(const Quaternion<T>& other) -> Quaternion<T>&
Add and assign quaternion.
auto operator+(const Quaternion<T>& other) const -> Quaternion<T>
Add quaternion.
auto operator-() const -> Quaternion<T>
Negated quaternion.
auto operator-=(const Quaternion<T>& other) -> Quaternion<T>&
Subtract and assign quaternion.
auto operator-(const Quaternion<T>& other) const -> Quaternion<T>
Subtract quaternion.
auto operator*=(T scalar) -> Quaternion<T>&
Multiply with scalar and assign.
auto operator*(T scalar) const -> Quaternion<T>
Multiply with scalar.
auto operator/=(T scalar) -> Quaternion<T>&
Divide with scalar and assign.
auto operator/(T scalar) const -> Quaternion<T>
Divide with scalar.
auto operator*(const Quaternion<T>& other) const -> Quaternion<T>
Multiply with quaternion.
auto dot() const -> T
Dot product of the quaternion.
auto length() const -> T
Quaternion length.
auto normalized() const -> Quaternion<T>
Normalized quaternion (of unit length)
auto conjugated() const -> Quaternion<T>
Conjugated quaternion.
auto inverted() const -> Quaternion<T>
Inverted quaternion.
auto invertedNormalized() const -> Quaternion<T>
Inverted normalized quaternion.
auto transformVector(const Vector3<T>& vector) const -> Vector3<T>
Rotate vector with quaternion.
auto transformVectorNormalized(const Vector3<T>& vector) const -> Vector3<T>
Rotate vector with normalized quaternion.

Function documentation

template<class T>
static Quaternion<T> Magnum::Math::Quaternion<T>::rotation(Rad<T> angle, const Vector3<T>& normalizedAxis)

Rotation quaternion.

Parameters
angle Rotation angle (counterclockwise)
normalizedAxis Normalized rotation axis

Expects that the rotation axis is normalized.

\[ q = [\boldsymbol a \cdot sin \frac \theta 2, cos \frac \theta 2] \]

template<class T>
static Quaternion<T> Magnum::Math::Quaternion<T>::fromMatrix(const Matrix3x3<T>& matrix)

Create quaternion from rotation matrix.

Expects that the matrix is orthogonal (i.e. pure rotation).

template<class T>
Magnum::Math::Quaternion<T>::Quaternion(IdentityInitT = IdentityInit) constexpr noexcept

Default constructor.

Creates unit quaternion.

\[ q = [\boldsymbol 0, 1] \]

template<class T>
Magnum::Math::Quaternion<T>::Quaternion(const Vector3<T>& vector, T scalar) constexpr noexcept

Construct quaternion from vector and scalar.

\[ q = [\boldsymbol v, s] \]

template<class T>
Magnum::Math::Quaternion<T>::Quaternion(const Vector3<T>& vector) explicit constexpr noexcept

Construct quaternion from vector.

To be used in transformations later.

\[ q = [\boldsymbol v, 0] \]

template<class T> template<class U>
Magnum::Math::Quaternion<T>::Quaternion(const Quaternion<U>& other) explicit constexpr noexcept

Construct dual complex number from another of different type.

Performs only default casting on the values, no rounding or anything else.

template<class T>
bool Magnum::Math::Quaternion<T>::isNormalized() const

Whether the quaternion is normalized.

Quaternion is normalized if it has unit length:

\[ |q \cdot q - 1| < 2 \epsilon + \epsilon^2 \cong 2 \epsilon \]

template<class T>
const Vector3<T> Magnum::Math::Quaternion<T>::vector() const constexpr

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
T Magnum::Math::Quaternion<T>::scalar() const constexpr

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
Rad<T> Magnum::Math::Quaternion<T>::angle() const

Rotation angle of unit quaternion.

Expects that the quaternion is normalized.

\[ \theta = 2 \cdot \arccos(q_S) \]

template<class T>
Vector3<T> Magnum::Math::Quaternion<T>::axis() const

Rotation axis of unit quaternion.

Expects that the quaternion is normalized. Returns either unit-length vector for valid rotation quaternion or NaN vector for default-constructed quaternion.

\[ \boldsymbol a = \frac{\boldsymbol q_V}{\sqrt{1 - q_S^2}} \]

template<class T>
Matrix3x3<T> Magnum::Math::Quaternion<T>::toMatrix() const

Convert quaternion to rotation matrix.

template<class T>
Quaternion<T>& Magnum::Math::Quaternion<T>::operator+=(const Quaternion<T>& other)

Add and assign quaternion.

The computation is done in-place.

\[ p + q = [\boldsymbol p_V + \boldsymbol q_V, p_S + q_S] \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::operator+(const Quaternion<T>& other) const

Add quaternion.

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::operator-() const

Negated quaternion.

\[ -q = [-\boldsymbol q_V, -q_S] \]

template<class T>
Quaternion<T>& Magnum::Math::Quaternion<T>::operator-=(const Quaternion<T>& other)

Subtract and assign quaternion.

The computation is done in-place.

\[ p - q = [\boldsymbol p_V - \boldsymbol q_V, p_S - q_S] \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::operator-(const Quaternion<T>& other) const

Subtract quaternion.

template<class T>
Quaternion<T>& Magnum::Math::Quaternion<T>::operator*=(T scalar)

Multiply with scalar and assign.

The computation is done in-place.

\[ q \cdot a = [\boldsymbol q_V \cdot a, q_S \cdot a] \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::operator*(T scalar) const

Multiply with scalar.

template<class T>
Quaternion<T>& Magnum::Math::Quaternion<T>::operator/=(T scalar)

Divide with scalar and assign.

The computation is done in-place.

\[ \frac q a = [\frac {\boldsymbol q_V} a, \frac {q_S} a] \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::operator/(T scalar) const

Divide with scalar.

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::operator*(const Quaternion<T>& other) const

Multiply with quaternion.

\[ p q = [p_S \boldsymbol q_V + q_S \boldsymbol p_V + \boldsymbol p_V \times \boldsymbol q_V, p_S q_S - \boldsymbol p_V \cdot \boldsymbol q_V] \]

template<class T>
T Magnum::Math::Quaternion<T>::dot() const

Dot product of the quaternion.

Should be used instead of length() for comparing quaternion length with other values, because it doesn't compute the square root.

\[ q \cdot q = \boldsymbol q_V \cdot \boldsymbol q_V + q_S^2 \]

template<class T>
T Magnum::Math::Quaternion<T>::length() const

Quaternion length.

See also dot() const which is faster for comparing length with other values.

\[ |q| = \sqrt{q \cdot q} \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::normalized() const

Normalized quaternion (of unit length)

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::conjugated() const

Conjugated quaternion.

\[ q^* = [-\boldsymbol q_V, q_S] \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::inverted() const

Inverted quaternion.

See invertedNormalized() which is faster for normalized quaternions.

\[ q^{-1} = \frac{q^*}{|q|^2} = \frac{q^*}{q \cdot q} \]

template<class T>
Quaternion<T> Magnum::Math::Quaternion<T>::invertedNormalized() const

Inverted normalized quaternion.

Equivalent to conjugated(). Expects that the quaternion is normalized.

\[ q^{-1} = \frac{q^*}{|q|^2} = q^* \]

template<class T>
Vector3<T> Magnum::Math::Quaternion<T>::transformVector(const Vector3<T>& vector) const

Rotate vector with quaternion.

See transformVectorNormalized(), which is faster for normalized quaternions.

\[ v' = qvq^{-1} = q [\boldsymbol v, 0] q^{-1} \]

template<class T>
Vector3<T> Magnum::Math::Quaternion<T>::transformVectorNormalized(const Vector3<T>& vector) const

Rotate vector with normalized quaternion.

Faster alternative to transformVector(), expects that the quaternion is normalized. Done using the following equation:

\[ \begin{array}{rcl} \boldsymbol t & = & 2 (\boldsymbol q_V \times \boldsymbol v) \\ \boldsymbol v' & = & \boldsymbol v + q_S \boldsymbol t + \boldsymbol q_V \times \boldsymbol t \end{array} \]

Which is equivalent to the common equation (source: https://molecularmusings.wordpress.com/2013/05/24/a-faster-quaternion-vector-multiplication/):

\[ v' = qvq^{-1} = qvq^* = q [\boldsymbol v, 0] q^* \]

template<class T> template<class T>
T dot(const Quaternion<T>& a, const Quaternion<T>& b)

Dot product between two quaternions.

\[ p \cdot q = \boldsymbol p_V \cdot \boldsymbol q_V + p_S q_S \]

template<class T> template<class T>
Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB)

Angle between normalized quaternions.

Expects that both quaternions are normalized.

\[ \theta = \arccos \left( \frac{p \cdot q}{|p| |q|} \right) = \arccos(p \cdot q) \]

template<class T> template<class T>
Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t)

Linear interpolation of two quaternions.

Parameters
normalizedA First quaternion
normalizedB Second quaternion
t Interpolation phase (from range $ [0; 1] $ )

Expects that both quaternions are normalized.

\[ q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|} \]

Note that this function does not check for shortest path interpolation, see lerpShortestPath(const Quaternion<T>&, const Quaternion<T>&, T) for an alternative.

template<class T> template<class T>
Quaternion<T> lerpShortestPath(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t)

Linear shortest-path interpolation of two quaternions.

Parameters
normalizedA First quaternion
normalizedB Second quaternion
t Interpolation phase (from range $ [0; 1] $ )

Unlike lerp(const Quaternion<T>&, const Quaternion<T>&, T), this interpolates on the shortest path at some performance expense. Expects that both quaternions are normalized.

\[ \begin{array}{rcl} d & = & q_A \cdot q_B \\[5pt] q'_A & = & \begin{cases} \phantom{-}q_A, & d \ge 0 \\ -q_A, & d < 0 \end{cases} \\[15pt] q_{LERP} & = & \cfrac{(1 - t) q'_A + t q_B}{|(1 - t) q'_A + t q_B|} \end{array} \]

template<class T> template<class T>
Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t)

Spherical linear interpolation of two quaternions.

Parameters
normalizedA First quaternion
normalizedB Second quaternion
t Interpolation phase (from range $ [0; 1] $ )

Expects that both quaternions are normalized. If the quaternions are the same or one is a negation of the other, it just returns the first argument:

\[ \begin{array}{rcl} d & = & q_A \cdot q_B \\[5pt] q_{SLERP} & = & q_A, ~ {\color{m-primary} \text{if} ~ d \ge 1} \end{array} \]

otherwise, the interpolation is performed as:

\[ \begin{array}{rcl} \theta & = & \arccos \left( \frac{q_A \cdot q_B}{|q_A| |q_B|} \right) = \arccos(q_A \cdot q_B) = \arccos(d) \\[5pt] q_{SLERP} & = & \cfrac{\sin((1 - t) \theta) q_A + \sin(t \theta) q_B}{\sin(\theta)} \end{array} \]

Note that this function does not check for shortest path interpolation, see slerpShortestPath(const Quaternion<T>&, const Quaternion<T>&, T) for an alternative.

template<class T> template<class T>
Quaternion<T> slerpShortestPath(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t)

Spherical linear shortest-path interpolation of two quaternions.

Parameters
normalizedA First quaternion
normalizedB Second quaternion
t Interpolation phase (from range $ [0; 1] $ )

Unlike slerp(const Quaternion<T>&, const Quaternion<T>&, T) this function interpolates on the shortest path. Expects that both quaternions are normalized. If the quaternions are the same or one is a negation of the other, it just returns the first argument:

\[ \begin{array}{rcl} d & = & q_A \cdot q_B \\ q_{SLERP} & = & q_A, ~ {\color{m-primary} \text{if} ~ d \ge 1} \end{array} \]

otherwise, the interpolation is performed as:

\[ \begin{array}{rcl} q'_A & = & \begin{cases} \phantom{-}q_A, & d \ge 0 \\ -q_A, & d < 0 \end{cases} \\[15pt] \theta & = & \arccos \left( \frac{|q'_A \cdot q_B|}{|q'_A| |q_B|} \right) = \arccos(|q'_A \cdot q_B|) = \arccos(|d|) \\[5pt] q_{SLERP} & = & \cfrac{\sin((1 - t) \theta) q'_A + \sin(t \theta) q_B}{\sin(\theta)} \end{array} \]

template<class T> template<class T>
Quaternion<T> operator*(T scalar, const Quaternion<T>& quaternion)

Multiply scalar with quaternion.

Same as Quaternion::operator*(T) const.

template<class T> template<class T>
Quaternion<T> operator/(T scalar, const Quaternion<T>& quaternion)

Divide quaternion with number and invert.

\[ \frac a q = [\frac a {\boldsymbol q_V}, \frac a {q_S}] \]

template<class T> template<class T>
Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Quaternion<T>& value)

Debug output operator.