Browse Source

Math: cleaned up plane/line intersection.

The function now accepts starting point and direction of the line (not
starting and ending point). Also improved the documentation and test a
bit.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
fd531b5101
  1. 32
      src/Math/Geometry/Intersection.h
  2. 2
      src/Math/Geometry/Test/CMakeLists.txt
  3. 8
      src/Math/Geometry/Test/IntersectionTest.cpp
  4. 4
      src/Physics/Plane.cpp

32
src/Math/Geometry/Intersection.h

@ -41,34 +41,30 @@ class Intersection {
* @brief %Intersection of a plane and line
* @param planePosition Plane position
* @param planeNormal Plane normal
* @param a Starting point of the line
* @param b Ending point of the line
* @return %Intersection point position, NaN if the line lies on the
* plane or infinity if the intersection doesn't exist. %Intersection
* point can be computed from the position with `a+intersection(...)*b`.
* If returned value is in range @f$ [ 0 ; 1 ] @f$, the intersection
* is inside the line segment defined by `a` and `b`.
* @param p Starting point of the line
* @param r Direction of the line
* @return %Intersection point position `t` on the line, NaN if the
* line lies on the plane or infinity if the intersection doesn't
* exist. %Intersection point can be then computed from with
* `p + t*r`. If returned value is in range @f$ [ 0 ; 1 ] @f$, the
* intersection is inside the line segment defined by `p` and `r`.
*
* First the parameter *f* of parametric equation of the plane
* is computed from plane normal **n** 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 **n**, parameter *f* and points **a** and **b**,
* value of *t* is computed and returned. @f[
* Using plane normal **n**, parameter *f* and line defined by **p**
* and **r**, value of *t* is computed and returned. @f[
* \begin{array}{rcl}
* \Delta \boldsymbol b & = & \boldsymbol b - \boldsymbol a \\
* f & = & \boldsymbol n \cdot (\boldsymbol a + \Delta \boldsymbol b \cdot t) \\
* \Rightarrow t & = & \cfrac{f - \boldsymbol n \cdot \boldsymbol a}{\boldsymbol n \cdot \Delta \boldsymbol b}
* 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}
* @f]
*/
template<class T> static T planeLine(const Vector3<T>& planePosition, const Vector3<T>& planeNormal, const Vector3<T>& a, const Vector3<T>& b) {
/* Compute f from normal and plane position */
T f = Vector3<T>::dot(planePosition, planeNormal);
/* Compute t */
return (f-Vector3<T>::dot(planeNormal, a))/Vector3<T>::dot(planeNormal, b-a);
template<class T> static T planeLine(const Vector3<T>& planePosition, const Vector3<T>& planeNormal, const Vector3<T>& p, const Vector3<T>& r) {
const T f = Vector3<T>::dot(planePosition, planeNormal);
return (f-Vector3<T>::dot(planeNormal, p))/Vector3<T>::dot(planeNormal, r);
}
};

2
src/Math/Geometry/Test/CMakeLists.txt

@ -23,5 +23,5 @@
#
corrade_add_test(MathGeometryDistanceTest DistanceTest.cpp)
corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp)
corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathGeometryRectangleTest RectangleTest.cpp LIBRARIES MagnumMathTestLib)

8
src/Math/Geometry/Test/IntersectionTest.cpp

@ -48,19 +48,19 @@ void IntersectionTest::planeLine() {
/* Inside line segment */
CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal,
Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 0.0f, 1.0f))), 0.75f);
Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 0.0f, 2.0f))), 0.75f);
/* Outside line segment */
CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal,
Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 2.0f))), -0.5f);
Vector3(0.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f))), -0.5f);
/* Line lies on the plane */
CORRADE_COMPARE(Intersection::planeLine(planePosition, planeNormal,
Vector3(1.0f, 0.5f, 0.5f), Vector3(0.0f, 1.0f, 0.5f)), std::numeric_limits<Float>::quiet_NaN());
Vector3(1.0f, 0.5f, 0.5f), Vector3(-1.0f, 0.5f, 0.0f)), std::numeric_limits<Float>::quiet_NaN());
/* Line is parallell to the plane */
CORRADE_COMPARE((Intersection::planeLine(planePosition, planeNormal,
Vector3(1.0f, 0.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f))), -std::numeric_limits<Float>::infinity());
Vector3(1.0f, 0.0f, 1.0f), Vector3(-1.0f, 0.0f, 0.0f))), -std::numeric_limits<Float>::infinity());
}
}}}}

4
src/Physics/Plane.cpp

@ -49,12 +49,12 @@ bool Plane::collides(const AbstractShape<3>* other) const {
}
bool Plane::operator%(const Line3D& other) const {
Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB());
Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA());
return t != t || (t != std::numeric_limits<Float>::infinity() && t != -std::numeric_limits<Float>::infinity());
}
bool Plane::operator%(const LineSegment3D& other) const {
Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB());
Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA());
return t > 0.0f && t < 1.0f;
}

Loading…
Cancel
Save