Browse Source

Math: added uniform scaling extraction to Matrix[34].

pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
59be5e26f7
  1. 25
      src/Math/Matrix3.h
  2. 29
      src/Math/Matrix4.h
  3. 16
      src/Math/Test/Matrix3Test.cpp
  4. 16
      src/Math/Test/Matrix4Test.cpp

25
src/Math/Matrix3.h

@ -164,7 +164,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
*
* Upper-left 2x2 part of the matrix.
* @see from(const Matrix<2, T>&, const Vector2&), rotation() const
* rotationNormalized(), rotation(T),
* rotationNormalized(), @ref uniformScaling(), rotation(T),
* Matrix4::rotationScaling() const
*/
constexpr Matrix<2, T> rotationScaling() const {
@ -177,7 +177,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
*
* Similar to @ref rotationScaling(), but additionally checks that the
* base vectors are normalized.
* @see rotation() const, @ref Matrix4::rotationNormalized()
* @see rotation() const, @ref uniformScaling(),
* @ref Matrix4::rotationNormalized()
* @todo assert also orthogonality or this is good enough?
*/
Matrix<2, T> rotationNormalized() const {
@ -191,8 +192,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @brief 2D rotation part of the matrix
*
* Normalized upper-left 2x2 part of the matrix.
* @see rotationNormalized(), rotationScaling() const, rotation(T),
* Matrix4::rotation() const
* @see rotationNormalized(), rotationScaling(), @ref uniformScaling(),
* rotation(T), Matrix4::rotation() const
* @todo assert uniform scaling (otherwise this would be garbage)
*/
Matrix<2, T> rotation() const {
@ -200,7 +201,21 @@ template<class T> class Matrix3: public Matrix<3, T> {
(*this)[1].xy().normalized()};
}
/** @todo uniform scaling extraction */
/**
* @brief Uniform scaling part of the matrix
*
* Length of vectors in upper-left 2x2 part of the matrix. Expects that
* the scaling is the same in all axes.
* @see @ref rotationScaling(), @ref rotation(),
* @ref rotationNormalized(), @ref scaling(const Vector2&),
* @ref Matrix4::uniformScaling()
*/
T uniformScaling() const {
const T scalingSquared = (*this)[0].xy().dot();
CORRADE_ASSERT(TypeTraits<T>::equals((*this)[1].xy().dot(), scalingSquared),
"Math::Matrix3::uniformScaling(): the matrix doesn't have uniform scaling", {});
return std::sqrt(scalingSquared);
}
/**
* @brief Right-pointing 2D vector

29
src/Math/Matrix4.h

@ -227,8 +227,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
*
* Upper-left 3x3 part of the matrix.
* @see from(const Matrix<3, T>&, const Vector3&), rotation() const,
* rotationNormalized(), rotation(T, const Vector3&),
* Matrix3::rotationScaling() const
* rotationNormalized(), @ref uniformScaling(),
* rotation(T, const Vector3&), Matrix3::rotationScaling() const
*/
/* Not Matrix3, because it is for affine 2D transformations */
constexpr Matrix<3, T> rotationScaling() const {
@ -242,7 +242,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
*
* Similar to @ref rotationScaling(), but additionally checks that the
* base vectors are normalized.
* @see rotation() const, @ref Matrix3::rotationNormalized()
* @see rotation() const, @ref uniformScaling(),
* @ref Matrix3::rotationNormalized()
* @todo assert also orthogonality or this is good enough?
*/
/* Not Matrix3, because it is for affine 2D transformations */
@ -259,13 +260,23 @@ template<class T> class Matrix4: public Matrix<4, T> {
*
* Normalized upper-left 3x3 part of the matrix.
* @see rotationNormalized(), rotationScaling() const,
* rotation(T, const Vector3&), Matrix3::rotation() const
* @ref uniformScaling(), rotation(T, const Vector3&),
* Matrix3::rotation() const
* @todo assert uniform scaling (otherwise this would be garbage)
*/
/* Not Matrix3, because it is for affine 2D transformations */
Matrix<3, T> rotation() const;
/** @todo uniform scaling extraction */
/**
* @brief Uniform scaling part of the matrix
*
* Length of vectors in upper-left 3x3 part of the matrix. Expects that
* the scaling is the same in all axes.
* @see @ref rotationScaling(), @ref rotation(),
* @ref rotationNormalized(), @ref scaling(const Vector3&),
* @ref Matrix3::uniformScaling()
*/
T uniformScaling() const;
/**
* @brief Right-pointing 3D vector
@ -446,6 +457,14 @@ template<class T> inline Matrix<3, T> Matrix4<T>::rotation() const {
(*this)[2].xyz().normalized()};
}
template<class T> T Matrix4<T>::uniformScaling() const {
const T scalingSquared = (*this)[0].xyz().dot();
CORRADE_ASSERT(TypeTraits<T>::equals((*this)[1].xyz().dot(), scalingSquared) &&
TypeTraits<T>::equals((*this)[2].xyz().dot(), scalingSquared),
"Math::Matrix4::uniformScaling(): the matrix doesn't have uniform scaling", {});
return std::sqrt(scalingSquared);
}
template<class T> Matrix4<T> Matrix4<T>::invertedRigid() const {
CORRADE_ASSERT(isRigidTransformation(),
"Math::Matrix4::invertedRigid(): the matrix doesn't represent rigid transformation", {});

16
src/Math/Test/Matrix3Test.cpp

@ -78,6 +78,7 @@ class Matrix3Test: public Corrade::TestSuite::Tester {
void rotationScalingPart();
void rotationNormalizedPart();
void rotationPart();
void uniformScalingPart();
void vectorParts();
void invertedRigid();
void transform();
@ -113,6 +114,7 @@ Matrix3Test::Matrix3Test() {
&Matrix3Test::rotationScalingPart,
&Matrix3Test::rotationNormalizedPart,
&Matrix3Test::rotationPart,
&Matrix3Test::uniformScalingPart,
&Matrix3Test::vectorParts,
&Matrix3Test::invertedRigid,
&Matrix3Test::transform,
@ -334,6 +336,20 @@ void Matrix3Test::rotationPart() {
}
}
void Matrix3Test::uniformScalingPart() {
const Matrix3 rotation = Matrix3::rotation(Deg(-74.0f));
/* Test uniform scaling */
CORRADE_COMPARE((rotation*Matrix3::scaling(Vector2(3.0f))).uniformScaling(), 3.0f);
/* Fails on non-uniform scaling */
std::ostringstream o;
Error::setOutput(&o);
const Float nonUniformScaling = (rotation*Matrix3::scaling(Vector2::yScale(3.0f))).uniformScaling();
CORRADE_COMPARE(o.str(), "Math::Matrix3::uniformScaling(): the matrix doesn't have uniform scaling\n");
CORRADE_COMPARE(nonUniformScaling, 0.0f);
}
void Matrix3Test::vectorParts() {
constexpr Matrix3 a({15.0f, 0.0f, 0.0f},
{ 0.0f, -3.0f, 0.0f},

16
src/Math/Test/Matrix4Test.cpp

@ -85,6 +85,7 @@ class Matrix4Test: public Corrade::TestSuite::Tester {
void rotationScalingPart();
void rotationNormalizedPart();
void rotationPart();
void uniformScalingPart();
void vectorParts();
void invertedRigid();
void transform();
@ -125,6 +126,7 @@ Matrix4Test::Matrix4Test() {
&Matrix4Test::rotationScalingPart,
&Matrix4Test::rotationNormalizedPart,
&Matrix4Test::rotationPart,
&Matrix4Test::uniformScalingPart,
&Matrix4Test::vectorParts,
&Matrix4Test::invertedRigid,
&Matrix4Test::transform,
@ -420,6 +422,20 @@ void Matrix4Test::rotationPart() {
}
}
void Matrix4Test::uniformScalingPart() {
const Matrix4 rotation = Matrix4::rotation(Deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized());
/* Test uniform scaling */
CORRADE_COMPARE((rotation*Matrix4::scaling(Vector3(3.0f))).uniformScaling(), 3.0f);
/* Fails on non-uniform scaling */
std::ostringstream o;
Error::setOutput(&o);
const Float nonUniformScaling = (rotation*Matrix4::scaling(Vector3::yScale(3.0f))).uniformScaling();
CORRADE_COMPARE(o.str(), "Math::Matrix4::uniformScaling(): the matrix doesn't have uniform scaling\n");
CORRADE_COMPARE(nonUniformScaling, 0.0f);
}
void Matrix4Test::vectorParts() {
constexpr Matrix4 a({-1.0f, 0.0f, 0.0f, 0.0f},
{ 0.0f, 12.0f, 0.0f, 0.0f},

Loading…
Cancel
Save