diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index 31eefcf6d..1dec2c7f3 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -24,9 +24,56 @@ namespace Magnum { namespace Math { -/** @brief 3x3 matrix */ +/** +@brief 3x3 matrix + +Provides functions for transformations in 2D. See also Matrix4 for 3D +transformations. +*/ template class Matrix3: public Matrix<3, T> { public: + /** + * @brief 2D translation matrix + * @param vec Translation vector + * + * @see Matrix4::translation() + */ + inline constexpr static Matrix3 translation(const Vector2& vec) { + return Matrix3( /* Column-major! */ + T(1), T(0), T(0), + T(0), T(1), T(0), + vec.x(), vec.y(), T(1) + ); + } + + /** + * @brief 2D scaling matrix + * @param vec Scaling vector + * + * @see Matrix4::scaling() + */ + inline constexpr static Matrix3 scaling(const Vector2& vec) { + return Matrix3( /* Column-major! */ + vec.x(), T(0), T(0), + T(0), vec.y(), T(0), + T(0), T(0), T(1) + ); + } + + /** + * @brief 3D rotation matrix + * @param angle Rotation angle (counterclockwise, in radians) + * + * @see Matrix4::rotation() + */ + static Matrix3 rotation(T angle) { + return Matrix3( /* Column-major! */ + T(cos(angle)), T(sin(angle)), T(0), + -T(sin(angle)), T(cos(angle)), T(0), + T(0), T(0), T(1) + ); + } + /** @copydoc Matrix::Matrix(ZeroType) */ inline constexpr explicit Matrix3(typename Matrix<3, T>::ZeroType): Matrix<3, T>(Matrix<3, T>::Zero) {} diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index d9ce27269..9674d2159 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -27,14 +27,18 @@ namespace Magnum { namespace Math { /** @brief 4x4 matrix +Provides functions for transformations in 3D. See also Matrix3 for 2D +transformations. @todo Shearing @todo Reflection */ template class Matrix4: public Matrix<4, T> { public: /** - * @brief Translation matrix + * @brief 3D translation matrix * @param vec Translation vector + * + * @see Matrix3::translation() */ inline constexpr static Matrix4 translation(const Vector3& vec) { return Matrix4( /* Column-major! */ @@ -46,8 +50,10 @@ template class Matrix4: public Matrix<4, T> { } /** - * @brief Scaling matrix + * @brief 3D scaling matrix * @param vec Scaling vector + * + * @see Matrix3::scaling() */ inline constexpr static Matrix4 scaling(const Vector3& vec) { return Matrix4( /* Column-major! */ @@ -59,10 +65,11 @@ template class Matrix4: public Matrix<4, T> { } /** - * @brief Rotation matrix + * @brief 3D rotation matrix * @param angle Rotation angle (counterclockwise, in radians) * @param vec Rotation vector * + * @see Matrix3::rotation() * @todo optimize - Assume the vectors are normalized? */ static Matrix4 rotation(T angle, const Vector3& vec) { diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index ab550d6a8..32d445d72 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -19,6 +19,7 @@ #include #include "Matrix3.h" +#include "Math.h" QTEST_APPLESS_MAIN(Magnum::Math::Test::Matrix3Test) @@ -51,6 +52,36 @@ void Matrix3Test::constructIdentity() { QVERIFY(identity3 == identity3Expected); } +void Matrix3Test::translation() { + Matrix3 matrix( + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 3.0f, 1.0f, 1.0f + ); + + QVERIFY(Matrix3::translation({3.0f, 1.0f}) == matrix); +} + +void Matrix3Test::scaling() { + Matrix3 matrix( + 3.0f, 0.0f, 0.0f, + 0.0f, 1.5f, 0.0f, + 0.0f, 0.0f, 1.0f + ); + + QVERIFY(Matrix3::scaling({3.0f, 1.5f}) == matrix); +} + +void Matrix3Test::rotation() { + Matrix3 matrix( + 0.965926f, 0.258819f, 0.0f, + -0.258819f, 0.965926f, 0.0f, + 0.0f, 0.0f, 1.0f + ); + + QVERIFY(Matrix3::rotation(deg(15.0f)) == matrix); +} + void Matrix3Test::debug() { Matrix3 m( 3.0f, 5.0f, 8.0f, diff --git a/src/Math/Test/Matrix3Test.h b/src/Math/Test/Matrix3Test.h index d482a6a0c..60aed65b4 100644 --- a/src/Math/Test/Matrix3Test.h +++ b/src/Math/Test/Matrix3Test.h @@ -25,6 +25,9 @@ class Matrix3Test: public QObject { private slots: void constructIdentity(); + void translation(); + void scaling(); + void rotation(); void debug(); };