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

3D transformation matrix

Template parameters
T Underlying data type

Expands upon a generic Matrix4x4 with functionality for 3D transformations. A 3D transformation matrix consists of a upper-left 3x3 part describing a combined scaling, rotation and shear, and the three top-right components specifying a translation:

\[ \boldsymbol{T} = \begin{pmatrix} \color{m-danger} a_x & \color{m-success} b_x & \color{m-info} c_x & \color{m-warning} t_x \\ \color{m-danger} a_y & \color{m-success} b_y & \color{m-info} c_y & \color{m-warning} t_y \\ \color{m-danger} a_z & \color{m-success} b_z & \color{m-info} c_z & \color{m-warning} t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

The $ \color{m-danger} \boldsymbol{a} $ , $ \color{m-success} \boldsymbol{b} $ and $ \color{m-info} \boldsymbol{c} $ vectors can be also thought of as the three basis vectors describing the coordinate system the matrix converts to. In case of an affine transformation, the bottom row is always $ \begin{pmatrix} \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} $ . A (pure) 3D perspective projection matrix, however, can look for example like this:

\[ \boldsymbol{P} = \begin{pmatrix} \color{m-danger} s_x & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 \\ \color{m-dim} 0 & \color{m-success} s_y & \color{m-dim} 0 & \color{m-dim} 0 \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-info} s_z & \color{m-warning} t_z \\ \color{m-primary} 0 & \color{m-primary} 0 & \color{m-primary} -1 & \color{m-primary} 0 \end{pmatrix} \]

The bottom row having the non-zero value in the third column instead of the fourth is, simply put, what makes perspective shortening happening along the Z axis. While perspective shortening along X or Y is technically also possible, it doesn't really have a common use, neither it is a thing in case of a 2D transformation with Matrix3.

Usage

See Math type system, Operations with matrices and vectors and 2D and 3D transformations first for an introduction into using transformation matrices.

While it's possible to create the matrix directly from the components, the recommended usage is by creating elementary transformation matrices with translation(), rotation() and variants, scaling(), reflection(), shearingXY() and variants, lookAt() and orthographicProjection() / perspectiveProjection() and multiplying them together to form the final transformation — the rightmost transformation is applied first, leftmost last:

using namespace Math::Literals;

Matrix4 transformation =
    Matrix4::rotationZ(15.0_degf)*
    Matrix4::translation({10.0f, 3.0f, -1.5f})*
    Matrix4::scaling(Vector3::yScale(2.0f));

Conversely, the transformation parts can be extracted back using the member rotation(), scaling() and their variants, and translation(). The basis vectors can be accessed using right(), up() and backward(). Matrices that combine non-uniform scaling and/or shear with rotation can't be trivially decomposed back, for these you might want to consider using Algorithms::qr() or Algorithms::svd().

When a lot of transformations gets composed together over time (for example with a camera movement), a floating-point drift accumulates, causing the rotation part to no longer be orthogonal. This can be accounted for using Algorithms::gramSchmidtOrthonormalizeInPlace() and variants.

Base classes

template<std::size_t size, class T>
class Matrix<T>
Square matrix.

Public static functions

static auto translation(const Vector3<T>& vector) -> Matrix4<T> constexpr
3D translation matrix
static auto scaling(const Vector3<T>& vector) -> Matrix4<T> constexpr
3D scaling matrix
static auto rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) -> Matrix4<T>
3D rotation matrix around arbitrary axis
static auto rotationX(Rad<T> angle) -> Matrix4<T>
3D rotation matrix around the X axis
static auto rotationY(Rad<T> angle) -> Matrix4<T>
3D rotation matrix around the Y axis
static auto rotationZ(Rad<T> angle) -> Matrix4<T>
3D rotation matrix around the Z axis
static auto reflection(const Vector3<T>& normal) -> Matrix4<T>
3D reflection matrix
static auto shearingXY(T amountX, T amountY) -> Matrix4<T> constexpr
3D shearing matrix along the XY plane
static auto shearingXZ(T amountX, T amountZ) -> Matrix4<T> constexpr
3D shearing matrix along the XZ plane
static auto shearingYZ(T amountY, T amountZ) -> Matrix4<T> constexpr
3D shearing matrix along the YZ plane
static auto orthographicProjection(const Vector2<T>& size, T near, T far) -> Matrix4<T>
3D orthographic projection matrix
static auto orthographicProjection(const Vector2<T>& bottomLeft, const Vector2<T>& topRight, T near, T far) -> Matrix4<T> new in Git master
3D off-center orthographic projection matrix
static auto perspectiveProjection(const Vector2<T>& size, T near, T far) -> Matrix4<T>
3D perspective projection matrix
static auto perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) -> Matrix4<T>
3D perspective projection matrix
static auto perspectiveProjection(const Vector2<T>& bottomLeft, const Vector2<T>& topRight, T near, T far) -> Matrix4<T> new in 2019.10
3D off-center perspective projection matrix
static auto lookAt(const Vector3<T>& eye, const Vector3<T>& target, const Vector3<T>& up) -> Matrix4<T>
Matrix oriented towards a specific point.
static auto from(const Matrix3x3<T>& rotationScaling, const Vector3<T>& translation) -> Matrix4<T> constexpr
Create a matrix from a rotation/scaling part and a translation part.

