Skip to content

Commit

Permalink
Math: class-level documentation for Matrix3 and Matrix4.
Browse files Browse the repository at this point in the history
Another one that was long on my TODO list.
  • Loading branch information
mosra committed Jul 18, 2021
1 parent 90e8798 commit 3097c4c
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 4 deletions.
24 changes: 24 additions & 0 deletions doc/snippets/MagnumMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,30 @@ Math::Matrix2x2<Byte> integral{floatingPoint}; // {{1, 2}, {-15, 7}}
/* [Matrix-conversion] */
}

{
/* [Matrix3-usage] */
using namespace Math::Literals;

Matrix3 transformation =
Matrix3::rotation(15.0_degf)*
Matrix3::translation({100.0f, -30.0f})*
Matrix3::scaling(Vector2::yScale(2.0f));
/* [Matrix3-usage] */
static_cast<void>(transformation);
}

{
/* [Matrix4-usage] */
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));
/* [Matrix4-usage] */
static_cast<void>(transformation);
}

{
/* [Quaternion-fromEuler] */
Rad x, y, z;
Expand Down
48 changes: 46 additions & 2 deletions src/Magnum/Math/Matrix3.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,54 @@ namespace Magnum { namespace Math {
@brief 2D transformation matrix
@tparam T Underlying data type
See @ref matrix-vector and @ref transformations for brief introduction.
Expands upon a generic @ref Matrix3x3 with functionality for 2D
transformations. A 2D transformation matrix consists of a upper-left 2x2 part
describing a combined scaling, rotation and shear, and the two top-right
components specifying a translation: @f[
\boldsymbol{T} = \begin{pmatrix}
\color{m-danger} a_x & \color{m-success} b_x & \color{m-warning} t_x \\
\color{m-danger} a_y & \color{m-success} b_y & \color{m-warning} t_y \\
\color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1
\end{pmatrix}
@f]
The @f$ \color{m-danger} \boldsymbol{a} @f$ and
@f$ \color{m-success} \boldsymbol{b} @f$ vectors can be also thought of as the
two basis vectors describing the coordinate system the matrix converts to. The
bottom row is always
@f$ \begin{pmatrix} \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} @f$
as, unlike with @ref Matrix4 in 3D, perspective shortening happening along the
X or Y axis isn't really a thing.
@section Math-Matrix3-usage Usage
See @ref types, @ref matrix-vector and @ref 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
@ref translation(const Vector2<T>&) "translation()",
@ref rotation(Rad<T>) "rotation()", @ref scaling(const Vector2<T>&) "scaling()",
@ref reflection(), @ref shearingX(), @ref shearingY(), and @ref projection()
and multiplying them together to form the final transformation --- the
rightmost transformation is applied first, leftmost last:
@snippet MagnumMath.cpp Matrix3-usage
Conversely, the transformation parts can be extracted back using the member
@ref rotation() const "rotation()", @ref scaling() const "scaling()" and their
variants, and @ref translation(). The basis vectors can be accessed using
@ref right() and @ref up(). 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 @ref Algorithms::qr() or @ref 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
@ref Algorithms::gramSchmidtOrthonormalizeInPlace() and variants.
@see @ref Magnum::Matrix3, @ref Magnum::Matrix3d, @ref Matrix3x3,
@ref DualComplex, @ref SceneGraph::MatrixTransformation2D
@configurationvalueref{Magnum::Math::Matrix3}
*/
template<class T> class Matrix3: public Matrix3x3<T> {
public:
Expand Down
65 changes: 63 additions & 2 deletions src/Magnum/Math/Matrix4.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,71 @@ namespace Magnum { namespace Math {
@brief 3D transformation matrix
@tparam T Underlying data type
See @ref matrix-vector and @ref transformations for brief introduction.
Expands upon a generic @ref 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: @f[
\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}
@f]
The @f$ \color{m-danger} \boldsymbol{a} @f$,
@f$ \color{m-success} \boldsymbol{b} @f$ and @f$ \color{m-info} \boldsymbol{c} @f$
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
@f$ \begin{pmatrix} \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 0 & \color{m-dim} 1 \end{pmatrix} @f$. A (pure) 3D perspective projection matrix, however,
can look for example like this: @f[
\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}
@f]
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 @ref Matrix3.
@section Math-Matrix4-usage Usage
See @ref types, @ref matrix-vector and @ref 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
@ref translation(const Vector3<T>&) "translation()",
@ref rotation(Rad<T>, const Vector3<T>&) "rotation()" and variants,
@ref scaling(const Vector3<T>&) "scaling()", @ref reflection(),
@ref shearingXY() and variants, @ref lookAt() and @ref orthographicProjection()
/ @ref perspectiveProjection() and multiplying them together to form the final
transformation --- the rightmost transformation is applied first, leftmost
last:
@snippet MagnumMath.cpp Matrix4-usage
Conversely, the transformation parts can be extracted back using the member
@ref rotation() const "rotation()", @ref scaling() const "scaling()" and their
variants, and @ref translation(). The basis vectors can be accessed using
@ref right(), @ref up() and @ref 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 @ref Algorithms::qr() or
@ref 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
@ref Algorithms::gramSchmidtOrthonormalizeInPlace() and variants.
@see @ref Magnum::Matrix4, @ref Magnum::Matrix4d, @ref Matrix4x4,
@ref DualQuaternion, @ref SceneGraph::MatrixTransformation3D
@configurationvalueref{Magnum::Math::Matrix4}
*/
template<class T> class Matrix4: public Matrix4x4<T> {
public:
Expand Down

0 comments on commit 3097c4c

Please sign in to comment.