Browse Source

Math: added convenience functions {Complex,DualComplex}::isNormalized().

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
1790f37295
  1. 29
      src/Math/Complex.h
  2. 15
      src/Math/DualComplex.h
  3. 9
      src/Math/Test/ComplexTest.cpp
  4. 9
      src/Math/Test/DualComplexTest.cpp

29
src/Math/Complex.h

@ -75,10 +75,10 @@ template<class T> class Complex {
* 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()
* @see isNormalized(), Quaternion::angle(), Vector::angle()
*/
inline static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(),
"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));
}
@ -147,6 +147,18 @@ template<class T> class Complex {
return !operator==(other);
}
/**
* @brief Whether the complex number is normalized
*
* Complex number is normalized if it has unit length: @f[
* |c|^2 = |c| = 1
* @f]
* @see dot(), normalized()
*/
inline bool isNormalized() const {
return TypeTraits<T>::equals(dot(), T(1));
}
/** @brief Real part */
inline constexpr T real() const { return _real; }
@ -311,7 +323,7 @@ template<class T> class Complex {
* with other values, because it doesn't compute the square root. @f[
* c \cdot c = a^2 + b^2
* @f]
* @see dot(const Complex&, const Complex&)
* @see dot(const Complex&, const Complex&), isNormalized()
*/
inline T dot() const {
return dot(*this, *this);
@ -324,12 +336,17 @@ template<class T> class Complex {
* values. @f[
* |c| = \sqrt{c \cdot c}
* @f]
* @see isNormalized()
*/
inline T length() const {
return std::hypot(_real, _imaginary);
}
/** @brief Normalized complex number (of unit length) */
/**
* @brief Normalized complex number (of unit length)
*
* @see isNormalized()
*/
inline Complex<T> normalized() const {
return (*this)/length();
}
@ -364,10 +381,10 @@ template<class T> class Complex {
* normalized. @f[
* c^{-1} = \frac{c^*}{c \cdot c} = c^*
* @f]
* @see inverted()
* @see isNormalized(), inverted()
*/
inline Complex<T> invertedNormalized() const {
CORRADE_ASSERT(TypeTraits<T>::equals(dot(), T(1)),
CORRADE_ASSERT(isNormalized(),
"Math::Complex::invertedNormalized(): complex number must be normalized",
Complex<T>(std::numeric_limits<T>::quiet_NaN(), {}));
return conjugated();

15
src/Math/DualComplex.h

@ -126,6 +126,18 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
inline constexpr explicit DualComplex(const Vector2<T>& vector): Dual<Complex<T>>({}, Complex<T>(vector)) {}
#endif
/**
* @brief Whether the dual complex number is normalized
*
* Dual complex number is normalized if its real part has unit length: @f[
* |c_0|^2 = |c_0| = 1
* @f]
* @see Complex::dot(), normalized()
*/
inline bool isNormalized() const {
return TypeTraits<T>::equals(this->real().dot(), T(1));
}
/**
* @brief Rotation angle of dual complex number
*
@ -240,6 +252,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f[
* c' = \frac{c_0}{|c_0|}
* @f]
* @see isNormalized()
* @todo can this be done similarly to dual quaternions?
*/
inline DualComplex<T> normalized() const {
@ -265,7 +278,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Expects that the complex number is normalized. @f[
* \hat c^{-1} = c_0^{-1} - \epsilon c_\epsilon = c_0^* - \epsilon c_\epsilon
* @f]
* @see inverted()
* @see isNormalized(), inverted()
* @todo can this be done similarly to dual quaternions?
*/
inline DualComplex<T> invertedNormalized() const {

9
src/Math/Test/ComplexTest.cpp

@ -37,7 +37,9 @@ class ComplexTest: public Corrade::TestSuite::Tester {
void construct();
void constructDefault();
void constructFromVector();
void compare();
void isNormalized();
void constExpressions();
@ -67,7 +69,9 @@ ComplexTest::ComplexTest() {
addTests({&ComplexTest::construct,
&ComplexTest::constructDefault,
&ComplexTest::constructFromVector,
&ComplexTest::compare,
&ComplexTest::isNormalized,
&ComplexTest::constExpressions,
@ -126,6 +130,11 @@ void ComplexTest::compare() {
CORRADE_VERIFY(Complex(1.0f+TypeTraits<Float>::epsilon()*2, 3.7f) != Complex(1.0f, 3.7f));
}
void ComplexTest::isNormalized() {
CORRADE_VERIFY(!Complex(2.5f, -3.7f).isNormalized());
CORRADE_VERIFY(Complex::rotation(Deg(23.0f)).isNormalized());
}
void ComplexTest::constExpressions() {
/* Default constructor */
constexpr Complex a;

9
src/Math/Test/DualComplexTest.cpp

@ -38,6 +38,8 @@ class DualComplexTest: public Corrade::TestSuite::Tester {
void constructDefault();
void constructFromVector();
void isNormalized();
void constExpressions();
void multiply();
@ -74,6 +76,8 @@ DualComplexTest::DualComplexTest() {
&DualComplexTest::constructDefault,
&DualComplexTest::constructFromVector,
&DualComplexTest::isNormalized,
&DualComplexTest::constExpressions,
&DualComplexTest::multiply,
@ -112,6 +116,11 @@ void DualComplexTest::constructFromVector() {
CORRADE_COMPARE(DualComplex(Vector2(1.5f, -3.0f)), DualComplex({1.0f, 0.0f}, {1.5f, -3.0f}));
}
void DualComplexTest::isNormalized() {
CORRADE_VERIFY(!DualComplex({2.0f, 1.0f}, {}).isNormalized());
CORRADE_VERIFY((DualComplex::rotation(Deg(23.0f))*DualComplex::translation({6.0f, 3.0f})).isNormalized());
}
void DualComplexTest::constExpressions() {
/* Default constructor */
constexpr DualComplex a;

Loading…
Cancel
Save