Browse Source

Math: preserve signs in the Matrix[34]::scaling() getter.

This is a breaking change, but I think it is worth doing. Because now

    Matrix4::scaling(vec).scaling() == vec

which was true also for translation and other.
mousecapture
Vladimír Vondruš 6 years ago
parent
commit
9aa68715db
  1. 10
      doc/changelog.dox
  2. 18
      src/Magnum/Math/Matrix3.h
  3. 22
      src/Magnum/Math/Matrix4.h
  4. 12
      src/Magnum/Math/Test/Matrix3Test.cpp
  5. 12
      src/Magnum/Math/Test/Matrix4Test.cpp

10
doc/changelog.dox

@ -127,6 +127,12 @@ See also:
in order to allow passing runtime-sized lists (see in order to allow passing runtime-sized lists (see
[mosra/magnum#403](https://github.com/mosra/magnum/pull/403)) [mosra/magnum#403](https://github.com/mosra/magnum/pull/403))
@subsubsection changelog-latest-changes-math Math library
- @ref Math::Matrix3::scaling() const and @ref Math::Matrix4::scaling() const
now return a signed scaling vector, taking into account negative scaling as
well
@subsubsection changelog-latest-changes-meshtools MeshTools library @subsubsection changelog-latest-changes-meshtools MeshTools library
- Added @ref MeshTools::subdivideInPlace() that operates on a partially - Added @ref MeshTools::subdivideInPlace() that operates on a partially
@ -223,6 +229,10 @@ See also:
@ref Animation library was changed to allow mutable access to the keys & @ref Animation library was changed to allow mutable access to the keys &
values it references. Existing code needs to be changed to say values it references. Existing code needs to be changed to say
@cpp TrackView<const K, const V> @ce instead of @cpp TrackView<K, V> @ce. @cpp TrackView<const K, const V> @ce instead of @cpp TrackView<K, V> @ce.
- @ref Math::Matrix3::scaling() const and @ref Math::Matrix4::scaling() const
now return a signed scaling vector instead of unsigned in order to prevent
information loss. To restore the old behavior, apply @ref Math::abs() on
the result.
- @ref Platform::GlfwApplication::setMinWindowSize() / - @ref Platform::GlfwApplication::setMinWindowSize() /
@ref Platform::GlfwApplication::setMaxWindowSize() and equivalent APIs in @ref Platform::GlfwApplication::setMaxWindowSize() and equivalent APIs in
@ref Platform::Sdl2Application now premultiply the value with @ref Platform::Sdl2Application now premultiply the value with

18
src/Magnum/Math/Matrix3.h

@ -430,11 +430,11 @@ template<class T> class Matrix3: public Matrix3x3<T> {
/** /**
* @brief Non-uniform scaling part of the matrix * @brief Non-uniform scaling part of the matrix
* *
* Length of vectors in upper-left 2x2 part of the matrix. Use the * *Signed* length of vectors in upper-left 2x2 part of the matrix. Use
* faster alternative @ref scalingSquared() where possible. Assuming * the faster alternative @ref scalingSquared() where possible.
* the following matrix, with the upper-left 2x2 part represented by * Assuming the following matrix, with the upper-left 2x2 part
* column vectors @f$ \boldsymbol{a} @f$ and @f$ \boldsymbol{b} @f$: * represented by column vectors @f$ \boldsymbol{a} @f$ and
* @f[ * @f$ \boldsymbol{b} @f$: @f[
* \begin{pmatrix} * \begin{pmatrix}
* \color{m-warning} a_x & \color{m-warning} b_x & t_x \\ * \color{m-warning} a_x & \color{m-warning} b_x & t_x \\
* \color{m-warning} a_y & \color{m-warning} b_y & t_y \\ * \color{m-warning} a_y & \color{m-warning} b_y & t_y \\
@ -446,8 +446,8 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* *
* the resulting scaling vector is: @f[ * the resulting scaling vector is: @f[
* \boldsymbol{s} = \begin{pmatrix} * \boldsymbol{s} = \begin{pmatrix}
* | \boldsymbol{a} | \\ * \operatorname{sgn}(a_x) | \boldsymbol{a} | \\
* | \boldsymbol{b} | * \operatorname{sgn}(a_y) | \boldsymbol{b} |
* \end{pmatrix} * \end{pmatrix}
* @f] * @f]
* *
@ -455,8 +455,8 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* @ref rotation() const, @ref Matrix4::scaling() const * @ref rotation() const, @ref Matrix4::scaling() const
*/ */
Vector2<T> scaling() const { Vector2<T> scaling() const {
return {(*this)[0].xy().length(), return {(*this)[0].xy().length()*T((*this)[0][0] < T(0) ? -1 : 1),
(*this)[1].xy().length()}; (*this)[1].xy().length()*T((*this)[1][1] < T(0) ? -1 : 1)};
} }
/** /**

22
src/Magnum/Math/Matrix4.h

@ -684,11 +684,11 @@ template<class T> class Matrix4: public Matrix4x4<T> {
/** /**
* @brief Non-uniform scaling part of the matrix * @brief Non-uniform scaling part of the matrix
* *
* Length of vectors in upper-left 3x3 part of the matrix. Use the * *Signed* length of vectors in upper-left 3x3 part of the matrix. Use
* faster alternative @ref scalingSquared() where possible. Assuming * the faster alternative @ref scalingSquared() where possible.
* the following matrix, with the upper-left 3x3 part represented by * Assuming the following matrix, with the upper-left 3x3 part
* column vectors @f$ \boldsymbol{a} @f$, @f$ \boldsymbol{b} @f$ and * represented by column vectors @f$ \boldsymbol{a} @f$,
* @f$ \boldsymbol{c} @f$: @f[ * @f$ \boldsymbol{b} @f$ and @f$ \boldsymbol{c} @f$: @f[
* \begin{pmatrix} * \begin{pmatrix}
* \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\ * \color{m-warning} a_x & \color{m-warning} b_x & \color{m-warning} c_x & t_x \\
* \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\ * \color{m-warning} a_y & \color{m-warning} b_y & \color{m-warning} c_y & t_y \\
@ -701,9 +701,9 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* *
* the resulting scaling vector is: @f[ * the resulting scaling vector is: @f[
* \boldsymbol{s} = \begin{pmatrix} * \boldsymbol{s} = \begin{pmatrix}
* | \boldsymbol{a} | \\ * \operatorname{sgn}(a_x) | \boldsymbol{a} | \\
* | \boldsymbol{b} | \\ * \operatorname{sgn}(b_y) | \boldsymbol{b} | \\
* | \boldsymbol{c} | * \operatorname{sgn}(c_z) | \boldsymbol{c} |
* \end{pmatrix} * \end{pmatrix}
* @f] * @f]
* *
@ -711,9 +711,9 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* @ref rotation() const, @ref Matrix3::scaling() const * @ref rotation() const, @ref Matrix3::scaling() const
*/ */
Vector3<T> scaling() const { Vector3<T> scaling() const {
return {(*this)[0].xyz().length(), return {(*this)[0].xyz().length()*T((*this)[0][0] < T(0) ? -1 : 1),
(*this)[1].xyz().length(), (*this)[1].xyz().length()*T((*this)[1][1] < T(0) ? -1 : 1),
(*this)[2].xyz().length()}; (*this)[2].xyz().length()*T((*this)[2][2] < T(0) ? -1 : 1)};
} }
/** /**

12
src/Magnum/Math/Test/Matrix3Test.cpp

@ -526,10 +526,18 @@ void Matrix3Test::scalingPart() {
Matrix3 translationRotationScaling = Matrix3 translationRotationScaling =
Matrix3::translation({2.0f, -3.0f})* Matrix3::translation({2.0f, -3.0f})*
Matrix3::rotation(15.0_degf)* Matrix3::rotation(15.0_degf)*
Matrix3::scaling({0.5f, 3.5f}); Matrix3::scaling({0.5f, -3.5f});
CORRADE_COMPARE(translationRotationScaling.scaling(), (Vector2{0.5f, 3.5f})); CORRADE_COMPARE(translationRotationScaling.scaling(), (Vector2{0.5f, -3.5f}));
CORRADE_COMPARE(translationRotationScaling.scalingSquared(), (Vector2{0.25f, 12.25f})); CORRADE_COMPARE(translationRotationScaling.scalingSquared(), (Vector2{0.25f, 12.25f}));
Matrix3 rotationScaling =
Matrix3::rotation(215.0_degf)*
Matrix3::scaling({-0.5f, 3.5f});
/* Sign inverted because of the rotation */
CORRADE_COMPARE(rotationScaling.scaling(), (Vector2{0.5f, -3.5f}));
CORRADE_COMPARE(rotationScaling.scalingSquared(), (Vector2{0.25f, 12.25f}));
} }
void Matrix3Test::uniformScalingPart() { void Matrix3Test::uniformScalingPart() {

12
src/Magnum/Math/Test/Matrix4Test.cpp

@ -760,10 +760,18 @@ void Matrix4Test::scalingPart() {
Matrix4 translationRotationScaling = Matrix4 translationRotationScaling =
Matrix4::translation({2.0f, 5.0f, -3.0f})* Matrix4::translation({2.0f, 5.0f, -3.0f})*
Matrix4::rotation(-74.0_degf, Vector3(-1.0f, 2.0f, 2.0f).normalized())* Matrix4::rotation(-74.0_degf, Vector3(-1.0f, 2.0f, 2.0f).normalized())*
Matrix4::scaling({0.5f, 3.5f, 1.2f}); Matrix4::scaling({0.5f, -3.5f, 1.2f});
CORRADE_COMPARE(translationRotationScaling.scaling(), (Vector3{0.5f, 3.5f, 1.2f})); CORRADE_COMPARE(translationRotationScaling.scaling(), (Vector3{0.5f, -3.5f, 1.2f}));
CORRADE_COMPARE(translationRotationScaling.scalingSquared(), (Vector3{0.25f, 12.25f, 1.44f})); CORRADE_COMPARE(translationRotationScaling.scalingSquared(), (Vector3{0.25f, 12.25f, 1.44f}));
Matrix4 rotationScaling =
Matrix4::rotation(-174.0_degf, Vector3(-1.0f, 2.0f, 2.0f).normalized())*
Matrix4::scaling({-0.5f, 3.5f, 1.2f});
/* Sign inverted because of the rotation */
CORRADE_COMPARE(rotationScaling.scaling(), (Vector3{0.5f, -3.5f, -1.2f}));
CORRADE_COMPARE(rotationScaling.scalingSquared(), (Vector3{0.25f, 12.25f, 1.44f}));
} }
void Matrix4Test::uniformScalingPart() { void Matrix4Test::uniformScalingPart() {

Loading…
Cancel
Save