Constructors, destructors, conversion operators

Matrix4() constexpr noexcept
Default constructor.
Matrix4(IdentityInitT, T value = T{1}) explicit constexpr noexcept
Construct an identity matrix.
Matrix4(ZeroInitT) explicit constexpr noexcept
Construct a zero-filled matrix.
Matrix4(Magnum::NoInitT) explicit constexpr noexcept
Construct without initializing the contents.
Matrix4(const Vector4<T>& first, const Vector4<T>& second, const Vector4<T>& third, const Vector4<T>& fourth) constexpr noexcept
Construct from column vectors.
Matrix4(T value) explicit constexpr noexcept
Construct with one value for all elements.
template<class U>
Matrix4(const RectangularMatrix<4, 4, U>& other) explicit constexpr noexcept
Construct from a matrix of a different type.
template<class U, class = decltype(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(std::declval<U>()))>
Matrix4(const U& other) explicit constexpr
Construct a matrix from external representation.
template<std::size_t otherCols, std::size_t otherRows>
Matrix4(IdentityInitT, const RectangularMatrix<otherCols, otherRows, T>& other, T value = T(1)) explicit constexpr noexcept new in Git master
Construct by slicing or expanding a matrix of different size, leaving the rest at identity.
template<std::size_t otherCols, std::size_t otherRows>
Matrix4(ZeroInitT, const RectangularMatrix<otherCols, otherRows, T>& other) explicit constexpr noexcept new in Git master
Construct by slicing or expanding a matrix of different size, leaving the rest at zero.
template<std::size_t otherCols, std::size_t otherRows>
Matrix4(const RectangularMatrix<otherCols, otherRows, T>& other, T value = T(1)) explicit constexpr noexcept new in Git master
Construct by slicing or expanding a matrix of different size.
Matrix4(const RectangularMatrix<4, 4, T>& other) constexpr noexcept
Copy constructor.

Public functions

auto isRigidTransformation() const -> bool
Check whether the matrix represents a rigid transformation.
auto rotationScaling() const -> Matrix3x3<T> constexpr
3D rotation and scaling part of the matrix
auto rotationShear() const -> Matrix3x3<T>
3D rotation, reflection and shear part of the matrix
auto rotation() const -> Matrix3x3<T>
3D rotation and reflection part of the matrix
auto rotationNormalized() const -> Matrix3x3<T>
3D rotation and reflection part of the matrix assuming there is no scaling
auto scalingSquared() const -> Vector3<T>
Non-uniform scaling part of the matrix, squared.
auto scaling() const -> Vector3<T>
Non-uniform scaling part of the matrix.
auto uniformScalingSquared() const -> T
Uniform scaling part of the matrix, squared.
auto uniformScaling() const -> T
Uniform scaling part of the matrix.
auto normalMatrix() const -> Matrix3x3<T> new in 2019.10
Normal matrix.
auto right() -> Vector3<T>&
Right-pointing 3D vector.
auto right() const -> Vector3<T> constexpr
auto up() -> Vector3<T>&
Up-pointing 3D vector.
auto up() const -> Vector3<T> constexpr
auto backward() -> Vector3<T>&
Backward-pointing 3D vector.
auto backward() const -> Vector3<T> constexpr
auto translation() -> Vector3<T>&
3D translation part of the matrix
auto translation() const -> Vector3<T> constexpr
auto orthographicProjectionNear() const -> Float new in Git master
Distance to near plane of an orthographic projection matrix.
auto orthographicProjectionFar() const -> Float new in Git master
Distance to far plane of an orthographic projection matrix.
auto perspectiveProjectionNear() const -> Float new in Git master
Distance to near plane of a perspective projection matrix.
auto perspectiveProjectionFar() const -> Float new in Git master
Distance to far plane of a perspective projection matrix.
auto invertedRigid() const -> Matrix4<T>
Inverted rigid transformation matrix.
auto transformVector(const Vector3<T>& vector) const -> Vector3<T>
Transform a 3D vector with the matrix.
auto transformPoint(const Vector3<T>& vector) const -> Vector3<T>
Transform a 3D point with the matrix.

