From 7c17871c906da2249ae8d2cb21caa8dcc767aac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 17 Sep 2012 13:44:31 +0200 Subject: [PATCH] Assuming the vectors are normalized in Matrix4::rotation(). --- src/Math/Matrix4.h | 35 +++++++++++++++++++---------------- src/Math/Test/CMakeLists.txt | 3 ++- src/Math/Test/Matrix4Test.cpp | 22 ++++++++++++++-------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 487a6baa9..ac4ad1639 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -69,36 +69,39 @@ template class Matrix4: public Matrix<4, T> { /** * @brief 3D rotation matrix * @param angle Rotation angle (counterclockwise, in radians) - * @param vec Rotation vector + * @param vec Normalized rotation vector * - * @see Matrix3::rotation(), Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(), deg(), rad() - * @todo optimize - Assume the vectors are normalized? + * @see Matrix3::rotation(), Vector3::xAxis(), Vector3::yAxis(), + * Vector3::zAxis(), deg(), rad() + * @attention Assertion fails on non-normalized rotation vector and + * identity matrix is returned. */ static Matrix4 rotation(T angle, const Vector3& vec) { - Vector3 vn = vec.normalized(); + CORRADE_ASSERT(MathTypeTraits::equals(vec.dot(), T(1)), + "Math::Matrix4::rotation(): vector must be normalized", {}); T sine = std::sin(angle); T cosine = std::cos(angle); T oneMinusCosine = T(1) - cosine; - T xx = vn.x()*vn.x(); - T xy = vn.x()*vn.y(); - T xz = vn.x()*vn.z(); - T yy = vn.y()*vn.y(); - T yz = vn.y()*vn.z(); - T zz = vn.z()*vn.z(); + T xx = vec.x()*vec.x(); + T xy = vec.x()*vec.y(); + T xz = vec.x()*vec.z(); + T yy = vec.y()*vec.y(); + T yz = vec.y()*vec.z(); + T zz = vec.z()*vec.z(); return Matrix4( /* Column-major! */ cosine + xx*oneMinusCosine, - xy*oneMinusCosine + vn.z()*sine, - xz*oneMinusCosine - vn.y()*sine, + xy*oneMinusCosine + vec.z()*sine, + xz*oneMinusCosine - vec.y()*sine, T(0), - xy*oneMinusCosine - vn.z()*sine, + xy*oneMinusCosine - vec.z()*sine, cosine + yy*oneMinusCosine, - yz*oneMinusCosine + vn.x()*sine, + yz*oneMinusCosine + vec.x()*sine, T(0), - xz*oneMinusCosine + vn.y()*sine, - yz*oneMinusCosine - vn.x()*sine, + xz*oneMinusCosine + vec.y()*sine, + yz*oneMinusCosine - vec.x()*sine, cosine + zz*oneMinusCosine, T(0), T(0), T(0), T(0), T(1) diff --git a/src/Math/Test/CMakeLists.txt b/src/Math/Test/CMakeLists.txt index a62ecefca..0f1e08a80 100644 --- a/src/Math/Test/CMakeLists.txt +++ b/src/Math/Test/CMakeLists.txt @@ -5,7 +5,6 @@ corrade_add_test2(MathMathTypeTraitsTest MathTypeTraitsTest.cpp) corrade_add_test2(MathRectangularMatrixTest RectangularMatrixTest.cpp) corrade_add_test2(MathVectorTest VectorTest.cpp) -set_target_properties(MathVectorTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) corrade_add_test2(MathVector2Test Vector2Test.cpp) corrade_add_test2(MathVector3Test Vector3Test.cpp) corrade_add_test2(MathVector4Test Vector4Test.cpp) @@ -16,3 +15,5 @@ corrade_add_test2(MathPoint3DTest Point3DTest.cpp) corrade_add_test2(MathMatrixTest MatrixTest.cpp) corrade_add_test2(MathMatrix3Test Matrix3Test.cpp) corrade_add_test2(MathMatrix4Test Matrix4Test.cpp) + +set_target_properties(MathVectorTest MathMatrix4Test PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index 03111d207..6451585f1 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -29,6 +29,7 @@ namespace Magnum { namespace Math { namespace Test { typedef Math::Matrix4 Matrix4; typedef Math::Matrix3 Matrix3; +typedef Math::Vector3 Vector3; Matrix4Test::Matrix4Test() { addTests(&Matrix4Test::constructIdentity, @@ -88,14 +89,19 @@ void Matrix4Test::scaling() { } void Matrix4Test::rotation() { + ostringstream o; + Error::setOutput(&o); + + CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}), Matrix4()); + CORRADE_COMPARE(o.str(), "Math::Matrix4::rotation(): vector must be normalized\n"); + Matrix4 matrix( - 0.35612214f, -0.80181062f, 0.47987163f, 0.0f, - 0.47987163f, 0.59757638f, 0.6423595f, 0.0f, - -0.80181062f, 0.0015183985f, 0.59757638f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f + 0.35612214f, -0.80181062f, 0.47987163f, 0.0f, + 0.47987163f, 0.59757638f, 0.6423595f, 0.0f, + -0.80181062f, 0.0015183985f, 0.59757638f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f ); - - CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}), matrix); + CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized()), matrix); } void Matrix4Test::rotationScalingPart() { @@ -122,10 +128,10 @@ void Matrix4Test::rotationPart() { -0.80181062f, 0.0015183985f, 0.59757638f ); - Matrix4 rotation = Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}); + Matrix4 rotation = Matrix4::rotation(deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized()); CORRADE_COMPARE(rotation.rotation(), expectedRotationPart); - Matrix4 rotationTransformed = Matrix4::translation({2.0f, 5.0f, -3.0f})*rotation*Matrix4::scaling(Vector3(9.0f)); + Matrix4 rotationTransformed = Matrix4::translation({2.0f, 5.0f, -3.0f})*rotation*Matrix4::scaling(Vector3(9.0f)); CORRADE_COMPARE(rotationTransformed.rotation(), expectedRotationPart); }