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

Complex number.

Template parameters
T Data type

Represents 2D rotation. Usually denoted as the following in equations, with $ a_0 $ being the real() part and $ a_i $ the imaginary() part:

\[ c = a_0 + i a_i \]

See 2D and 3D transformations for brief introduction.

Public types

using Type = T
Underlying data type.

Public static functions

static auto rotation(Rad<T> angle) -> Complex<T>
Rotation complex number.
static auto fromMatrix(const Matrix2x2<T>& matrix) -> Complex<T>
Create complex number from rotation matrix.

Constructors, destructors, conversion operators

Complex() constexpr noexcept
Default constructor.
Complex(IdentityInitT) explicit constexpr noexcept
Identity constructor.
Complex(ZeroInitT) explicit constexpr noexcept
Construct zero-initialized complex number.
Complex(Magnum::NoInitT) explicit noexcept
Construct without initializing the contents.
Complex(T real, T imaginary) constexpr noexcept
Construct a complex number from real and imaginary part.
Complex(const Vector2<T>& vector) explicit constexpr noexcept
Construct a complex number from a vector.
template<class U>
Complex(const Complex<U>& other) explicit constexpr noexcept
Construct a complex number from another of different type.
template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::from(std::declval<U>()))>
Complex(const U& other) explicit constexpr
Construct a complex number from external representation.
template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::to(std::declval<Complex<T>>()))>
operator U() const explicit constexpr
Convert a complex number to external representation.
operator Vector2<T>() const explicit constexpr
Convert a complex number to vector.

Public functions

auto data() -> T*
Raw data.
auto data() const -> const T*
auto operator==(const Complex<T>& other) const -> bool
Equality comparison.
auto operator!=(const Complex<T>& other) const -> bool
Non-equality comparison.
auto isNormalized() const -> bool
Whether the complex number is normalized.
auto real() -> T&
Real part ( $ a_0 $ )
auto real() const -> T constexpr
auto imaginary() -> T&
Imaginary part ( $ a_i $ )
auto imaginary() const -> T constexpr
auto angle() const -> Rad<T>
Rotation angle of a complex number.
auto toMatrix() const -> Matrix2x2<T>
Convert a complex number to a rotation matrix.
auto operator+() const -> Complex<T> new in Git master
Promotion.
auto operator+=(const Complex<T>& other) -> Complex<T>&
Add a complex number and assign.
auto operator+(const Complex<T>& other) const -> Complex<T>
Add a complex number.
auto operator-() const -> Complex<T>
Negated complex number.
auto operator-=(const Complex<T>& other) -> Complex<T>&
Subtract a complex number and assign.
auto operator-(const Complex<T>& other) const -> Complex<T>
Subtract a complex number.
auto operator*=(T scalar) -> Complex<T>&
Multiply with a scalar and assign.
auto operator*=(const Vector2<T>& vector) -> Complex<T>&
Multiply with a vector and assign.
auto operator*(T scalar) const -> Complex<T>
Multiply with a scalar.
auto operator*(const Vector2<T>& vector) const -> Complex<T>
Multiply with a vector.
auto operator/=(T scalar) -> Complex<T>&
Divide with a scalar and assign.
auto operator/=(const Vector2<T>& vector) -> Complex<T>&
Divide with a vector and assign.
auto operator/(T scalar) const -> Complex<T>
Divide with a scalar.
auto operator/(const Vector2<T>& vector) const -> Complex<T>
Divide with a vector.
auto operator*(const Complex<T>& other) const -> Complex<T>
Multiply with a complex number.
auto dot() const -> T
Dot product of the complex number.
auto length() const -> T
Complex number length.
auto normalized() const -> Complex<T>
Normalized complex number (of unit length)
auto conjugated() const -> Complex<T>
Conjugated complex number.
auto inverted() const -> Complex<T>
Inverted complex number.
auto invertedNormalized() const -> Complex<T>
Inverted normalized complex number.
auto transformVector(const Vector2<T>& vector) const -> Vector2<T>
Rotate a vector with the complex number.

Function documentation

template<class T>
static Complex<T> Magnum::Math::Complex<T>::rotation(Rad<T> angle)

Rotation complex number.

Parameters
angle Rotation angle (counterclockwise)
\[ c = \cos(\theta) + i \sin(\theta) \]

template<class T>
static Complex<T> Magnum::Math::Complex<T>::fromMatrix(const Matrix2x2<T>& matrix)

Create complex number from rotation matrix.

Expects that the matrix is a pure rotation, i.e. orthogonal and without any reflection. See Matrix3::rotation() const for an example of how to extract rotation, reflection and scaling components from a 2D transformation matrix.

template<class T>
Magnum::Math::Complex<T>::Complex() constexpr noexcept

Default constructor.

Equivalent to Complex(IdentityInitT).

template<class T>
Magnum::Math::Complex<T>::Complex(IdentityInitT) explicit constexpr noexcept

Identity constructor.

Constructs unit complex number.

\[ c = 1 + i0 \]

template<class T>
Magnum::Math::Complex<T>::Complex(T real, T imaginary) constexpr noexcept

Construct a complex number from real and imaginary part.

\[ c = a + ib \]

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

Construct a complex number from a vector.

To be used in transformations later.

\[ c = v_x + iv_y \]

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

Construct a complex number from another of different type.

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

template<class T>
Magnum::Math::Complex<T>::operator Vector2<T>() const explicit constexpr

Convert a complex number to vector.

\[ \boldsymbol v = \begin{pmatrix} a \\ b \end{pmatrix} \]

template<class T>
T* Magnum::Math::Complex<T>::data()

Raw data.

Contrary to what Doxygen shows, returns reference to an one-dimensional fixed-size array of two elements, i.e. T(&)[2].

