From 041e541d39bf648c1b37e4e9c7d467a3d8ed6c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 18 Dec 2012 22:54:54 +0100 Subject: [PATCH] SceneGraph: ability to normalize rotation in Euclidean transformation. --- .../EuclideanMatrixTransformation2D.h | 24 +++++++++++++- .../EuclideanMatrixTransformation3D.h | 32 ++++++++++++++++--- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/SceneGraph/EuclideanMatrixTransformation2D.h b/src/SceneGraph/EuclideanMatrixTransformation2D.h index 1eb73381b..cb4a59081 100644 --- a/src/SceneGraph/EuclideanMatrixTransformation2D.h +++ b/src/SceneGraph/EuclideanMatrixTransformation2D.h @@ -20,6 +20,7 @@ */ #include "Math/Matrix3.h" +#include "Math/Algorithms/GramSchmidt.h" #include "AbstractTranslationRotation2D.h" #include "Object.h" @@ -75,13 +76,34 @@ class EuclideanMatrixTransformation2D: public AbstractTranslationRotation2D { return this; } + /** + * @brief Normalize rotation part + * @return Pointer to self (for method chaining) + * + * Normalizes the rotation part using Math::Algorithms::gramSchmidt() + * to prevent rounding errors when rotating the object subsequently. + */ + EuclideanMatrixTransformation2D* normalizeRotation() { + setTransformation(Math::Matrix3::from( + Math::Algorithms::gramSchmidt(_transformation.rotationScaling()), + _transformation.translation())); + return this; + } + /** @copydoc AbstractTranslationRotation2D::translate() */ inline EuclideanMatrixTransformation2D* translate(const Math::Vector2& vector, TransformationType type = TransformationType::Global) override { transform(Math::Matrix3::translation(vector), type); return this; } - /** @copydoc AbstractTranslationRotation2D::rotate() */ + /** + * @brief Rotate object + * @param angle Angle in radians, counterclockwise + * @param type Transformation type + * @return Pointer to self (for method chaining) + * + * @see deg(), rad(), normalizeRotation() + */ inline EuclideanMatrixTransformation2D* rotate(T angle, TransformationType type = TransformationType::Global) override { transform(Math::Matrix3::rotation(angle), type); return this; diff --git a/src/SceneGraph/EuclideanMatrixTransformation3D.h b/src/SceneGraph/EuclideanMatrixTransformation3D.h index 45e2ba8b0..d39dac91a 100644 --- a/src/SceneGraph/EuclideanMatrixTransformation3D.h +++ b/src/SceneGraph/EuclideanMatrixTransformation3D.h @@ -20,6 +20,7 @@ */ #include "Math/Matrix4.h" +#include "Math/Algorithms/GramSchmidt.h" #include "AbstractTranslationRotation3D.h" #include "Object.h" @@ -75,13 +76,36 @@ class EuclideanMatrixTransformation3D: public AbstractTranslationRotation3D { return this; } + /** + * @brief Normalize rotation part + * @return Pointer to self (for method chaining) + * + * Normalizes the rotation part using Math::Algorithms::gramSchmidt() + * to prevent rounding errors when rotating the object subsequently. + */ + EuclideanMatrixTransformation3D* normalizeRotation() { + setTransformation(Math::Matrix4::from( + Math::Algorithms::gramSchmidt(_transformation.rotationScaling()), + _transformation.translation())); + return this; + } + /** @copydoc AbstractTranslationRotation3D::translate() */ inline EuclideanMatrixTransformation3D* translate(const Math::Vector3& vector, TransformationType type = TransformationType::Global) override { transform(Math::Matrix4::translation(vector), type); return this; } - /** @copydoc AbstractTranslationRotation3D::rotate() */ + /** + * @brief Rotate object + * @param angle Angle in radians, counterclockwise + * @param normalizedAxis Normalized rotation axis + * @param type Transformation type + * @return Pointer to self (for method chaining) + * + * @see deg(), rad(), Vector3::xAxis(), Vector3::yAxis(), + * Vector3::zAxis(), normalizeRotation() + */ inline EuclideanMatrixTransformation3D* rotate(T angle, const Math::Vector3& normalizedAxis, TransformationType type = TransformationType::Global) override { transform(Math::Matrix4::rotation(angle, normalizedAxis), type); return this; @@ -93,7 +117,7 @@ class EuclideanMatrixTransformation3D: public AbstractTranslationRotation3D { * @param type Transformation type * @return Pointer to self (for method chaining) * - * @see deg(), rad() + * @see deg(), rad(), normalizeRotation() */ inline EuclideanMatrixTransformation3D* rotateX(T angle, TransformationType type = TransformationType::Global) override { transform(Math::Matrix4::rotationX(angle), type); @@ -106,7 +130,7 @@ class EuclideanMatrixTransformation3D: public AbstractTranslationRotation3D { * @param type Transformation type * @return Pointer to self (for method chaining) * - * @see deg(), rad() + * @see deg(), rad(), normalizeRotation() */ inline EuclideanMatrixTransformation3D* rotateY(T angle, TransformationType type = TransformationType::Global) override { transform(Math::Matrix4::rotationY(angle), type); @@ -119,7 +143,7 @@ class EuclideanMatrixTransformation3D: public AbstractTranslationRotation3D { * @param type Transformation type * @return Pointer to self (for method chaining) * - * @see deg(), rad() + * @see deg(), rad(), normalizeRotation() */ inline EuclideanMatrixTransformation3D* rotateZ(T angle, TransformationType type = TransformationType::Global) override { transform(Math::Matrix4::rotationZ(angle), type);