Browse Source

Math: provide transformVector() also on the DualThing classes.

To make them more consistent with Matrix3/4, making switching from one
to the other easier.
pull/420/head
Vladimír Vondruš 6 years ago
parent
commit
c4a3b273e6
  1. 5
      doc/changelog.dox
  2. 13
      src/Magnum/Math/DualComplex.h
  3. 23
      src/Magnum/Math/DualQuaternion.h
  4. 13
      src/Magnum/Math/Test/DualComplexTest.cpp
  5. 38
      src/Magnum/Math/Test/DualQuaternionTest.cpp
  6. 1
      src/Magnum/Math/Test/QuaternionTest.cpp

5
doc/changelog.dox

@ -76,6 +76,11 @@ See also:
- Added @ref Math::Quaternion::toEuler() and documented how to convert Euler - Added @ref Math::Quaternion::toEuler() and documented how to convert Euler
angles to a quaternion (see [mosra/magnum#397](https://github.com/mosra/magnum/pull/397)) angles to a quaternion (see [mosra/magnum#397](https://github.com/mosra/magnum/pull/397))
- Added @ref Math::DualComplex::transformVector(),
@ref Math::DualQuaternion::transformVector(),
@ref Math::DualQuaternion::transformVectorNormalized() delegating to
respective APIs in the underlying @ref Complex / @ref Quaternion to make
the transformation API more consistent with @ref Matrix3 / @ref Matrix4
@subsubsection changelog-latest-new-platform Platform libraries @subsubsection changelog-latest-new-platform Platform libraries

13
src/Magnum/Math/DualComplex.h

@ -339,6 +339,17 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
return DualComplex<T>(Dual<Complex<T>>::real().invertedNormalized(), {{}, {}})*DualComplex<T>({}, -Dual<Complex<T>>::dual()); return DualComplex<T>(Dual<Complex<T>>::real().invertedNormalized(), {{}, {}})*DualComplex<T>({}, -Dual<Complex<T>>::dual());
} }
/**
* @brief Rotate a vector with a dual complex number
* @m_since_latest
*
* Calls @ref Complex::transformVector() on the @ref real() part,
* see its documentation for more information.
*/
Vector2<T> transformVector(const Vector2<T>& vector) const {
return Dual<Complex<T>>::real().transformVector(vector);
}
/** /**
* @brief Rotate and translate point with dual complex number * @brief Rotate and translate point with dual complex number
* *
@ -346,7 +357,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* v' = \hat c v = \hat c ((0 + i) + \epsilon(v_x + iv_y)) * v' = \hat c v = \hat c ((0 + i) + \epsilon(v_x + iv_y))
* @f] * @f]
* @see @ref DualComplex(const Vector2<T>&), @ref dual(), * @see @ref DualComplex(const Vector2<T>&), @ref dual(),
* @ref Matrix3::transformPoint(), @ref Complex::transformVector(), * @ref Matrix3::transformPoint(),
* @ref DualQuaternion::transformPoint() * @ref DualQuaternion::transformPoint()
*/ */
Vector2<T> transformPoint(const Vector2<T>& vector) const { Vector2<T> transformPoint(const Vector2<T>& vector) const {

23
src/Magnum/Math/DualQuaternion.h

@ -474,6 +474,28 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
return quaternionConjugated(); return quaternionConjugated();
} }
/**
* @brief Rotate a vector with a dual quaternion
* @m_since_latest
*
* Calls @ref Quaternion::transformVector() on the @ref real() part,
* see its documentation for more information.
*/
Vector3<T> transformVector(const Vector3<T>& vector) const {
return Dual<Quaternion<T>>::real().transformVector(vector);
}
/**
* @brief Rotate a vector with a normalized dual quaternion
* @m_since_latest
*
* Calls @ref Quaternion::transformVectorNormalized() on the
* @ref real() part, see its documentation for more information.
*/
Vector3<T> transformVectorNormalized(const Vector3<T>& vector) const {
return Dual<Quaternion<T>>::real().transformVectorNormalized(vector);
}
/** /**
* @brief Rotate and translate point with dual quaternion * @brief Rotate and translate point with dual quaternion
* *
@ -483,7 +505,6 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f] * @f]
* @see @ref DualQuaternion(const Vector3<T>&), @ref dual(), * @see @ref DualQuaternion(const Vector3<T>&), @ref dual(),
* @ref Matrix4::transformPoint(), * @ref Matrix4::transformPoint(),
* @ref Quaternion::transformVector(),
* @ref DualComplex::transformPoint() * @ref DualComplex::transformPoint()
*/ */
Vector3<T> transformPoint(const Vector3<T>& vector) const { Vector3<T> transformPoint(const Vector3<T>& vector) const {

13
src/Magnum/Math/Test/DualComplexTest.cpp

@ -90,6 +90,7 @@ struct DualComplexTest: Corrade::TestSuite::Tester {
void combinedTransformParts(); void combinedTransformParts();
void matrix(); void matrix();
void matrixNotOrthogonal(); void matrixNotOrthogonal();
void transformVector();
void transformPoint(); void transformPoint();
void strictWeakOrdering(); void strictWeakOrdering();
@ -147,6 +148,7 @@ DualComplexTest::DualComplexTest() {
&DualComplexTest::combinedTransformParts, &DualComplexTest::combinedTransformParts,
&DualComplexTest::matrix, &DualComplexTest::matrix,
&DualComplexTest::matrixNotOrthogonal, &DualComplexTest::matrixNotOrthogonal,
&DualComplexTest::transformVector,
&DualComplexTest::transformPoint, &DualComplexTest::transformPoint,
&DualComplexTest::strictWeakOrdering, &DualComplexTest::strictWeakOrdering,
@ -439,6 +441,17 @@ void DualComplexTest::matrixNotOrthogonal() {
" 0, 0, 2)\n"); " 0, 0, 2)\n");
} }
void DualComplexTest::transformVector() {
DualComplex a = Complex::rotation(23.0_degf);
Complex c = Complex::rotation(23.0_degf);
Vector2 v{-3.6f, 0.7f};
Vector2 rotated = a.transformVector(v);
/* Delegates to Complex, so should give the same result */
CORRADE_COMPARE(rotated, c.transformVector(v));
CORRADE_COMPARE(rotated, (Vector2{-3.58733f, -0.762279f}));
}
void DualComplexTest::transformPoint() { void DualComplexTest::transformPoint() {
DualComplex a = DualComplex::translation({2.0f, 3.0f})*DualComplex::rotation(Deg(23.0f)); DualComplex a = DualComplex::translation({2.0f, 3.0f})*DualComplex::rotation(Deg(23.0f));
DualComplex b = DualComplex::rotation(Deg(23.0f))*DualComplex::translation({2.0f, 3.0f}); DualComplex b = DualComplex::rotation(Deg(23.0f))*DualComplex::translation({2.0f, 3.0f});

38
src/Magnum/Math/Test/DualQuaternionTest.cpp

@ -92,6 +92,9 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester {
void combinedTransformParts(); void combinedTransformParts();
void matrix(); void matrix();
void matrixNotOrthogonal(); void matrixNotOrthogonal();
void transformVector();
void transformVectorNormalized();
void transformVectorNormalizedNotNormalized();
void transformPoint(); void transformPoint();
void transformPointNormalized(); void transformPointNormalized();
void transformPointNormalizedNotNormalized(); void transformPointNormalizedNotNormalized();
@ -154,6 +157,9 @@ DualQuaternionTest::DualQuaternionTest() {
&DualQuaternionTest::combinedTransformParts, &DualQuaternionTest::combinedTransformParts,
&DualQuaternionTest::matrix, &DualQuaternionTest::matrix,
&DualQuaternionTest::matrixNotOrthogonal, &DualQuaternionTest::matrixNotOrthogonal,
&DualQuaternionTest::transformVector,
&DualQuaternionTest::transformVectorNormalized,
&DualQuaternionTest::transformVectorNormalizedNotNormalized,
&DualQuaternionTest::transformPoint, &DualQuaternionTest::transformPoint,
&DualQuaternionTest::transformPointNormalized, &DualQuaternionTest::transformPointNormalized,
&DualQuaternionTest::transformPointNormalizedNotNormalized, &DualQuaternionTest::transformPointNormalizedNotNormalized,
@ -493,6 +499,38 @@ void DualQuaternionTest::matrixNotOrthogonal() {
" 0, 0, 0, 2)\n"); " 0, 0, 0, 2)\n");
} }
void DualQuaternionTest::transformVector() {
DualQuaternion a = DualQuaternion::rotation(23.0_degf, Vector3::xAxis());
Quaternion q = Quaternion::rotation(23.0_degf, Vector3::xAxis());
Vector3 v(5.0f, -3.6f, 0.7f);
Vector3 rotated = a.transformVector(v);
/* Delegates to Quaternion, so should give the same result */
CORRADE_COMPARE(rotated, q.transformVector(v));
CORRADE_COMPARE(rotated, (Vector3{5.0f, -3.58733f, -0.762279f}));
}
void DualQuaternionTest::transformVectorNormalized() {
DualQuaternion a = DualQuaternion::rotation(23.0_degf, Vector3::xAxis());
Quaternion q = Quaternion::rotation(23.0_degf, Vector3::xAxis());
Vector3 v(5.0f, -3.6f, 0.7f);
Vector3 rotated = a.transformVectorNormalized(v);
/* Delegates to Quaternion, so should give the same result */
CORRADE_COMPARE(rotated, q.transformVector(v));
CORRADE_COMPARE(rotated, a.transformVector(v));
}
void DualQuaternionTest::transformVectorNormalizedNotNormalized() {
std::ostringstream out;
Error redirectError{&out};
Quaternion a = Quaternion::rotation(23.0_degf, Vector3::xAxis());
(a*2).transformVectorNormalized({});
/* Delegates to quaternion, so the assert prints Quaternion */
CORRADE_COMPARE(out.str(), "Math::Quaternion::transformVectorNormalized(): Quaternion({0.398736, 0, 0}, 1.95985) is not normalized\n");
}
void DualQuaternionTest::transformPoint() { void DualQuaternionTest::transformPoint() {
DualQuaternion a = DualQuaternion::translation({-1.0f, 2.0f, 3.0f})*DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis()); DualQuaternion a = DualQuaternion::translation({-1.0f, 2.0f, 3.0f})*DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis());
DualQuaternion b = DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({-1.0f, 2.0f, 3.0f}); DualQuaternion b = DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({-1.0f, 2.0f, 3.0f});

1
src/Magnum/Math/Test/QuaternionTest.cpp

@ -744,6 +744,7 @@ void QuaternionTest::transformVectorNormalized() {
Quaternion a = Quaternion::rotation(Deg(23.0f), Vector3::xAxis()); Quaternion a = Quaternion::rotation(Deg(23.0f), Vector3::xAxis());
Matrix4 m = Matrix4::rotationX(Deg(23.0f)); Matrix4 m = Matrix4::rotationX(Deg(23.0f));
Vector3 v(5.0f, -3.6f, 0.7f); Vector3 v(5.0f, -3.6f, 0.7f);
Vector3 rotated = a.transformVectorNormalized(v); Vector3 rotated = a.transformVectorNormalized(v);
CORRADE_COMPARE(rotated, m.transformVector(v)); CORRADE_COMPARE(rotated, m.transformVector(v));
CORRADE_COMPARE(rotated, a.transformVector(v)); CORRADE_COMPARE(rotated, a.transformVector(v));

Loading…
Cancel
Save