From f30a4677eb441419db7440b1fa2d15418f1ae9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 11 Jan 2015 22:33:33 +0100 Subject: [PATCH] Math: added Matrix[34]::shearing*(). --- src/Magnum/Math/Matrix3.h | 28 ++++++++++++++++ src/Magnum/Math/Matrix4.h | 48 ++++++++++++++++++++++++++++ src/Magnum/Math/Test/Matrix3Test.cpp | 20 ++++++++++++ src/Magnum/Math/Test/Matrix4Test.cpp | 33 +++++++++++++++++++ 4 files changed, 129 insertions(+) diff --git a/src/Magnum/Math/Matrix3.h b/src/Magnum/Math/Matrix3.h index 6d2d635db..cf9d1ad35 100644 --- a/src/Magnum/Math/Matrix3.h +++ b/src/Magnum/Math/Matrix3.h @@ -99,6 +99,34 @@ template class Matrix3: public Matrix3x3 { return from(Matrix2x2() - T(2)*normal*RectangularMatrix<1, 2, T>(normal).transposed(), {}); } + /** + * @brief 2D shearing matrix along X axis + * @param amount Shearing amount + * + * Y axis remains unchanged. + * @see @ref shearingY(), @ref Matrix4::shearingXY(), + * @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ() + */ + constexpr static Matrix3 shearingX(T amount) { + return {{ T(1), T(0), T(0)}, + {amount, T(1), T(0)}, + { T(0), T(0), T(1)}}; + } + + /** + * @brief 2D shearing matrix along Y axis + * @param amount Shearing amount + * + * X axis remains unchanged. + * @see @ref shearingX(), @ref Matrix4::shearingXY(), + * @ref Matrix4::shearingXZ(), @ref Matrix4::shearingYZ() + */ + constexpr static Matrix3 shearingY(T amount) { + return {{T(1), amount, T(0)}, + {T(0), T(1), T(0)}, + {T(0), T(0), T(1)}}; + } + /** * @brief 2D projection matrix * @param size Size of the view diff --git a/src/Magnum/Math/Matrix4.h b/src/Magnum/Math/Matrix4.h index 1c7009584..8d713cc82 100644 --- a/src/Magnum/Math/Matrix4.h +++ b/src/Magnum/Math/Matrix4.h @@ -142,6 +142,54 @@ template class Matrix4: public Matrix4x4 { */ static Matrix4 reflection(const Vector3& normal); + /** + * @brief 3D shearing along XY plane + * @param amountX Amount of shearing along X axis + * @param amountY Amount of shearing along Y axis + * + * Z axis remains unchanged. + * @see @ref shearingXZ(), @ref shearingYZ(), @ref Matrix3::shearingX(), + * @ref Matrix3::shearingY() + */ + constexpr static Matrix4 shearingXY(T amountX, T amountY) { + return {{ (1), T(0), T(0), T(0)}, + { (0), T(1), T(0), T(0)}, + {amountX, amountY, T(1), T(0)}, + { (0), T(0), T(0), T(1)}}; + } + + /** + * @brief 3D shearing along XZ plane + * @param amountX Amount of shearing along X axis + * @param amountZ Amount of shearing along Z axis + * + * Y axis remains unchanged. + * @see @ref shearingXY(), @ref shearingYZ(), @ref Matrix3::shearingX(), + * @ref Matrix3::shearingY() + */ + constexpr static Matrix4 shearingXZ(T amountX, T amountZ) { + return {{ T(1), T(0), T(0), T(0)}, + {amountX, T(1), amountZ, T(0)}, + { T(0), T(0), T(1), T(0)}, + { T(0), T(0), T(0), T(1)}}; + } + + /** + * @brief 3D shearing along YZ plane + * @param amountY Amount of shearing along Y axis + * @param amountZ Amount of shearing along Z axis + * + * X axis remains unchanged. + * @see @ref shearingXY(), @ref shearingXZ(), @ref Matrix3::shearingX(), + * @ref Matrix3::shearingY() + */ + constexpr static Matrix4 shearingYZ(T amountY, T amountZ) { + return {{T(1), amountY, amountZ, T(0)}, + {T(0), T(1), T(0), T(0)}, + {T(0), T(0), T(1), T(0)}, + {T(0), T(0), T(0), T(1)}}; + } + /** * @brief 3D orthographic projection matrix * @param size Size of the view diff --git a/src/Magnum/Math/Test/Matrix3Test.cpp b/src/Magnum/Math/Test/Matrix3Test.cpp index 7a9b13480..15fce0e7b 100644 --- a/src/Magnum/Math/Test/Matrix3Test.cpp +++ b/src/Magnum/Math/Test/Matrix3Test.cpp @@ -74,6 +74,8 @@ struct Matrix3Test: Corrade::TestSuite::Tester { void rotation(); void reflection(); void reflectionIsScaling(); + void shearingX(); + void shearingY(); void projection(); void fromParts(); void rotationScalingPart(); @@ -111,6 +113,8 @@ Matrix3Test::Matrix3Test() { &Matrix3Test::rotation, &Matrix3Test::reflection, &Matrix3Test::reflectionIsScaling, + &Matrix3Test::shearingX, + &Matrix3Test::shearingY, &Matrix3Test::projection, &Matrix3Test::fromParts, &Matrix3Test::rotationScalingPart, @@ -259,6 +263,22 @@ void Matrix3Test::reflectionIsScaling() { CORRADE_COMPARE(Matrix3::reflection(Vector2::yAxis()), Matrix3::scaling(Vector2::yScale(-1.0f))); } +void Matrix3Test::shearingX() { + constexpr Matrix3 a = Matrix3::shearingX(3.0f); + CORRADE_COMPARE(a, Matrix3({1.0f, 0.0f, 0.0f}, + {3.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector2(1.0f)), Vector2(4.0f, 1.0f)); +} + +void Matrix3Test::shearingY() { + constexpr Matrix3 a = Matrix3::shearingY(3.0f); + CORRADE_COMPARE(a, Matrix3({1.0f, 3.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector2(1.0f)), Vector2(1.0f, 4.0f)); +} + void Matrix3Test::projection() { Matrix3 expected({2.0f/4.0f, 0.0f, 0.0f}, { 0.0f, 2.0f/3.0f, 0.0f}, diff --git a/src/Magnum/Math/Test/Matrix4Test.cpp b/src/Magnum/Math/Test/Matrix4Test.cpp index 2dfcd68c1..f3b832d55 100644 --- a/src/Magnum/Math/Test/Matrix4Test.cpp +++ b/src/Magnum/Math/Test/Matrix4Test.cpp @@ -79,6 +79,9 @@ struct Matrix4Test: Corrade::TestSuite::Tester { void rotationZ(); void reflection(); void reflectionIsScaling(); + void shearingXY(); + void shearingXZ(); + void shearingYZ(); void orthographicProjection(); void perspectiveProjection(); void perspectiveProjectionFov(); @@ -122,6 +125,9 @@ Matrix4Test::Matrix4Test() { &Matrix4Test::rotationZ, &Matrix4Test::reflection, &Matrix4Test::reflectionIsScaling, + &Matrix4Test::shearingXY, + &Matrix4Test::shearingXZ, + &Matrix4Test::shearingYZ, &Matrix4Test::orthographicProjection, &Matrix4Test::perspectiveProjection, &Matrix4Test::perspectiveProjectionFov, @@ -323,6 +329,33 @@ void Matrix4Test::reflectionIsScaling() { CORRADE_COMPARE(Matrix4::reflection(Vector3::yAxis()), Matrix4::scaling(Vector3::yScale(-1.0f))); } +void Matrix4Test::shearingXY() { + constexpr Matrix4 a = Matrix4::shearingXY(3.0f, -5.0f); + CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {3.0f, -5.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector3(1.0f)), Vector3(4.0f, -4.0f, 1.0f)); +} + +void Matrix4Test::shearingXZ() { + constexpr Matrix4 a = Matrix4::shearingXZ(3.0f, -5.0f); + CORRADE_COMPARE(a, Matrix4({1.0f, 0.0f, 0.0f, 0.0f}, + {3.0f, 1.0f, -5.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector3(1.0f)), Vector3(4.0f, 1.0f, -4.0f)); +} + +void Matrix4Test::shearingYZ() { + constexpr Matrix4 a = Matrix4::shearingYZ(3.0f, -5.0f); + CORRADE_COMPARE(a, Matrix4({1.0f, 3.0f, -5.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + CORRADE_COMPARE(a.transformPoint(Vector3(1.0f)), Vector3(1.0f, 4.0f, -4.0f)); +} + void Matrix4Test::orthographicProjection() { Matrix4 expected({0.4f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.5f, 0.0f, 0.0f},