From b8f09a0616c7b1b72ff78943dd182908b1c1079c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 6 Mar 2012 00:24:07 +0100 Subject: [PATCH] Added arithmetic assign operators to Matrix and Vector. Multiplication, division, addition and substraction is now done primarily in assigning operators, as they do the computations in-place, so they are more memory efficient than implementing them using e.g. `*this = *this+other;`. Updated unit test only for matrix multiplication, as vector unit tests test arithmetic asssign operators too. --- src/Math/Matrix.h | 5 +++ src/Math/Matrix3.h | 6 ++++ src/Math/Matrix4.h | 6 ++++ src/Math/Test/MatrixTest.cpp | 2 +- src/Math/Vector.h | 68 +++++++++++++++++++++++++----------- src/Math/Vector2.h | 24 +++++++++++++ src/Math/Vector3.h | 24 +++++++++++++ src/Math/Vector4.h | 24 +++++++++++++ 8 files changed, 138 insertions(+), 21 deletions(-) diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index d614cbeb0..af1066b99 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -144,6 +144,11 @@ template class Matrix { return out; } + /** @brief Multiply and assign matrix operator */ + inline Matrix& operator*=(const Matrix& other) { + return (*this = *this*other); + } + /** @brief Multiply vector operator */ Vector operator*(const Vector& other) const { Vector out; diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index 65808314b..90d36471e 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -58,6 +58,12 @@ template class Matrix3: public Matrix { /** @copydoc Matrix::operator*(const Matrix&) const */ inline Matrix3 operator*(const Matrix& other) const { return Matrix::operator*(other); } + /** @copydoc Matrix::operator*=() */ + inline Matrix3& operator*=(const Matrix& other) { + Matrix::operator*=(other); + return *this; + } + /** @copydoc Matrix::operator*(const Vector&) const */ inline Vector3 operator*(const Vector& other) const { return Matrix::operator*(other); } diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 1c6c8e7af..8699336d1 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -124,6 +124,12 @@ template class Matrix4: public Matrix { /** @copydoc Matrix::operator*(const Matrix&) const */ inline Matrix4 operator*(const Matrix& other) const { return Matrix::operator*(other); } + /** @copydoc Matrix::operator*=() */ + inline Matrix4& operator*=(const Matrix& other) { + Matrix::operator*=(other); + return *this; + } + /** @copydoc Matrix::operator*(const Vector&) const */ inline Vector4 operator*(const Vector& other) const { return Matrix::operator*(other); } diff --git a/src/Math/Test/MatrixTest.cpp b/src/Math/Test/MatrixTest.cpp index 928fc058a..da467fe47 100644 --- a/src/Math/Test/MatrixTest.cpp +++ b/src/Math/Test/MatrixTest.cpp @@ -158,7 +158,7 @@ void MatrixTest::multiply() { -12, 8, -20, -26, -2 ); - QVERIFY(left*right == expected); + QVERIFY((left *= right) == expected); } void MatrixTest::multiplyVector() { diff --git a/src/Math/Vector.h b/src/Math/Vector.h index d18b4562d..1a9f152fd 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -124,43 +124,71 @@ template class Vector { } /** @brief Multiply vector */ - Vector operator*(T number) const { - Vector out; + inline Vector operator*(T number) const { + return Vector(*this)*=number; + } + /** + * @brief Multiply and assign vector + * + * More efficient than operator*(), because it does the computation + * in-place. + */ + Vector& operator*=(T number) { for(size_t i = 0; i != size; ++i) - out.set(i, at(i)*number); - - return out; + set(i, at(i)*number); + return *this; } /** @brief Divide vector */ - Vector operator/(T number) const { - Vector out; + inline Vector operator/(T number) const { + return Vector(*this)/=number; + } + /** + * @brief Divide and assign vector + * + * More efficient than operator/(), because it does the computation + * in-place. + */ + Vector& operator/=(T number) { for(size_t i = 0; i != size; ++i) - out.set(i, at(i)/number); - - return out; + set(i, at(i)/number); + return *this; } /** @brief Add two vectors */ - Vector operator+(const Vector& other) const { - Vector out; + inline Vector operator+(const Vector& other) const { + return Vector(*this)+=other; + } + /** + * @brief Add and assign vector + * + * More efficient than operator+(), because it does the computation + * in-place. + */ + Vector& operator+=(const Vector& other) { for(size_t i = 0; i != size; ++i) - out.set(i, at(i)+other.at(i)); - - return out; + set(i, at(i)+other.at(i)); + return *this; } /** @brief Substract two vectors */ - Vector operator-(const Vector& other) const { - Vector out; + inline Vector operator-(const Vector& other) const { + return Vector(*this)-=other; + } + /** + * @brief Substract and assign vector + * + * More efficient than operator-(), because it does the computation + * in-place. + */ + Vector& operator-=(const Vector& other) { for(size_t i = 0; i != size; ++i) - out.set(i, at(i)-other.at(i)); - - return out; + set(i, at(i)-other.at(i)); + return *this; } /** @brief Negative vector */ diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index 3ef6c8ff4..8d48ea289 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -57,15 +57,39 @@ template class Vector2: public Vector { /** @copydoc Vector::operator*(T) const */ inline Vector2 operator*(T number) const { return Vector::operator*(number); } + /** @copydoc Vector::operator*=() */ + inline Vector2& operator*=(T number) { + Vector::operator*=(number); + return *this; + } + /** @copydoc Vector::operator/() */ inline Vector2 operator/(T number) const { return Vector::operator/(number); } + /** @copydoc Vector::operator/=() */ + inline Vector2& operator/=(T number) { + Vector::operator/=(number); + return *this; + } + /** @copydoc Vector::operator+() */ inline Vector2 operator+(const Vector& other) const { return Vector::operator+(other); } + /** @copydoc Vector::operator+=() */ + inline Vector2& operator+=(const Vector& other) { + Vector::operator+=(other); + return *this; + } + /** @copydoc Vector::operator-(const Vector&) const */ inline Vector2 operator-(const Vector& other) const { return Vector::operator-(other); } + /** @copydoc Vector::operator-=() */ + inline Vector2& operator-=(const Vector& other) { + Vector::operator-=(other); + return *this; + } + /** @copydoc Vector::operator-() */ inline Vector2 operator-() const { return Vector::operator-(); } diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index 7f8c52562..59d040e8f 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -91,15 +91,39 @@ template class Vector3: public Vector { /** @copydoc Vector::operator*(T) const */ inline Vector3 operator*(T number) const { return Vector::operator*(number); } + /** @copydoc Vector::operator*=() */ + inline Vector3& operator*=(T number) { + Vector::operator*=(number); + return *this; + } + /** @copydoc Vector::operator/() */ inline Vector3 operator/(T number) const { return Vector::operator/(number); } + /** @copydoc Vector::operator/=() */ + inline Vector3& operator/=(T number) { + Vector::operator/=(number); + return *this; + } + /** @copydoc Vector::operator+() */ inline Vector3 operator+(const Vector& other) const { return Vector::operator+(other); } + /** @copydoc Vector::operator+=() */ + inline Vector3& operator+=(const Vector& other) { + Vector::operator+=(other); + return *this; + } + /** @copydoc Vector::operator-(const Vector&) const */ inline Vector3 operator-(const Vector& other) const { return Vector::operator-(other); } + /** @copydoc Vector::operator-=() */ + inline Vector3& operator-=(const Vector& other) { + Vector::operator-=(other); + return *this; + } + /** @copydoc Vector::operator-() */ inline Vector3 operator-() const { return Vector::operator-(); } diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index 4f01f29c4..3ba586d2d 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -98,15 +98,39 @@ template class Vector4: public Vector { /** @copydoc Vector::operator*(T) const */ inline Vector4 operator*(T number) const { return Vector::operator*(number); } + /** @copydoc Vector::operator*=() */ + inline Vector4& operator*=(T number) { + Vector::operator*=(number); + return *this; + } + /** @copydoc Vector::operator/() */ inline Vector4 operator/(T number) const { return Vector::operator/(number); } + /** @copydoc Vector::operator/=() */ + inline Vector4& operator/=(T number) { + Vector::operator/=(number); + return *this; + } + /** @copydoc Vector::operator+() */ inline Vector4 operator+(const Vector& other) const { return Vector::operator+(other); } + /** @copydoc Vector::operator+=() */ + inline Vector4& operator+=(const Vector& other) { + Vector::operator+=(other); + return *this; + } + /** @copydoc Vector::operator-(const Vector&) const */ inline Vector4 operator-(const Vector& other) const { return Vector::operator-(other); } + /** @copydoc Vector::operator-=() */ + inline Vector4& operator-=(const Vector& other) { + Vector::operator-=(other); + return *this; + } + /** @copydoc Vector::operator-() */ inline Vector4 operator-() const { return Vector::operator-(); }