sm::mat44

A 4x4 transformation matrix class

#include <sm/mat44>

Header file: <sm/mat44>. Test and example code: tests/testTransformMatrix tests/testTranslatePretranslate tests/testTransMat_constexpr

Table of Contents

Summary

A 4x4 matrix class with a templated element type. constexpr capable.

Defined as:

namespace sm {
    template <typename F>
    struct mat44 {
        // ...
        std::array<F, 16> mat;

where F hints that the template arg is usually a floating point type (although it may be any signed arithmetic type). The data is stored in an std::array in column-major format; the left-most column of the matrix is stored in the first 4 elements of the array.

Note that this class template (along with mat22 and mat33) is not designed with template parameters for rows and columns; it retains the simplicity of providing just a square transform matrix.

Create a mat44

sm::mat44<double> m;
std::cout << "Initialized as the identity matrix:\n" << m << std::endl;

Set data in the mat44

Raw access to the elements

You can set the contained mat manually:

sm::mat44<int> m;
m.mat = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
std::cout << "Matrix contains:\n" << m << std::endl;

which outputs:

Matrix contains:
[ 0 , 4 , 8 , 12 ;
  1 , 5 , 9 , 13 ;
  2 , 6 , 10 , 14 ;
  3 , 7 , 11 , 15 ]

You can change individual elements of the matrix with the array access operator:

m[3] = 100;
std::cout << "Matrix updated:\n" << m << std::endl;

The updated matrix is:

Matrix updated:
[ 0 , 4 , 8 , 12 ;
  1 , 5 , 9 , 13 ;
  2 , 6 , 10 , 14 ;
  100 , 7 , 11 , 15 ]

You can reset a mat44 to the identity matrix:

m.setToIdentity();

Setting elements by transforms

Often, you want to set the values in the matrix by defining translations and rotations.

sm::mat44<float> m;
sm::vec<float, 3> t = { 1, 2, 3 };
m.translate (t); // t could also be std::array<float, 3>
// or equivalently:
sm::mat44<float> m2;
m2.translate (1.0f, 2.0f, 3.0f);

translate applies the translation after any rotation that is specified in the linear part of the matrix (the top left 3x3 sub-matrix).

The rotate methods apply a rotation into the linear part of the matrix:

sm::mat44<float> m;
// Rotate by axis and angle
sm::vec<float> axis = { 0, 1, 0 }; // You can also use std::array<float, 3>
m.rotate (axis, sm::mathconst<float>::pi_over_2);
// Rotate using a sm::quaternion
sm::mat44<float> m2;
sm::quaternion<double> qd (axis.as_double(), sm::mathconst<double>::pi_over_4);
m2.rotate (qd); // Note that the quaternion does not have to have the same
                // element type as the mat44

The rotate methods pre-multipy the ‘this’ matrix by a pure rotation matrix.

After applying a rotation with rotate, you can apply a translation that occurs before the rotation with pretranslate:

sm::mat44<float> m;
sm::vec<float> axis = { 0, 1, 0 };
m.rotate (axis, sm::mathconst<float>::pi_over_2);
sm::vec<float> t = { 2, 0, 0 }; // a translation
m.pretranslate (t); // m now encodes a translation followed by a rotation about (0,1,0)

Finally, there are the prerotate methods, which apply a rotation before any existing rotations and translations that are already encoded in the matrix. These methods post-multiply the ‘this’ matrix with a pure rotation matrix.

sm::mat44<float> m;
sm::vec<float> t = { 2, 0, 0 };
m.translate (t);
sm::vec<float> axis = { 0, 1, 0 };
m.prerotate (axis, sm::mathconst<float>::pi_over_2);
// m now encodes a rotation about (0,1,0) followed by a translation of (2,0,0)

The rotate, prerotate, translate and pretranslate methods have equivalent names to similar functions in Eigen.

In addition to rotate and translate functions, mat44 provides scale functions:

sm::mat44<float> m;
sm::vec<float> t = { 2, 0, 0 };
m.translate (t);
sm::vec<float> scaling = { 0.5, 1, 1.5 };
m.scale (scaling);

Here, the 3D scaling can be provided as a sm::vec<float, 3>, std::array<float, 3> or as three floats.

It’s also possible to specify an equal scaling in all elements:

sm::mat44<float> m;
sm::vec<float> t = { 2, 0, 0 };
m.translate (t);
float scaling = 1.2f;
m.scale (scaling);

Special setters

frombasis perspective and orthographic

Matrix properties

sm::mat44<float> m;
float d = m.determinant();
float t = m.trace();

Matrix operations

sm::mat44<float> m;
sm::mat44<float> the_inverse = m.inverse(); // Returns the inverse.
m.transpose(); // Transposes the matrix in place