Function documentation

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::translation(const Vector3<T>& vector) constexpr

3D translation matrix

Parameters
vector Translation vector
\[ \boldsymbol{A} = \begin{pmatrix} 1 & 0 & 0 & v_x \\ 0 & 1 & 0 & v_y \\ 0 & 0 & 1 & v_z \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::scaling(const Vector3<T>& vector) constexpr

3D scaling matrix

Parameters
vector Scaling vector
\[ \boldsymbol{A} = \begin{pmatrix} v_x & 0 & 0 & 0 \\ 0 & v_y & 0 & 0 \\ 0 & 0 & v_z & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

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

3D rotation matrix around arbitrary axis

Parameters
angle Rotation angle (counterclockwise)
normalizedAxis Normalized rotation axis

Expects that the rotation axis is normalized. If possible, use faster alternatives like rotationX(), rotationY() and rotationZ().

\[ \boldsymbol{A} = \begin{pmatrix} v_{x}v_{x}(1 - \cos\theta) + \cos\theta & v_{y}v_{x}(1 - \cos\theta) - v_{z}\sin \theta & v_{z}v_{x}(1 - \cos\theta) + v_{y}\sin\theta & 0 \\ v_{x}v_{y}(1 - \cos\theta) + v_{z}\sin\theta & v_{y}v_{y}(1 - \cos\theta) + \cos\theta & v_{z}v_{y}(1 - \cos\theta) - v_{x}\sin\theta & 0 \\ v_{x}v_{z}(1 - \cos\theta) - v_{y}\sin\theta & v_{y}v_{z}(1 - \cos\theta)+v_{x}\sin\theta & v_{z}v_{z}(1 - \cos\theta) + \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::rotationX(Rad<T> angle)

3D rotation matrix around the X axis

Parameters
angle Rotation angle (counterclockwise)

Faster than calling Matrix4::rotation(angle, Vector3::xAxis()).

\[ \boldsymbol{A} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::rotationY(Rad<T> angle)

3D rotation matrix around the Y axis

Parameters
angle Rotation angle (counterclockwise)

Faster than calling Matrix4::rotation(angle, Vector3::yAxis()).

\[ \boldsymbol{A} = \begin{pmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::rotationZ(Rad<T> angle)

3D rotation matrix around the Z axis

Parameters
angle Rotation angle (counterclockwise)

Faster than calling Matrix4::rotation(angle, Vector3::zAxis()).

\[ \boldsymbol{A} = \begin{pmatrix} \cos\theta & -\sin\theta & 0 & 0 \\ \sin\theta & \cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::reflection(const Vector3<T>& normal)

3D reflection matrix

Parameters
normal Normal of the plane through which to reflect

Expects that the normal is normalized. Reflection along axes can be done in a slightly simpler way also using scaling(), e.g. Matrix4::reflection(Vector3::yAxis()) is equivalent to Matrix4::scaling(Vector3::yScale(-1.0f)).

\[ \boldsymbol{A} = \boldsymbol{I} - 2 \boldsymbol{NN}^T ~~~~~ \boldsymbol{N} = \begin{pmatrix} n_x \\ n_y \\ n_z \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::shearingXY(T amountX, T amountY) constexpr

3D shearing matrix along the XY plane

Parameters
amountX Amount of shearing along the X axis
amountY Amount of shearing along the Y axis

Z axis remains unchanged.

\[ \boldsymbol{A} = \begin{pmatrix} 1 & 0 & v_x & 0 \\ 0 & 1 & v_y & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::shearingXZ(T amountX, T amountZ) constexpr

3D shearing matrix along the XZ plane

Parameters
amountX Amount of shearing along the X axis
amountZ Amount of shearing along the Z axis

Y axis remains unchanged.

\[ \boldsymbol{A} = \begin{pmatrix} 1 & v_x & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & v_z & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::shearingYZ(T amountY, T amountZ) constexpr

3D shearing matrix along the YZ plane

Parameters
amountY Amount of shearing along the Y axis
amountZ Amount of shearing along the Z axis

X axis remains unchanged.

\[ \boldsymbol{A} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ v_y & 1 & 0 & 0 \\ v_z & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::orthographicProjection(const Vector2<T>& size, T near, T far)

3D orthographic projection matrix

Parameters
size Size of the view
near Distance to near clipping plane, positive is ahead
far Distance to far clipping plane, positive is ahead
\[ \boldsymbol{A} = \begin{pmatrix} \frac{2}{s_x} & 0 & 0 & 0 \\ 0 & \frac{2}{s_y} & 0 & 0 \\ 0 & 0 & \frac{2}{n - f} & \frac{n + f}{n - f} \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

If you need an off-center projection (as with the classic glOrtho() function), use orthographicProjection(const Vector2<T>&, const Vector2<T>&, T, T).

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::orthographicProjection(const Vector2<T>& bottomLeft, const Vector2<T>& topRight, T near, T far) new in Git master

3D off-center orthographic projection matrix

Parameters
bottomLeft Bottom left corner of the clipping plane
topRight Top right corner of the clipping plane
near Distance to near clipping plane, positive is ahead
far Distance to far clipping plane, positive is ahead
\[ \boldsymbol{A} = \begin{pmatrix} \frac{2}{r - l} & 0 & 0 & - \frac{r + l}{r - l} \\ 0 & \frac{2}{t - b} & 0 & - \frac{t + b}{t - b} \\ 0 & 0 & \frac{2}{n - f} & \frac{n + f}{n - f} \\ 0 & 0 & 0 & 1 \end{pmatrix} \]

Equivalent to the classic glOrtho() function. If bottomLeft and topRight are a negation of each other, this function is equivalent to orthographicProjection(const Vector2<T>&, T, T).

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::perspectiveProjection(const Vector2<T>& size, T near, T far)

3D perspective projection matrix

Parameters
size Size of near clipping plane
near Distance to near clipping plane, positive is ahead
far Distance to far clipping plane, positive is ahead

If far is finite, the result is:

\[ \boldsymbol{A} = \begin{pmatrix} \frac{2n}{s_x} & 0 & 0 & 0 \\ 0 & \frac{2n}{s_y} & 0 & 0 \\ 0 & 0 & \frac{n + f}{n - f} & \frac{2nf}{n - f} \\ 0 & 0 & -1 & 0 \end{pmatrix} \]

For infinite far, the result is:

\[ \boldsymbol{A} = \begin{pmatrix} \frac{2n}{s_x} & 0 & 0 & 0 \\ 0 & \frac{2n}{s_y} & 0 & 0 \\ 0 & 0 & -1 & -2n \\ 0 & 0 & -1 & 0 \end{pmatrix} \]

If you need an off-center projection, use perspectiveProjection(const Vector2<T>&, const Vector2<T>&, T, T) instead.

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far)

3D perspective projection matrix

Parameters
fov Horizontal field of view angle $ \theta $
aspectRatio Horizontal:vertical aspect ratio $ a $
near Near clipping plane $ n $
far Far clipping plane $ f $

If far is finite, the result is:

\[ \boldsymbol{A} = \begin{pmatrix} \frac{1}{\tan \left(\frac{\theta}{2} \right)} & 0 & 0 & 0 \\ 0 & \frac{a}{\tan \left(\frac{\theta}{2} \right)} & 0 & 0 \\ 0 & 0 & \frac{n + f}{n - f} & \frac{2nf}{n - f} \\ 0 & 0 & -1 & 0 \end{pmatrix} \]

For infinite far, the result is:

\[ \boldsymbol{A} = \begin{pmatrix} \frac{1}{\tan \left( \frac{\theta}{2} \right) } & 0 & 0 & 0 \\ 0 & \frac{a}{\tan \left( \frac{\theta}{2} \right) } & 0 & 0 \\ 0 & 0 & -1 & -2n \\ 0 & 0 & -1 & 0 \end{pmatrix} \]

This function is equivalent to calling perspectiveProjection(const Vector2<T>&, T, T) with the size parameter calculated as

\[ \boldsymbol{s} = 2 n \tan \left(\tfrac{\theta}{2} \right) \begin{pmatrix} 1 \\ \frac{1}{a} \end{pmatrix} \]

This function is similar to the classic gluPerspective(), with the difference that fov is horizontal instead of vertical. If you need an off-center projection (as with the classic glFrustum() function), use perspectiveProjection(const Vector2<T>&, const Vector2<T>&, T, T).

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::perspectiveProjection(const Vector2<T>& bottomLeft, const Vector2<T>& topRight, T near, T far) new in 2019.10

3D off-center perspective projection matrix

Parameters
bottomLeft Bottom left corner of the near clipping plane
topRight Top right corner of the near clipping plane
near Distance to near clipping plane, positive is ahead
far Distance to far clipping plane, positive is ahead

If far is finite, the result is:

\[ \boldsymbol{A} = \begin{pmatrix} \frac{2n}{r - l} & 0 & \frac{r + l}{r - l} & 0 \\ 0 & \frac{2n}{t - b} & \frac{t + b}{t - b} & 0 \\ 0 & 0 & \frac{n + f}{n - f} & \frac{2nf}{n - f} \\ 0 & 0 & -1 & 0 \end{pmatrix} \]

For infinite far, the result is:

\[ \boldsymbol{A} = \begin{pmatrix} \frac{2n}{r - l} & 0 & \frac{r + l}{r - l} & 0 \\ 0 & \frac{2n}{t - b} & \frac{t + b}{t - b} & 0 \\ 0 & 0 & -1 & -2n \\ 0 & 0 & -1 & 0 \end{pmatrix} \]

Equivalent to the classic glFrustum() function. If bottomLeft and topRight are a negation of each other, this function is equivalent to perspectiveProjection(const Vector2<T>&, T, T).

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::lookAt(const Vector3<T>& eye, const Vector3<T>& target, const Vector3<T>& up)

Matrix oriented towards a specific point.

Parameters
eye Location to place the matrix
target Location towards which the matrix is oriented
up Vector as a guide of which way is up (should not be the same direction as target - eye)

template<class T>
static Matrix4<T> Magnum::Math::Matrix4<T>::from(const Matrix3x3<T>& rotationScaling, const Vector3<T>& translation) constexpr

Create a matrix from a rotation/scaling part and a translation part.

Parameters
rotationScaling Rotation/scaling part (upper-left 3x3 matrix)
translation Translation part (first three elements of fourth column)

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

Default constructor.

Equivalent to Matrix4(IdentityInitT, T).

template<class T>
Magnum::Math::Matrix4<T>::Matrix4(IdentityInitT, T value = T{1}) explicit constexpr noexcept

Construct an identity matrix.

The value allows you to specify value on diagonal.

template<class T>
Magnum::Math::Matrix4<T>::Matrix4(ZeroInitT) explicit constexpr noexcept

Construct a zero-filled matrix.

template<class T> template<class U>
Magnum::Math::Matrix4<T>::Matrix4(const RectangularMatrix<4, 4, U>& other) explicit constexpr noexcept

Construct from a matrix of a different type.

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

Matrix2x2 floatingPoint{Vector2{1.3f, 2.7f}, Vector2{-15.0f, 7.0f}};
Math::Matrix2x2<Byte> integral{floatingPoint}; // {{1, 2}, {-15, 7}}

template<class T> template<std::size_t otherCols, std::size_t otherRows>
Magnum::Math::Matrix4<T>::Matrix4(IdentityInitT, const RectangularMatrix<otherCols, otherRows, T>& other, T value = T(1)) explicit constexpr noexcept new in Git master

Construct by slicing or expanding a matrix of different size, leaving the rest at identity.

If the other matrix has less columns or rows, the corresponding vectors and components are set to either zeros or value on the diagonal.

template<class T> template<std::size_t otherCols, std::size_t otherRows>
Magnum::Math::Matrix4<T>::Matrix4(ZeroInitT, const RectangularMatrix<otherCols, otherRows, T>& other) explicit constexpr noexcept new in Git master

Construct by slicing or expanding a matrix of different size, leaving the rest at zero.

If the other matrix has less columns or rows, the corresponding vectors and components are set to zeros.

template<class T> template<std::size_t otherCols, std::size_t otherRows>
Magnum::Math::Matrix4<T>::Matrix4(const RectangularMatrix<otherCols, otherRows, T>& other, T value = T(1)) explicit constexpr noexcept new in Git master

Construct by slicing or expanding a matrix of different size.

Equivalent to Matrix4(IdentityInitT, const RectangularMatrix<otherCols, otherRows, T>&, T). Note that this default is different from RectangularMatrix, where it's equivalent to the ZeroInit variant instead.

template<class T>
bool Magnum::Math::Matrix4<T>::isRigidTransformation() const

Check whether the matrix represents a rigid transformation.

A rigid transformation consists only of rotation, reflection and translation (i.e., no scaling, skew or projection).

template<class T>
Matrix3x3<T> Magnum::Math::Matrix4<T>::rotationScaling() const constexpr

3D rotation and scaling part of the matrix

Unchanged upper-left 3x3 part of the matrix.

\[ \begin{pmatrix} \color{m-danger} a_x & \color{m-success} b_x & \color{m-info} c_x & t_x \\ \color{m-danger} a_y & \color{m-success} b_y & \color{m-info} c_y & t_y \\ \color{m-danger} a_z & \color{m-success} b_z & \color{m-info} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

Note that an arbitrary combination of rotation and scaling can also represent shear and reflection. Especially when non-uniform scaling is involved, decomposition of the result into primary linear transformations may have multiple equivalent solutions. See rotation() const, Algorithms::svd() and Algorithms::qr() for further info. See also rotationShear() and scaling() const for extracting further properties.

template<class T>
Matrix3x3<T> Magnum::Math::Matrix4<T>::rotationShear() const

3D rotation, reflection and shear part of the matrix

Normalized upper-left 3x3 part of the matrix. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting rotation is extracted as:

\[ \boldsymbol{R} = \begin{pmatrix} \cfrac{\boldsymbol{a}}{|\boldsymbol{a}|} & \cfrac{\boldsymbol{b}}{|\boldsymbol{b}|} & \cfrac{\boldsymbol{c}}{|\boldsymbol{c}|} \end{pmatrix} \]

This function is a counterpart to rotation() const that does not require orthogonal input. See also rotationScaling() and scaling() const for extracting other properties. The Algorithms::svd() and Algorithms::qr() can be used to separate the rotation / shear components; see rotation() const for an example of decomposing a rotation + reflection matrix into a pure rotation and signed scaling.

template<class T>
Matrix3x3<T> Magnum::Math::Matrix4<T>::rotation() const

3D rotation and reflection part of the matrix

Normalized upper-left 3x3 part of the matrix. Expects that the normalized part is orthogonal. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting rotation is extracted as:

\[ \boldsymbol{R} = \begin{pmatrix} \cfrac{\boldsymbol{a}}{|\boldsymbol{a}|} & \cfrac{\boldsymbol{b}}{|\boldsymbol{b}|} & \cfrac{\boldsymbol{c}}{|\boldsymbol{c}|} \end{pmatrix} \]

This function is equivalent to rotationShear() but with the added orthogonality requirement. See also rotationScaling() and scaling() const for extracting other properties.

There's usually several solutions for decomposing the matrix into a rotation $ \boldsymbol{R} $ and a scaling $ \boldsymbol{S} $ that satisfy $ \boldsymbol{R} \boldsymbol{S} = \boldsymbol{M} $ . One possibility that gives you always a pure rotation matrix without reflections (which can then be fed to Quaternion::fromMatrix(), for example) is to flip an arbitrary column of the 3x3 part if its determinant() is negative, and apply the sign flip to the corresponding scaling component instead:

Matrix4 transformation = ;
Matrix3x3 rotation = transformation.rotation();
Vector3 scaling = transformation.scaling();
if(rotation.determinant() < 0.0f) {
    rotation[0] *= -1.0f;
    scaling[0] *= -1.0f;
}

template<class T>
Matrix3x3<T> Magnum::Math::Matrix4<T>::rotationNormalized() const

3D rotation and reflection part of the matrix assuming there is no scaling

Similar to rotation() const, but expects that the rotation part is orthogonal, saving the extra renormalization. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-danger} a_x & \color{m-success} b_x & \color{m-info} c_x & t_x \\ \color{m-danger} a_y & \color{m-success} b_y & \color{m-info} c_y & t_y \\ \color{m-danger} a_z & \color{m-success} b_z & \color{m-info} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting rotation is extracted as:

\[ \boldsymbol{R} = \begin{pmatrix} \cfrac{\boldsymbol{a}}{|\boldsymbol{a}|} & \cfrac{\boldsymbol{b}}{|\boldsymbol{b}|} & \cfrac{\boldsymbol{c}}{|\boldsymbol{c}|} \end{pmatrix} = \begin{pmatrix} \boldsymbol{a} & \boldsymbol{b} & \boldsymbol{c} \end{pmatrix} \]

In particular, for an orthogonal matrix, rotationScaling(), rotationShear(), rotation() const and rotationNormalized() all return the same value.

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::scalingSquared() const

Non-uniform scaling part of the matrix, squared.

Squared length of vectors in upper-left 3x3 part of the matrix. Faster alternative to scaling() const, because it doesn't calculate the square root. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting scaling vector, squared, is:

\[ \boldsymbol{s}^2 = \begin{pmatrix} \boldsymbol{a} \cdot \boldsymbol{a} \\ \boldsymbol{b} \cdot \boldsymbol{b} \\ \boldsymbol{c} \cdot \boldsymbol{c} \end{pmatrix} \]

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::scaling() const

Non-uniform scaling part of the matrix.

Length of vectors in upper-left 3x3 part of the matrix. Use the faster alternative scalingSquared() where possible. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting scaling vector is:

\[ \boldsymbol{s} = \begin{pmatrix} | \boldsymbol{a} | \\ | \boldsymbol{b} | \\ | \boldsymbol{c} | \end{pmatrix} \]

Note that the returned vector is sign-less and the signs are instead contained in rotation() const / rotationShear() const, meaning these contain rotation together with a potential reflection. See rotation() const for an example of decomposing a rotation + reflection matrix into a pure rotation and signed scaling.

template<class T>
T Magnum::Math::Matrix4<T>::uniformScalingSquared() const

Uniform scaling part of the matrix, squared.

Squared length of vectors in upper-left 3x3 part of the matrix. Expects that the scaling is the same in all axes. Faster alternative to uniformScaling(), because it doesn't calculate the square root. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting uniform scaling, squared, is:

\[ s^2 = \boldsymbol{a} \cdot \boldsymbol{a} = \boldsymbol{b} \cdot \boldsymbol{b} = \boldsymbol{c} \cdot \boldsymbol{c} \]

template<class T>
T Magnum::Math::Matrix4<T>::uniformScaling() const

Uniform scaling part of the matrix.

Length of vectors in upper-left 3x3 part of the matrix. Expects that the scaling is the same in all axes. Use the faster alternative uniformScalingSquared() where possible. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the resulting uniform scaling is:

\[ s = | \boldsymbol{a} | = | \boldsymbol{b} | = | \boldsymbol{c} | \]

template<class T>
Matrix3x3<T> Magnum::Math::Matrix4<T>::normalMatrix() const new in 2019.10

Normal matrix.

Shorthand for taking an inverse transpose of the upper-left 3x3 part of the matrix. Assuming the following matrix, with the upper-left 3x3 part represented by column vectors $ \boldsymbol{a} $ , $ \boldsymbol{b} $ and $ \boldsymbol{c} $ :

\[ \begin{pmatrix} \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ \color{m-warning} a_z & \color{m-warning} b_z & \color{m-warning} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

the normal matrix is extracted as:

\[ \boldsymbol{N} = \left(\begin{pmatrix} \boldsymbol{a} & \boldsymbol{b} & \boldsymbol{c} \end{pmatrix}^{-1}\right)^T \]

The inverse transpose guarantees that the normals stay perpendicular to the surface and point in the original direction even in presence of shear, non-uniform scaling and reflection.

template<class T>
Vector3<T>& Magnum::Math::Matrix4<T>::right()

Right-pointing 3D vector.

First three elements of first column.

\[ \begin{pmatrix} \color{m-danger} a_x & b_x & c_x & t_x \\ \color{m-danger} a_y & b_y & c_y & t_y \\ \color{m-danger} a_z & b_z & c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::right() 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>
Vector3<T>& Magnum::Math::Matrix4<T>::up()

Up-pointing 3D vector.

First three elements of second column.

\[ \begin{pmatrix} a_x & \color{m-success} b_x & c_x & t_x \\ a_y & \color{m-success} b_y & c_y & t_y \\ a_z & \color{m-success} b_z & c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::up() 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>
Vector3<T>& Magnum::Math::Matrix4<T>::backward()

Backward-pointing 3D vector.

First three elements of third column.

\[ \begin{pmatrix} a_x & b_x & \color{m-info} c_x & t_x \\ a_y & b_y & \color{m-info} c_y & t_y \\ a_z & b_z & \color{m-info} c_z & t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::backward() 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>
Vector3<T>& Magnum::Math::Matrix4<T>::translation()

3D translation part of the matrix

First three elements of fourth column.

\[ \begin{pmatrix} a_x & b_x & c_x & \color{m-warning} t_x \\ a_y & b_y & c_y & \color{m-warning} t_y \\ a_z & b_z & c_z & \color{m-warning} t_z \\ \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} \]

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::translation() 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>
Float Magnum::Math::Matrix4<T>::orthographicProjectionNear() const new in Git master

Distance to near plane of an orthographic projection matrix.

Assuming a matrix $ \boldsymbol{A} $ constructed with orthographicProjection(), returns the distance to its near plane:

\[ \frac{\boldsymbol{A}_{3,2} + 1}{\boldsymbol{A}_{2,2}} = \frac{\frac{n + f}{n - f} + 1}{\frac{2}{n - f}} = \frac{\frac{n + f + n - f}{n - f}}{\frac{2}{n - f}} = \frac{2n}{2} = n \]

template<class T>
Float Magnum::Math::Matrix4<T>::orthographicProjectionFar() const new in Git master

Distance to far plane of an orthographic projection matrix.

Assuming a matrix $ \boldsymbol{A} $ constructed with orthographicProjection(), returns the distance to its far plane:

\[ \frac{\boldsymbol{A}_{3,2} - 1}{\boldsymbol{A}_{2,2}} = \frac{\frac{n + f}{n - f} - 1}{\frac{2}{n - f}} = \frac{\frac{n + f - n + f}{n - f}}{\frac{2}{n - f}} = \frac{2f}{2} = f \]

template<class T>
Float Magnum::Math::Matrix4<T>::perspectiveProjectionNear() const new in Git master

Distance to near plane of a perspective projection matrix.

Assuming a matrix $ \boldsymbol{A} $ constructed with perspectiveProjection(), returns the distance to its near plane:

\[ \frac{\boldsymbol{A}_{3,2}}{\boldsymbol{A}_{2,2} - 1} = \frac{\frac{2nf}{n - f}}{\frac{n + f}{n - f} - 1} = \frac{\frac{2nf}{n - f}}{\frac{n + f - n + f}{n - f}} = \frac{2nf}{2f} = n \]

The same equation works for a perspective projection with an infinite far plane:

\[ \frac{\boldsymbol{A}_{3,2}}{\boldsymbol{A}_{2,2} - 1} = \frac{-2n}{-1 - 1} = \frac{-2n}{-2} = n \]

template<class T>
Float Magnum::Math::Matrix4<T>::perspectiveProjectionFar() const new in Git master

Distance to far plane of a perspective projection matrix.

Assuming a matrix $ \boldsymbol{A} $ constructed with perspectiveProjection() with a positive far value, returns the distance to its far plane:

\[ \left\lvert \frac{\boldsymbol{A}_{3,2}}{\boldsymbol{A}_{2,2} + 1}\right\rvert = \left\lvert \frac{\frac{2nf}{n - f}}{\frac{n + f}{n - f} + 1}\right\rvert = \left\lvert \frac{\frac{2nf}{n - f}}{\frac{n + f + n - f}{n - f}}\right\rvert = \left\lvert \frac{2nf}{2n} \right\rvert = f \]

The same equation works for a perspective projection with an infinite far plane:

\[ \left\lvert \frac{\boldsymbol{A}_{3,2}}{\boldsymbol{A}_{2,2} + 1} \right\rvert = \left\lvert \frac{-2n}{-1 + 1} \right\rvert = \left\lvert \frac{-2n}{0} \right\rvert = \infty \]

template<class T>
Matrix4<T> Magnum::Math::Matrix4<T>::invertedRigid() const

Inverted rigid transformation matrix.

Expects that the matrix represents a rigid transformation (i.e., no scaling, skew or projection). Significantly faster than the general algorithm in inverted().

\[ A^{-1} = \begin{pmatrix} (A^{3,3})^T & (A^{3,3})^T \begin{pmatrix} a_{3,0} \\ a_{3,1} \\ a_{3,2} \\ \end{pmatrix} \\ \begin{array}{ccc} 0 & 0 & 0 \end{array} & 1 \end{pmatrix} \]

$ A^{i, j} $ is matrix without i-th row and j-th column, see ij()

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

Transform a 3D vector with the matrix.

Unlike in transformPoint(), translation is not involved in the transformation.

\[ \boldsymbol v' = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 0 \end{pmatrix} \]

template<class T>
Vector3<T> Magnum::Math::Matrix4<T>::transformPoint(const Vector3<T>& vector) const

Transform a 3D point with the matrix.

Unlike in transformVector(), translation is also involved in the transformation.

\[ \boldsymbol v' = \boldsymbol v''_{xyz} / v''_w ~~~~~~~~~~ \boldsymbol v'' = \begin{pmatrix} v''_x \\ v''_y \\ v''_z \\ v''_w \end{pmatrix} = \boldsymbol M \begin{pmatrix} v_x \\ v_y \\ v_z \\ 1 \end{pmatrix} \\ \]