Browse Source

Math: document the math behind 2D/3D matrix transformations.

pull/179/head
Vladimír Vondruš 10 years ago
parent
commit
98735f50f4
  1. 48
      src/Magnum/Math/Matrix3.h
  2. 125
      src/Magnum/Math/Matrix4.h
  3. 3
      src/Magnum/Math/RectangularMatrix.h

48
src/Magnum/Math/Matrix3.h

@ -49,6 +49,13 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @brief 2D translation matrix * @brief 2D translation matrix
* @param vector Translation vector * @param vector Translation vector
* *
* @f[
* \boldsymbol{A} = \begin{pmatrix}
* 1 & 0 & v_x \\
* 0 & 1 & v_y \\
* 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref translation() const, @ref DualComplex::translation(), * @see @ref translation() const, @ref DualComplex::translation(),
* @ref Matrix4::translation(const Vector3<T>&), * @ref Matrix4::translation(const Vector3<T>&),
* @ref Vector2::xAxis(), @ref Vector2::yAxis() * @ref Vector2::xAxis(), @ref Vector2::yAxis()
@ -63,6 +70,13 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @brief 2D scaling matrix * @brief 2D scaling matrix
* @param vector Scaling vector * @param vector Scaling vector
* *
* @f[
* \boldsymbol{A} = \begin{pmatrix}
* v_x & 0 & 0 \\
* 0 & v_y & 0 \\
* 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref rotationScaling(), * @see @ref rotationScaling(),
* @ref Matrix4::scaling(const Vector3<T>&), * @ref Matrix4::scaling(const Vector3<T>&),
* @ref Vector2::xScale(), @ref Vector2::yScale() * @ref Vector2::xScale(), @ref Vector2::yScale()
@ -77,6 +91,13 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @brief 2D rotation matrix * @brief 2D rotation matrix
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* @f[
* \boldsymbol{A} = \begin{pmatrix}
* \cos\theta & -\sin\theta & 0 \\
* \sin\theta & \cos\theta & 0 \\
* 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref rotation() const, @ref Complex::rotation(), * @see @ref rotation() const, @ref Complex::rotation(),
* @ref DualComplex::rotation(), * @ref DualComplex::rotation(),
* @ref Matrix4::rotation(Rad, const Vector3<T>&) * @ref Matrix4::rotation(Rad, const Vector3<T>&)
@ -90,7 +111,9 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* Expects that the normal is normalized. Reflection along axes can be * Expects that the normal is normalized. Reflection along axes can be
* done in a slightly simpler way also using @ref scaling(), e.g. * done in a slightly simpler way also using @ref scaling(), e.g.
* `Matrix3::reflection(Vector2::yAxis())` is equivalent to * `Matrix3::reflection(Vector2::yAxis())` is equivalent to
* `Matrix3::scaling(Vector2::yScale(-1.0f))`. * `Matrix3::scaling(Vector2::yScale(-1.0f))`. @f[
* \boldsymbol{A} = \boldsymbol{I} - 2 \boldsymbol{NN}^T ~~~~~ \boldsymbol{N} = \begin{pmatrix} n_x \\ n_y \end{pmatrix}
* @f]
* @see @ref Matrix4::reflection(), @ref Vector::isNormalized() * @see @ref Matrix4::reflection(), @ref Vector::isNormalized()
*/ */
static Matrix3<T> reflection(const Vector2<T>& normal) { static Matrix3<T> reflection(const Vector2<T>& normal) {
@ -103,7 +126,13 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @brief 2D shearing matrix along X axis * @brief 2D shearing matrix along X axis
* @param amount Shearing amount * @param amount Shearing amount
* *
* Y axis remains unchanged. * Y axis remains unchanged. @f[
* \boldsymbol{A} = \begin{pmatrix}
* 1 & v_x & 0 \\
* 0 & 1 & 0 \\
* 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref shearingY(), @ref Matrix4::shearingXY(), * @see @ref shearingY(), @ref Matrix4::shearingXY(),
* @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ() * @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ()
*/ */
@ -117,7 +146,13 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @brief 2D shearing matrix along Y axis * @brief 2D shearing matrix along Y axis
* @param amount Shearing amount * @param amount Shearing amount
* *
* X axis remains unchanged. * X axis remains unchanged. @f[
* \boldsymbol{A} = \begin{pmatrix}
* 1 & 0 & 0 \\
* v_y & 1 & 0 \\
* 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref shearingX(), @ref Matrix4::shearingXY(), * @see @ref shearingX(), @ref Matrix4::shearingXY(),
* @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ() * @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ()
*/ */
@ -131,6 +166,13 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @brief 2D projection matrix * @brief 2D projection matrix
* @param size Size of the view * @param size Size of the view
* *
* @f[
* \boldsymbol{A} = \begin{pmatrix}
* \frac{2}{s_x} & 0 & 0 \\
* 0 & \frac{2}{s_y} & 0 \\
* 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref Matrix4::orthographicProjection(), * @see @ref Matrix4::orthographicProjection(),
* @ref Matrix4::perspectiveProjection() * @ref Matrix4::perspectiveProjection()
*/ */

125
src/Magnum/Math/Matrix4.h

@ -51,9 +51,17 @@ See @ref matrix-vector and @ref transformations for brief introduction.
template<class T> class Matrix4: public Matrix4x4<T> { template<class T> class Matrix4: public Matrix4x4<T> {
public: public:
/** /**
* @brief 3D translation * @brief 3D translation matrix
* @param vector Translation vector * @param vector Translation vector
* *
* @f[
* \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}
* @f]
* @see @ref translation(), @ref DualQuaternion::translation(), * @see @ref translation(), @ref DualQuaternion::translation(),
* @ref Matrix3::translation(const Vector2<T>&), * @ref Matrix3::translation(const Vector2<T>&),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(), * @ref Vector3::xAxis(), @ref Vector3::yAxis(),
@ -67,9 +75,17 @@ template<class T> class Matrix4: public Matrix4x4<T> {
} }
/** /**
* @brief 3D scaling * @brief 3D scaling matrix
* @param vector Scaling vector * @param vector Scaling vector
* *
* @f[
* \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}
* @f]
* @see @ref rotationScaling(), * @see @ref rotationScaling(),
* @ref Matrix3::scaling(const Vector2<T>&), * @ref Matrix3::scaling(const Vector2<T>&),
* @ref Vector3::xScale(), @ref Vector3::yScale(), * @ref Vector3::xScale(), @ref Vector3::yScale(),
@ -83,13 +99,20 @@ template<class T> class Matrix4: public Matrix4x4<T> {
} }
/** /**
* @brief 3D rotation around arbitrary axis * @brief 3D rotation matrix around arbitrary axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* @param normalizedAxis Normalized rotation axis * @param normalizedAxis Normalized rotation axis
* *
* Expects that the rotation axis is normalized. If possible, use * Expects that the rotation axis is normalized. If possible, use
* faster alternatives like @ref rotationX(), @ref rotationY() and * faster alternatives like @ref rotationX(), @ref rotationY() and
* @ref rotationZ(). * @ref rotationZ(). @f[
* \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}
* @f]
* @see @ref rotation() const, @ref Quaternion::rotation(), * @see @ref rotation() const, @ref Quaternion::rotation(),
* @ref DualQuaternion::rotation(), @ref Matrix3::rotation(Rad), * @ref DualQuaternion::rotation(), @ref Matrix3::rotation(Rad),
* @ref Vector3::xAxis(), @ref Vector3::yAxis(), * @ref Vector3::xAxis(), @ref Vector3::yAxis(),
@ -98,10 +121,17 @@ template<class T> class Matrix4: public Matrix4x4<T> {
static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis); static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis);
/** /**
* @brief 3D rotation around X axis * @brief 3D rotation matrix around X axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`. * Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`. @f[
* \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}
* @f]
* @see @ref rotation(Rad, const Vector3<T>&), @ref rotationY(), * @see @ref rotation(Rad, const Vector3<T>&), @ref rotationY(),
* @ref rotationZ(), @ref rotation() const, * @ref rotationZ(), @ref rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad) * @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
@ -109,10 +139,17 @@ template<class T> class Matrix4: public Matrix4x4<T> {
static Matrix4<T> rotationX(Rad<T> angle); static Matrix4<T> rotationX(Rad<T> angle);
/** /**
* @brief 3D rotation around Y axis * @brief 3D rotation matrix around Y axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`. * Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`. @f[
* \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}
* @f]
* @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(), * @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(),
* @ref rotationZ(), @ref rotation() const, * @ref rotationZ(), @ref rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad) * @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
@ -123,7 +160,14 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* @brief 3D rotation matrix around Z axis * @brief 3D rotation matrix around Z axis
* @param angle Rotation angle (counterclockwise) * @param angle Rotation angle (counterclockwise)
* *
* Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`. * Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`. @f[
* \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}
* @f]
* @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(), * @see @ref rotation(Rad, const Vector3<T>&), @ref rotationX(),
* @ref rotationY(), @ref rotation() const, * @ref rotationY(), @ref rotation() const,
* @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad) * @ref Quaternion::rotation(), @ref Matrix3::rotation(Rad)
@ -137,17 +181,26 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* Expects that the normal is normalized. Reflection along axes can be * Expects that the normal is normalized. Reflection along axes can be
* done in a slightly simpler way also using @ref scaling(), e.g. * done in a slightly simpler way also using @ref scaling(), e.g.
* `Matrix4::reflection(Vector3::yAxis())` is equivalent to * `Matrix4::reflection(Vector3::yAxis())` is equivalent to
* `Matrix4::scaling(Vector3::yScale(-1.0f))`. * `Matrix4::scaling(Vector3::yScale(-1.0f))`. @f[
* \boldsymbol{A} = \boldsymbol{I} - 2 \boldsymbol{NN}^T ~~~~~ \boldsymbol{N} = \begin{pmatrix} n_x \\ n_y \\ n_z \end{pmatrix}
* @f]
* @see @ref Matrix3::reflection(), @ref Vector::isNormalized() * @see @ref Matrix3::reflection(), @ref Vector::isNormalized()
*/ */
static Matrix4<T> reflection(const Vector3<T>& normal); static Matrix4<T> reflection(const Vector3<T>& normal);
/** /**
* @brief 3D shearing along XY plane * @brief 3D shearing matrix along XY plane
* @param amountX Amount of shearing along X axis * @param amountX Amount of shearing along X axis
* @param amountY Amount of shearing along Y axis * @param amountY Amount of shearing along Y axis
* *
* Z axis remains unchanged. * Z axis remains unchanged. @f[
* \boldsymbol{A} = \begin{pmatrix}
* 1 & 0 & v_x & 0 \\
* 0 & 1 & v_y & 0 \\
* 0 & 0 & 1 & 0 \\
* 0 & 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref shearingXZ(), @ref shearingYZ(), @ref Matrix3::shearingX(), * @see @ref shearingXZ(), @ref shearingYZ(), @ref Matrix3::shearingX(),
* @ref Matrix3::shearingY() * @ref Matrix3::shearingY()
*/ */
@ -159,11 +212,18 @@ template<class T> class Matrix4: public Matrix4x4<T> {
} }
/** /**
* @brief 3D shearing along XZ plane * @brief 3D shearing matrix along XZ plane
* @param amountX Amount of shearing along X axis * @param amountX Amount of shearing along X axis
* @param amountZ Amount of shearing along Z axis * @param amountZ Amount of shearing along Z axis
* *
* Y axis remains unchanged. * Y axis remains unchanged. @f[
* \boldsymbol{A} = \begin{pmatrix}
* 1 & v_x & 0 & 0 \\
* 0 & 1 & 0 & 0 \\
* 0 & v_z & 1 & 0 \\
* 0 & 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref shearingXY(), @ref shearingYZ(), @ref Matrix3::shearingX(), * @see @ref shearingXY(), @ref shearingYZ(), @ref Matrix3::shearingX(),
* @ref Matrix3::shearingY() * @ref Matrix3::shearingY()
*/ */
@ -175,11 +235,18 @@ template<class T> class Matrix4: public Matrix4x4<T> {
} }
/** /**
* @brief 3D shearing along YZ plane * @brief 3D shearing matrix along YZ plane
* @param amountY Amount of shearing along Y axis * @param amountY Amount of shearing along Y axis
* @param amountZ Amount of shearing along Z axis * @param amountZ Amount of shearing along Z axis
* *
* X axis remains unchanged. * X axis remains unchanged. @f[
* \boldsymbol{A} = \begin{pmatrix}
* 1 & 0 & 0 & 0 \\
* v_y & 1 & 0 & 0 \\
* v_z & 0 & 1 & 0 \\
* 0 & 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref shearingXY(), @ref shearingXZ(), @ref Matrix3::shearingX(), * @see @ref shearingXY(), @ref shearingXZ(), @ref Matrix3::shearingX(),
* @ref Matrix3::shearingY() * @ref Matrix3::shearingY()
*/ */
@ -196,6 +263,14 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* @param near Distance to near clipping plane, positive is ahead * @param near Distance to near clipping plane, positive is ahead
* @param far Distance to far clipping plane, positive is ahead * @param far Distance to far clipping plane, positive is ahead
* *
* @f[
* \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{2n}{n - f} - 1 \\
* 0 & 0 & 0 & 1
* \end{pmatrix}
* @f]
* @see @ref perspectiveProjection(), @ref Matrix3::projection() * @see @ref perspectiveProjection(), @ref Matrix3::projection()
*/ */
static Matrix4<T> orthographicProjection(const Vector2<T>& size, T near, T far); static Matrix4<T> orthographicProjection(const Vector2<T>& size, T near, T far);
@ -206,6 +281,14 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* @param near Distance to near clipping plane, positive is ahead * @param near Distance to near clipping plane, positive is ahead
* @param far Distance to far clipping plane, positive is ahead * @param far Distance to far clipping plane, positive is ahead
* *
* @f[
* \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}
* @f]
* @see @ref orthographicProjection(), @ref Matrix3::projection() * @see @ref orthographicProjection(), @ref Matrix3::projection()
*/ */
static Matrix4<T> perspectiveProjection(const Vector2<T>& size, T near, T far); static Matrix4<T> perspectiveProjection(const Vector2<T>& size, T near, T far);
@ -217,6 +300,14 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* @param near Near clipping plane * @param near Near clipping plane
* @param far Far clipping plane * @param far Far clipping plane
* *
* @f[
* \boldsymbol{A} = \begin{pmatrix}
* \frac{1}{\tan{\frac{\theta}{2}}} & 0 & 0 & 0 \\
* 0 & \frac{a}{\tan{\frac{\theta}{2}}} & 0 & 0 \\
* 0 & 0 & \frac{n + f}{n - f} & \frac{2nf}{n - f} \\
* 0 & 0 & -1 & 0
* \end{pmatrix}
* @f]
* @see @ref orthographicProjection(), @ref Matrix3::projection() * @see @ref orthographicProjection(), @ref Matrix3::projection()
*/ */
static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) { static Matrix4<T> perspectiveProjection(Rad<T> fov, T aspectRatio, T near, T far) {
@ -447,7 +538,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* *
* Unlike in @ref transformVector(), translation is also involved in * Unlike in @ref transformVector(), translation is also involved in
* the transformation. @f[ * the transformation. @f[
* \boldsymbol v' = 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} \\ * \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} \\
* @f] * @f]
* @see @ref DualQuaternion::transformPoint(), * @see @ref DualQuaternion::transformPoint(),
* @ref Matrix3::transformPoint() * @ref Matrix3::transformPoint()

3
src/Magnum/Math/RectangularMatrix.h

@ -339,6 +339,9 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** /**
* @brief Transposed matrix * @brief Transposed matrix
* *
* @f[
* \boldsymbol{A}^T_ij = \boldsymbol{A}_ji
* @f]
* @see @ref row(), @ref flippedCols(), @ref flippedRows() * @see @ref row(), @ref flippedCols(), @ref flippedRows()
*/ */
RectangularMatrix<rows, cols, T> transposed() const; RectangularMatrix<rows, cols, T> transposed() const;

Loading…
Cancel
Save