Browse Source

Math: angle between two complex numbers.

Also crosslinked the documentation with similar functions in Vector and
Quaternion.
pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
4ebd204482
  1. 15
      src/Math/Complex.h
  2. 1
      src/Math/Quaternion.h
  3. 27
      src/Math/Test/ComplexTest.cpp
  4. 11
      src/Math/Test/QuaternionTest.cpp
  5. 1
      src/Math/Vector.h

15
src/Math/Complex.h

@ -23,6 +23,7 @@
#include <Utility/Assert.h>
#include <Utility/Debug.h>
#include "Math/Angle.h"
#include "Math/MathTypeTraits.h"
#include "magnumVisibility.h"
@ -51,6 +52,20 @@ template<class T> class Complex {
return a*b.conjugated();
}
/**
* @brief Angle between normalized complex numbers
*
* Expects that both complex numbers are normalized. @f[
* \theta = acos \left( \frac{Re(c_0 \cdot c_1))}{|c_0| |c_1|} \right) = acos (a_0 a_1 + b_0 b_1)
* @f]
* @see Quaternion::angle(), Vector::angle()
*/
inline static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)),
"Math::Complex::angle(): complex numbers must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(std::acos(normalizedA._real*normalizedB._real + normalizedA._imaginary*normalizedB._imaginary));
}
/**
* @brief Default constructor
*

1
src/Math/Quaternion.h

@ -59,6 +59,7 @@ template<class T> class Quaternion {
* Expects that both quaternions are normalized. @f[
* \theta = acos \left( \frac{p \cdot q}{|p| |q|} \right) = acos(p \cdot q)
* @f]
* @see Complex::angle(), Vector::angle()
*/
inline static Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)),

27
src/Math/Test/ComplexTest.cpp

@ -17,6 +17,7 @@
#include <TestSuite/Tester.h>
#include "Math/Complex.h"
#include "Math/Vector2.h"
namespace Magnum { namespace Math { namespace Test {
@ -44,6 +45,8 @@ class ComplexTest: public Corrade::TestSuite::Tester {
void inverted();
void invertedNormalized();
void angle();
void debug();
};
@ -68,10 +71,14 @@ ComplexTest::ComplexTest() {
&ComplexTest::inverted,
&ComplexTest::invertedNormalized,
&ComplexTest::angle,
&ComplexTest::debug);
}
typedef Math::Rad<float> Rad;
typedef Math::Complex<float> Complex;
typedef Math::Vector2<float> Vector2;
void ComplexTest::construct() {
Complex c(0.5f, -3.7f);
@ -201,6 +208,26 @@ void ComplexTest::invertedNormalized() {
CORRADE_COMPARE(inverted, b);
}
void ComplexTest::angle() {
std::ostringstream o;
Error::setOutput(&o);
auto angle = Complex::angle(Complex(1.5f, -2.0f).normalized(), {-4.0f, 3.5f});
CORRADE_VERIFY(angle != angle);
CORRADE_COMPARE(o.str(), "Math::Complex::angle(): complex numbers must be normalized\n");
o.str({});
angle = Complex::angle({1.5f, -2.0f}, Complex(-4.0f, 3.5f).normalized());
CORRADE_VERIFY(angle != angle);
CORRADE_COMPARE(o.str(), "Math::Complex::angle(): complex numbers must be normalized\n");
/* Verify also that the angle is the same as angle between 2D vectors */
angle = Complex::angle(Complex( 1.5f, -2.0f).normalized(),
Complex(-4.0f, 3.5f).normalized());
CORRADE_COMPARE(angle, Vector2::angle(Vector2( 1.5f, -2.0f).normalized(),
Vector2(-4.0f, 3.5f).normalized()));
CORRADE_COMPARE(angle, Rad(2.933128f));
}
void ComplexTest::debug() {
std::ostringstream o;

11
src/Math/Test/QuaternionTest.cpp

@ -253,7 +253,7 @@ void QuaternionTest::rotation() {
void QuaternionTest::angle() {
std::ostringstream o;
Corrade::Utility::Error::setOutput(&o);
Error::setOutput(&o);
auto angle = Quaternion::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(), {{4.0f, -3.0f, 2.0f}, -1.0f});
CORRADE_VERIFY(angle != angle);
CORRADE_COMPARE(o.str(), "Math::Quaternion::angle(): quaternions must be normalized\n");
@ -263,9 +263,12 @@ void QuaternionTest::angle() {
CORRADE_VERIFY(angle != angle);
CORRADE_COMPARE(o.str(), "Math::Quaternion::angle(): quaternions must be normalized\n");
CORRADE_COMPARE(Quaternion::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(),
Quaternion({4.0f, -3.0f, 2.0f}, -1.0f).normalized()),
Rad(1.704528f));
/* Verify also that the angle is the same as angle between 4D vectors */
angle = Quaternion::angle(Quaternion({1.0f, 2.0f, -3.0f}, -4.0f).normalized(),
Quaternion({4.0f, -3.0f, 2.0f}, -1.0f).normalized());
CORRADE_COMPARE(angle, Vector4::angle(Vector4(1.0f, 2.0f, -3.0f, -4.0f).normalized(),
Vector4(4.0f, -3.0f, 2.0f, -1.0f).normalized()));
CORRADE_COMPARE(angle, Rad(1.704528f));
}
void QuaternionTest::matrix() {

1
src/Math/Vector.h

@ -84,6 +84,7 @@ template<std::size_t size, class T> class Vector {
* Expects that both vectors are normalized. @f[
* \theta = acos \left( \frac{\boldsymbol a \cdot \boldsymbol b}{|\boldsymbol a| |\boldsymbol b|} \right) = acos (\boldsymbol a \cdot \boldsymbol b)
* @f]
* @see Quaternion::angle(), Complex::angle()
*/
inline static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)),

Loading…
Cancel
Save