From fe10dbece8f759540ad680a0784fbeab5bff9ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 13 Aug 2018 23:40:08 +0200 Subject: [PATCH] Math: use plane equation in Intersection::planeLine(). The old overload taking a separate "position" and normal is a deprecated alias, passing a calculated plane equation to the new one. --- doc/changelog.dox | 3 ++ src/Magnum/Math/Intersection.h | 44 +++++++++++++---------- src/Magnum/Math/Test/IntersectionTest.cpp | 10 +++--- src/Magnum/Shapes/Plane.cpp | 4 +-- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 1d350c4a6..cd6021195 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -268,6 +268,9 @@ See also: deeply nested, use @ref Math::Distance and @ref Math::Intersection instead - `Math::Geometry::Intersection::boxFrustum()` is deprecated, use @ref Math::Intersection::rangeFrustum() instead +- @ref Math::Intersection::planeLine() taking a separate plane normal and + position is deprecated, use @ref Math::planeEquation() and the overload + taking a plane equation as @ref Math::Vector4 instead - @ref Audio::PlayableGroup::setClean() is deprecated in favor of @ref Audio::Listener::update(), as that one is a feature superset with clearer naming diff --git a/src/Magnum/Math/Intersection.h b/src/Magnum/Math/Intersection.h index 677d0ed95..16d2f8a1e 100644 --- a/src/Magnum/Math/Intersection.h +++ b/src/Magnum/Math/Intersection.h @@ -110,8 +110,7 @@ template inline T lineSegmentLine(const Vector2& p, const Vector2 /** @brief Intersection of a plane and line -@param planePosition Plane position -@param planeNormal Plane normal +@param plane Plane equation @param p Starting point of the line @param r Direction of the line @@ -123,27 +122,36 @@ Returns intersection point position @f$ t @f$ on the line: - @f$ t \notin [ 0 ; 1 ] @f$ if the intersection is outside the line segment - @f$ t \in \{-\infty, \infty\} @f$ if the intersection doesn't exist -First the parameter @f$ f @f$ of parametric equation of the plane is calculated -from plane normal @f$ \boldsymbol{n} @f$ and plane position: @f[ - \begin{pmatrix} n_0 \\ n_1 \\ n_2 \end{pmatrix} \cdot - \begin{pmatrix} x \\ y \\ z \end{pmatrix} - f = 0 -@f] -Using plane normal @f$ \boldsymbol{n} @f$, parameter @f$ f @f$ and line defined -by @f$ \boldsymbol{p} @f$ and @f$ \boldsymbol{r} @f$, value of @f$ t @f$ is -calculated and returned. @f[ - \begin{array}{rcl} - f & = & \boldsymbol n \cdot (\boldsymbol p + t \boldsymbol r) \\ - \Rightarrow t & = & \cfrac{f - \boldsymbol n \cdot \boldsymbol p}{\boldsymbol n \cdot \boldsymbol r} - \end{array} +Using the plane equation @f$ ax + by + cz + d = 0 @f$ with @f$ \boldsymbol{n} @f$ +defined as @f$ \boldsymbol{n} = (a, b, c)^T @f$ and a line defined by +@f$ \boldsymbol{p} @f$ and @f$ \boldsymbol{r} @f$, value of @f$ t @f$ is +calculated as: @f[ + t = \cfrac{-d - \boldsymbol{n} \cdot \boldsymbol{p}}{\boldsymbol{n} \cdot \boldsymbol{r}} @f] -@see @ref isInf(), @ref isNan() +@see @ref planeEquation(), @ref isInf(), @ref isNan() */ -template inline T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& p, const Vector3& r) { - const T f = dot(planePosition, planeNormal); - return (f - dot(planeNormal, p))/dot(planeNormal, r); +template inline T planeLine(const Vector4& plane, const Vector3& p, const Vector3& r) { + return (-plane.w() - dot(plane.xyz(), p))/dot(plane.xyz(), r); } +#ifdef MAGNUM_BUILD_DEPRECATED +/** +@brief Intersection of a plane and line +@param planePosition Plane position +@param planeNormal Plane normal +@param p Starting point of the line +@param r Direction of the line + +@deprecated Use @ref planeLine(const Vector4&, const Vector3&, const Vector3&) + together with @ref planeEquation(const Vector3&, const Vector3&, const Vector3&) + instead. +*/ +template inline CORRADE_DEPRECATED("use planeLine(const Vector4&, const Vector3&, const Vector3&) together with planeEquation(const Vector3&, const Vector3&) instead") T planeLine(const Vector3& planePosition, const Vector3& planeNormal, const Vector3& p, const Vector3& r) { + return planeLine(planeEquation(planePosition, planeNormal), p, r); +} +#endif + /** @brief Intersection of a point and a frustum @param point Point diff --git a/src/Magnum/Math/Test/IntersectionTest.cpp b/src/Magnum/Math/Test/IntersectionTest.cpp index d47368693..23318335b 100644 --- a/src/Magnum/Math/Test/IntersectionTest.cpp +++ b/src/Magnum/Math/Test/IntersectionTest.cpp @@ -84,21 +84,23 @@ IntersectionTest::IntersectionTest() { void IntersectionTest::planeLine() { const Vector3 planePosition(-1.0f, 1.0f, 0.5f); const Vector3 planeNormal(0.0f, 0.0f, 1.0f); + const Vector4 planeEquation = Math::planeEquation(planeNormal, planePosition); + CORRADE_COMPARE(planeEquation, (Vector4{0.0f, 0.0f, 1.0f, -0.5f})); /* Inside line segment */ - CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + CORRADE_COMPARE(Intersection::planeLine(planeEquation, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 2.0f}), 0.75f); /* Outside line segment */ - CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + CORRADE_COMPARE(Intersection::planeLine(planeEquation, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}), -0.5f); /* Line lies on the plane */ - CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + CORRADE_COMPARE(Intersection::planeLine(planeEquation, {1.0f, 0.5f, 0.5f}, {-1.0f, 0.5f, 0.0f}), Constants::nan()); /* Line is parallel to the plane */ - CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal, + CORRADE_COMPARE(Intersection::planeLine(planeEquation, {1.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}), -Constants::inf()); } diff --git a/src/Magnum/Shapes/Plane.cpp b/src/Magnum/Shapes/Plane.cpp index c001d789c..1916b8d60 100644 --- a/src/Magnum/Shapes/Plane.cpp +++ b/src/Magnum/Shapes/Plane.cpp @@ -40,12 +40,12 @@ Plane Plane::transformed(const Matrix4& matrix) const { } bool Plane::operator%(const Line3D& other) const { - Float t = Math::Intersection::planeLine(_position, _normal, other.a(), other.b()-other.a()); + Float t = Math::Intersection::planeLine(Math::planeEquation(_normal, _position), other.a(), other.b()-other.a()); return t != t || (t != Constants::inf() && t != -Constants::inf()); } bool Plane::operator%(const LineSegment3D& other) const { - Float t = Math::Intersection::planeLine(_position, _normal, other.a(), other.b()-other.a()); + Float t = Math::Intersection::planeLine(Math::planeEquation(_normal, _position), other.a(), other.b()-other.a()); return t > 0.0f && t < 1.0f; }