Browse Source

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.
pull/272/head
Vladimír Vondruš 8 years ago
parent
commit
fe10dbece8
  1. 3
      doc/changelog.dox
  2. 44
      src/Magnum/Math/Intersection.h
  3. 10
      src/Magnum/Math/Test/IntersectionTest.cpp
  4. 4
      src/Magnum/Shapes/Plane.cpp

3
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

44
src/Magnum/Math/Intersection.h

@ -110,8 +110,7 @@ template<class T> inline T lineSegmentLine(const Vector2<T>& p, const Vector2<T>
/**
@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<class T> inline T planeLine(const Vector3<T>& planePosition, const Vector3<T>& planeNormal, const Vector3<T>& p, const Vector3<T>& r) {
const T f = dot(planePosition, planeNormal);
return (f - dot(planeNormal, p))/dot(planeNormal, r);
template<class T> inline T planeLine(const Vector4<T>& plane, const Vector3<T>& p, const Vector3<T>& 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<T>&, const Vector3<T>&, const Vector3<T>&)
together with @ref planeEquation(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&)
instead.
*/
template<class T> inline CORRADE_DEPRECATED("use planeLine(const Vector4&, const Vector3&, const Vector3&) together with planeEquation(const Vector3&, const Vector3&) instead") T planeLine(const Vector3<T>& planePosition, const Vector3<T>& planeNormal, const Vector3<T>& p, const Vector3<T>& r) {
return planeLine(planeEquation(planePosition, planeNormal), p, r);
}
#endif
/**
@brief Intersection of a point and a frustum
@param point Point

10
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());
}

4
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;
}

Loading…
Cancel
Save