From e3e61d8865fa8066f2982d3b08100e29d0a4863e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 12 Oct 2018 19:21:48 +0200 Subject: [PATCH] Math: ability to multiply/divide a Complex with a Vector2. --- doc/changelog.dox | 3 ++ src/Magnum/Math/Complex.h | 75 +++++++++++++++++++++++++++- src/Magnum/Math/Test/ComplexTest.cpp | 15 ++++++ 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index a3cf253a9..5e5ffe45e 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -120,6 +120,9 @@ See also: @ref Math::Complex::imaginary(), @ref Math::Dual::real(), @ref Math::Dual::dual(), @ref Math::Quaternion::vector() and @ref Math::Quaternion::scalar() +- Ability to do a component-wise multiply and divide of @ref Math::Complex + and a @ref Math::Vector2, in addition to multiplication/division with a + scalar - Ability to use @ref Math::Complex, @ref Math::DualComplex, @ref Math::Quaternion, @ref Math::DualQuaternion with @ref Corrade::Utility::Configuration and @ref Corrade::Utility::Arguments diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index 4d24aa169..5377f94bf 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -322,6 +322,7 @@ template class Complex { * The computation is done in-place. @f[ * c t = a t + i b t * @f] + * @see @ref operator*=(const Vector2&) */ Complex& operator*=(T scalar) { _real *= scalar; @@ -330,20 +331,45 @@ template class Complex { } /** - * @brief Multiply with a scalar + * @brief Multiply with a vector and assign * + * The computation is done in-place. @f[ + * c \boldsymbol{v} = a v_x + i b v_y + * @f] * @see @ref operator*=(T) */ + Complex& operator*=(const Vector2& vector) { + _real *= vector.x(); + _imaginary *= vector.y(); + return *this; + } + + /** + * @brief Multiply with a scalar + * + * @see @ref operator*=(T), @ref operator*(const Vector2&) const, + * @ref operator*(const Complex&) const + */ Complex operator*(T scalar) const { return Complex(*this) *= scalar; } + /** + * @brief Multiply with a vector + * + * @see @ref operator*=(const Vector2&) + */ + Complex operator*(const Vector2& vector) const { + return Complex(*this) *= vector; + } + /** * @brief Divide with a scalar and assign * * The computation is done in-place. @f[ * \frac{c}{t} = \frac{a}{t} + i \frac{b}{t} * @f] + * @see @ref operator/=(const Vector2&) */ Complex& operator/=(T scalar) { _real /= scalar; @@ -352,20 +378,44 @@ template class Complex { } /** - * @brief Divide with a scalar + * @brief Divide with a vector and assign * + * The computation is done in-place. @f[ + * c \boldsymbol{v} = \frac{a}{v_x} + i \frac{b}{v_y} + * @f] * @see @ref operator/=(T) */ + Complex& operator/=(const Vector2& vector) { + _real /= vector.x(); + _imaginary /= vector.y(); + return *this; + } + + /** + * @brief Divide with a scalar + * + * @see @ref operator/=(T), @ref operator/(const Vector2&) const + */ Complex operator/(T scalar) const { return Complex(*this) /= scalar; } + /** + * @brief Divide with a vector + * + * @see @ref operator/=(const Vector2&), @ref operator/(T) const + */ + Complex operator/(const Vector2& vector) const { + return Complex(*this) /= vector; + } + /** * @brief Multiply with a complex number * * @f[ * c_0 c_1 = (a_0 + ib_0)(a_1 + ib_1) = (a_0 a_1 - b_0 b_1) + i(a_1 b_0 + a_0 b_1) * @f] + * @see @ref operator*(const Vector2& other) const */ Complex operator*(const Complex& other) const { return {_real*other._real - _imaginary*other._imaginary, @@ -473,6 +523,15 @@ template inline Complex operator*(T scalar, const Complex& comple return complex*scalar; } +/** @relatesalso Complex +@brief Multiply a vector with a complex number + +Same as @ref Complex::operator*(const Vector2&) const. +*/ +template inline Complex operator*(const Vector2& vector, const Complex& complex) { + return complex*vector; +} + /** @relates Complex @brief Divide a complex number with a scalar and invert @@ -485,6 +544,18 @@ template inline Complex operator/(T scalar, const Complex& comple return {scalar/complex.real(), scalar/complex.imaginary()}; } +/** @relates Complex +@brief Divide a complex number with a vector and invert + +@f[ + \frac{\boldsymbol{v}}{c} = \frac{v_x}{a} + i \frac{v_y}{b} +@f] +@see @ref Complex::operator/() +*/ +template inline Complex operator/(const Vector2& vector, const Complex& complex) { + return {vector.x()/complex.real(), vector.y()/complex.imaginary()}; +} + /** @relatesalso Complex @brief Linear interpolation of two complex numbers @param normalizedA First complex number diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index 88aaa3cdb..a097aa80e 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -73,6 +73,7 @@ struct ComplexTest: Corrade::TestSuite::Tester { void addSubtract(); void negated(); void multiplyDivideScalar(); + void multiplyDivideVector(); void multiply(); void dot(); @@ -118,6 +119,7 @@ ComplexTest::ComplexTest() { &ComplexTest::addSubtract, &ComplexTest::negated, &ComplexTest::multiplyDivideScalar, + &ComplexTest::multiplyDivideVector, &ComplexTest::multiply, &ComplexTest::dot, @@ -318,6 +320,19 @@ void ComplexTest::multiplyDivideScalar() { CORRADE_COMPARE(-2.0f/a, c); } +void ComplexTest::multiplyDivideVector() { + Complex a{ 2.5f, -0.5f}; + Vector2 b{-3.0f, 0.8f}; + Complex c{-7.5f, -0.4f}; + + CORRADE_COMPARE(a*b, c); + CORRADE_COMPARE(b*a, c); + CORRADE_COMPARE(c/b, a); + + Complex d(-0.8f, -3.2f); + CORRADE_COMPARE((Vector2{-2.0f, 1.6f}/a), d); +} + void ComplexTest::multiply() { Complex a( 5.0f, 3.0f); Complex b( 6.0f, -7.0f);