template<class T>
const T* Magnum::Math::Complex<T>::data() const

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>
bool Magnum::Math::Complex<T>::isNormalized() const

Whether the complex number is normalized.

Complex number is normalized if it has unit length:

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

template<class T>
T& Magnum::Math::Complex<T>::real()

Real part ( $ a_0 $ )

template<class T>
T Magnum::Math::Complex<T>::real() 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::Complex<T>::imaginary()

Imaginary part ( $ a_i $ )

template<class T>
T Magnum::Math::Complex<T>::imaginary() 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::Complex<T>::angle() const

Rotation angle of a complex number.

\[ \theta = \operatorname{atan2}(b, a) \]

template<class T>
Matrix2x2<T> Magnum::Math::Complex<T>::toMatrix() const

Convert a complex number to a rotation matrix.

\[ M = \begin{pmatrix} a & -b \\ b & a \end{pmatrix} \]

template<class T>
Complex<T> Magnum::Math::Complex<T>::operator+() const new in Git master

Promotion.

Returns the value as-is.

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

Add a complex number and assign.

The computation is done in-place.

\[ c_0 + c_1 = (a_0 + a_1) + i(b_0 + b_1) \]

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

Add a complex number.

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

Negated complex number.

\[ -c = -a -ib \]

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

Subtract a complex number and assign.

The computation is done in-place.

\[ c_0 - c_1 = (a_0 - a_1) + i(b_0 - b_1) \]

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

Subtract a complex number.

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

Multiply with a scalar and assign.

The computation is done in-place.

\[ c t = a t + i b t \]

template<class T>
Complex<T>& Magnum::Math::Complex<T>::operator*=(const Vector2<T>& vector)

Multiply with a vector and assign.

The computation is done in-place.

\[ c \boldsymbol{v} = a v_x + i b v_y \]

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

Multiply with a scalar.

template<class T>
Complex<T> Magnum::Math::Complex<T>::operator*(const Vector2<T>& vector) const

Multiply with a vector.

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

Divide with a scalar and assign.

The computation is done in-place.

\[ \frac{c}{t} = \frac{a}{t} + i \frac{b}{t} \]

template<class T>
Complex<T>& Magnum::Math::Complex<T>::operator/=(const Vector2<T>& vector)

Divide with a vector and assign.

The computation is done in-place.

\[ c \boldsymbol{v} = \frac{a}{v_x} + i \frac{b}{v_y} \]

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

Divide with a scalar.

template<class T>
Complex<T> Magnum::Math::Complex<T>::operator/(const Vector2<T>& vector) const

Divide with a vector.

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

Multiply with a complex number.

\[ c_0 c_1 = (a_0 + ib_0)(a_1 + ib_1) = (a_0 a_1 - b_0 b_1) + i(a_1 b_0 + a_0 b_1) \]

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

Dot product of the complex number.

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

\[ c \cdot c = a^2 + b^2 \]

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

Complex number length.

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

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

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

Normalized complex number (of unit length)

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

Conjugated complex number.

\[ c^* = a - ib \]

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

Inverted complex number.

See invertedNormalized() which is faster for normalized complex numbers.

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

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

Inverted normalized complex number.

Equivalent to conjugated(). Expects that the complex number is normalized.

\[ c^{-1} = \frac{c^*}{c \cdot c} = c^* \]

template<class T>
Vector2<T> Magnum::Math::Complex<T>::transformVector(const Vector2<T>& vector) const

Rotate a vector with the complex number.

\[ v' = c v = c (v_x + iv_y) \]

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

Dot product of two complex numbers.

\[ c_0 \cdot c_1 = a_0 a_1 + b_0 b_1 \]

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

Angle between normalized complex numbers.

Expects that both complex numbers are normalized.

\[ \theta = \arccos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = \arccos (a_0 a_1 + b_0 b_1) \]

To avoid numerical issues when two complex numbers are very close to each other, the dot product is clamped to the $ [-1, +1] $ range before being passed to $ \arccos $ .

template<class T> template<class T>
Complex<T> operator*(T scalar, const Complex<T>& complex)

Multiply a scalar with a complex number.

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

template<class T> template<class T>
Complex<T> operator*(const Vector2<T>& vector, const Complex<T>& complex)

Multiply a vector with a complex number.

Same as Complex::operator*(const Vector2<T>&) const.

template<class T> template<class T>
Complex<T> operator/(T scalar, const Complex<T>& complex)

Divide a complex number with a scalar and invert.

\[ \frac{t}{c} = \frac{t}{a} + i \frac{t}{b} \]

template<class T> template<class T>
Complex<T> operator/(const Vector2<T>& vector, const Complex<T>& complex)

Divide a complex number with a vector and invert.

\[ \frac{\boldsymbol{v}}{c} = \frac{v_x}{a} + i \frac{v_y}{b} \]

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

Linear interpolation of two complex numbers.

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

Expects that both complex numbers are normalized.

\[ c_{LERP} = \frac{(1 - t) c_A + t c_B}{|(1 - t) c_A + t c_B|} \]

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

Spherical linear interpolation of two complex numbers.

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

Expects that both complex numbers are normalized. If the complex numbers are the same, returns the first argument.

\[ \begin{array}{rcl} \theta & = & \arccos \left( \frac{c_A \cdot c_B}{|c_A| |c_B|} \right) = \arccos(c_A \cdot c_B) \\[6pt] c_{SLERP} & = & \cfrac{\sin((1 - t) \theta) c_A + \sin(t \theta) c_B}{\sin(\theta)} \end{array} \]

template<class T> template<class T>
Debug& operator<<(Debug& debug, const Complex<T>& value)

Debug output operator.