diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index a07b3d345..d274b5af5 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -56,6 +56,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void maxAbs(); void projected(); + void projectedOntoNormalized(); void angle(); void lerp(); @@ -98,6 +99,7 @@ VectorTest::VectorTest() { &VectorTest::maxAbs, &VectorTest::projected, + &VectorTest::projectedOntoNormalized, &VectorTest::angle, &VectorTest::lerp, @@ -286,6 +288,22 @@ void VectorTest::projected() { CORRADE_COMPARE(projected.normalized(), line.normalized()); } +void VectorTest::projectedOntoNormalized() { + std::ostringstream o; + Error::setOutput(&o); + + Vector3 vector(1.0f, 2.0f, 3.0f); + Vector3 line(1.0f, -1.0f, 0.5f); + Vector3 projected = vector.projectedOntoNormalized(line); + CORRADE_VERIFY(projected != projected); + CORRADE_COMPARE(o.str(), "Math::Vector::projectedOntoNormalized(): line must be normalized\n"); + + projected = vector.projectedOntoNormalized(line.normalized()); + CORRADE_COMPARE(projected, Vector3(0.222222f, -0.222222f, 0.111111f)); + CORRADE_COMPARE(projected.normalized(), line.normalized()); + CORRADE_COMPARE(projected, vector.projected(line)); +} + void VectorTest::angle() { std::ostringstream o; Error::setOutput(&o); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 6744acb13..977ed935b 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -420,14 +420,29 @@ template class Vector { } /** - * @brief %Vector projected onto another + * @brief %Vector projected onto line * - * Returns vector projected onto line defined by @p other. @f[ + * Returns vector projected onto @p line. @f[ * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b * @f] + * @see projectedOntoNormalized() */ - inline Vector projected(const Vector& other) const { - return other*dot(*this, other)/other.dot(); + inline Vector projected(const Vector& line) const { + return line*dot(*this, line)/line.dot(); + } + + /** + * @brief %Vector projected onto normalized line + * + * Slightly faster alternative to projected(), expects @p line to be + * normalized. @f[ + * \boldsymbol a_1 = \frac{\boldsymbol a \cdot \boldsymbol b}{\boldsymbol b \cdot \boldsymbol b} \boldsymbol b = + * (\boldsymbol a \cdot \boldsymbol b) \boldsymbol b + * @f] + */ + inline Vector projectedOntoNormalized(const Vector& line) const { + CORRADE_ASSERT(MathTypeTraits::equals(line.dot(), T(1)), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector(std::numeric_limits::quiet_NaN()))); + return line*dot(*this, line); } /** @brief Sum of values in the vector */