@ -27,202 +27,192 @@
*/
*/
/** @file
/** @file
* @ brief Class @ ref Magnum : : Math : : Geometry : : Distance
* @ brief Namespace @ ref Magnum : : Math : : Geometry : : Distance
*/
*/
# include "Magnum/Math/Functions.h"
# include "Magnum/Math/Functions.h"
# include "Magnum/Math/Vector3.h"
# include "Magnum/Math/Vector3.h"
# include "Magnum/Math/Vector4.h"
# include "Magnum/Math/Vector4.h"
namespace Magnum { namespace Math { namespace Geometry {
namespace Magnum { namespace Math { namespace Geometry { namespace Distance {
/** @brief Functions for computing distances */
/**
class Distance {
@ brief Distance of line and point in 2 D , squared
public :
@ param a First point of the line
Distance ( ) = delete ;
@ param b Second point of the line
@ param point Point
/**
* @ brief Distance of line and point in 2 D
More efficient than @ ref linePoint ( const Vector2 < T > & , const Vector2 < T > & , const Vector2 < T > & )
* @ param a First point of the line
for comparing distance with other values , because it doesn ' t calculate the
* @ param b Second point of the line
square root .
* @ param point Point
*/
*
template < class T > inline T linePointSquared ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
* The distance * d * is computed from point * * p * * and line defined by * * a * *
const Vector2 < T > bMinusA = b - a ;
* and * * b * * using @ ref cross ( const Vector2 < T > & , const Vector2 < T > & ) " perp-dot product " : @ f [
return Math : : pow < 2 > ( cross ( bMinusA , a - point ) ) / bMinusA . dot ( ) ;
* d = \ frac { | ( \ boldsymbol b - \ boldsymbol a ) _ \ bot \ cdot ( \ boldsymbol a - \ boldsymbol p ) | } { | \ boldsymbol b - \ boldsymbol a | }
}
* @ f ]
* Source : http : //mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
/**
* @ see @ ref linePointSquared ( const Vector2 < T > & , const Vector2 < T > & , const Vector2 < T > & )
@ brief Distance of line and point in 2 D
*/
@ param a First point of the line
template < class T > static T linePoint ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
@ param b Second point of the line
const Vector2 < T > bMinusA = b - a ;
@ param point Point
return std : : abs ( cross ( bMinusA , a - point ) ) / bMinusA . length ( ) ;
}
The distance @ f $ d @ f $ is calculated from point @ f $ \ boldsymbol { p } @ f $ and line
defined by @ f $ \ boldsymbol { a } @ f $ and @ f $ \ boldsymbol { b } @ f $ using
/**
@ ref cross ( const Vector2 < T > & , const Vector2 < T > & ) " perp-dot product " : @ f [
* @ brief Distance of line and point in 2 D , squared
d = \ frac { | ( \ boldsymbol b - \ boldsymbol a ) _ \ bot \ cdot ( \ boldsymbol a - \ boldsymbol p ) | } { | \ boldsymbol b - \ boldsymbol a | }
* @ param a First point of the line
@ f ]
* @ param b Second point of the line
Source : http : //mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
* @ param point Point
@ see @ ref linePointSquared ( const Vector2 < T > & , const Vector2 < T > & , const Vector2 < T > & )
*
*/
* More efficient than
template < class T > inline T linePoint ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
* @ ref linePoint ( const Vector2 < T > & , const Vector2 < T > & , const Vector2 < T > & )
const Vector2 < T > bMinusA = b - a ;
* for comparing distance with other values , because it doesn ' t
return std : : abs ( cross ( bMinusA , a - point ) ) / bMinusA . length ( ) ;
* compute the square root .
}
*/
template < class T > static T linePointSquared ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
/**
const Vector2 < T > bMinusA = b - a ;
@ brief Distance of line and point in 3 D , squared
return Math : : pow < 2 > ( cross ( bMinusA , a - point ) ) / bMinusA . dot ( ) ;
}
More efficient than @ ref linePoint ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
for comparing distance with other values , because it doesn ' t calculate the
/**
square root .
* @ brief Distance of line and point in 3 D
*/
* @ param a First point of the line
template < class T > inline T linePointSquared ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
* @ param b Second point of the line
return cross ( point - a , point - b ) . dot ( ) / ( b - a ) . dot ( ) ;
* @ param point Point
}
*
* The distance * d * is computed from point * * p * * and line defined by * * a * *
/**
* and * * b * * using @ ref cross ( const Vector3 < T > & , const Vector3 < T > & ) " cross product " : @ f [
@ brief Distance of line and point in 3 D
* d = \ frac { | ( \ boldsymbol p - \ boldsymbol a ) \ times ( \ boldsymbol p - \ boldsymbol b ) | }
@ param a First point of the line
* { | \ boldsymbol b - \ boldsymbol a | }
@ param b Second point of the line
* @ f ]
@ param point Point
* Source : http : //mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
* @ see @ ref linePointSquared ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
The distance @ f $ d @ f $ is calculated from point @ f $ \ boldsymbol { p } @ f $ and line
*/
defined by @ f $ \ boldsymbol { a } @ f $ and @ f $ \ boldsymbol { b } @ f $ using
template < class T > static T linePoint ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
@ ref cross ( const Vector3 < T > & , const Vector3 < T > & ) " cross product " : @ f [
return std : : sqrt ( linePointSquared ( a , b , point ) ) ;
d = \ frac { | ( \ boldsymbol p - \ boldsymbol a ) \ times ( \ boldsymbol p - \ boldsymbol b ) | } { | \ boldsymbol b - \ boldsymbol a | }
}
@ f ]
Source : http : //mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
/**
@ see @ ref linePointSquared ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
* @ brief Distance of line and point in 3 D , squared
*/
*
template < class T > inline T linePoint ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
* More efficient than @ ref linePoint ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
return std : : sqrt ( linePointSquared ( a , b , point ) ) ;
* for comparing distance with other values , because it doesn ' t
}
* compute the square root .
*/
/**
template < class T > static T linePointSquared ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
@ brief Distance of point from line segment in 2 D , squared
return cross ( point - a , point - b ) . dot ( ) / ( b - a ) . dot ( ) ;
}
More efficient than @ ref lineSegmentPoint ( ) for comparing distance with other
values , because it doesn ' t calculate the square root .
/**
*/
* @ brief Dístance of point from line segment in 2 D
template < class T > T lineSegmentPointSquared ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) ;
* @ param a Starting point of the line
* @ param b Ending point of the line
/**
* @ param point Point
@ brief Dístance of point from line segment in 2 D
*
@ param a Starting point of the line
* Returns distance of point from line segment or from its
@ param b Ending point of the line
* starting / ending point , depending on where the point lies .
@ param point Point
*
* Determining whether the point lies next to line segment or outside
Returns distance of point from line segment or from its starting / ending point ,
* is done using Pythagorean theorem . If the following equation
depending on where the point lies .
* applies , the point * * p * * lies outside line segment closer to * * a * * : @ f [
* | \ boldsymbol p - \ boldsymbol b | ^ 2 > | \ boldsymbol b - \ boldsymbol a | ^ 2 + | \ boldsymbol p - \ boldsymbol a | ^ 2
Determining whether the point lies next to line segment or outside is done
* @ f ]
using Pythagorean theorem . If the following equation applies , the point
* On the other hand , if the following equation applies , the point
@ f $ \ boldsymbol { p } @ f $ lies outside line segment closer to @ f $ \ boldsymbol { a } @ f $ : @ f [
* lies outside line segment closer to * * b * * : @ f [
| \ boldsymbol p - \ boldsymbol b | ^ 2 > | \ boldsymbol b - \ boldsymbol a | ^ 2 + | \ boldsymbol p - \ boldsymbol a | ^ 2
* | \ boldsymbol p - \ boldsymbol a | ^ 2 > | \ boldsymbol b - \ boldsymbol a | ^ 2 + | \ boldsymbol p - \ boldsymbol b | ^ 2
@ f ]
* @ f ]
On the other hand , if the following equation applies , the point lies outside
* The last alternative is when the following equation applies . The
line segment closer to @ f $ \ boldsymbol { b } @ f $ : @ f [
* point then lies between * * a * * and * * b * * and the distance is
| \ boldsymbol p - \ boldsymbol a | ^ 2 > | \ boldsymbol b - \ boldsymbol a | ^ 2 + | \ boldsymbol p - \ boldsymbol b | ^ 2
* computed the same way as in @ ref linePoint ( ) . @ f [
@ f ]
* | \ boldsymbol b - \ boldsymbol a | ^ 2 > | \ boldsymbol p - \ boldsymbol a | ^ 2 + | \ boldsymbol p - \ boldsymbol b | ^ 2
The last alternative is when the following equation applies . The point then
* @ f ]
lies between @ f $ \ boldsymbol { a } @ f $ and @ f $ \ boldsymbol { b } @ f $ and the distance
*
is calculated the same way as in @ ref linePoint ( ) . @ f [
* @ see @ ref lineSegmentPointSquared ( )
| \ boldsymbol b - \ boldsymbol a | ^ 2 > | \ boldsymbol p - \ boldsymbol a | ^ 2 + | \ boldsymbol p - \ boldsymbol b | ^ 2
*/
@ f ]
template < class T > static T lineSegmentPoint ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) ;
@ see @ ref lineSegmentPointSquared ( )
/**
*/
* @ brief Distance of point from line segment in 2 D , squared
template < class T > T lineSegmentPoint ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) ;
*
* More efficient than @ ref lineSegmentPoint ( ) for comparing distance
/**
* with other values , because it doesn ' t compute the square root .
@ brief Distance of point from line segment in 3 D , squared
*/
template < class T > static T lineSegmentPointSquared ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) ;
More efficient than @ ref lineSegmentPoint ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
for comparing distance with other values , because it doesn ' t calculate the
/**
square root .
* @ brief Dístance of point from line segment in 3 D
*/
* @ param a Starting point of the line
template < class T > T lineSegmentPointSquared ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) ;
* @ param b Ending point of the line
* @ param point Point
/**
*
@ brief Dístance of point from line segment in 3 D
* Similar to 2 D implementation
@ param a Starting point of the line
* @ ref lineSegmentPoint ( const Vector2 < T > & , const Vector2 < T > & , const Vector2 < T > & ) .
@ param b Ending point of the line
*
@ param point Point
* @ see @ ref lineSegmentPointSquared ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
*/
Similar to 2 D implementation @ ref lineSegmentPoint ( const Vector2 < T > & , const Vector2 < T > & , const Vector2 < T > & ) .
template < class T > static T lineSegmentPoint ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
@ see @ ref lineSegmentPointSquared ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
return std : : sqrt ( lineSegmentPointSquared ( a , b , point ) ) ;
*/
}
template < class T > inline T lineSegmentPoint ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
return std : : sqrt ( lineSegmentPointSquared ( a , b , point ) ) ;
/**
}
* @ brief Distance of point from line segment in 3 D , squared
*
/**
* More efficient than
@ brief Distance of point from plane , scaled by the length of the planes normal
* @ ref lineSegmentPoint ( const Vector3 < T > & , const Vector3 < T > & , const Vector3 < T > & )
* for comparing distance with other values , because it doesn ' t compute
The distance @ f $ d @ f $ is calculated from point @ f $ \ boldsymbol { p } @ f $ and
* the square root .
plane with normal @ f $ \ boldsymbol { n } @ f $ and @ f $ w @ f $ using : @ f [
*/
d = \ boldsymbol { p } \ cdot \ boldsymbol { n } + w
template < class T > static T lineSegmentPointSquared ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) ;
@ f ]
The distance is negative if the point lies behind the plane .
/**
* @ brief Distance of point from plane
More efficient than @ ref pointPlane ( ) when merely the sign of the distance is
*
of interest , for example when testing on which half space of the plane the
* The distance * * d * * is computed from point * * p * * and plane with
point lies .
* normal * * n * * and * * w * * using : @ f [
@ see @ ref pointPlaneNormalized ( )
* d = \ frac { p \ cdot n + w } { \ left | n \ right | }
*/
* @ f ]
template < class T > inline T pointPlaneScaled ( const Vector3 < T > & point , const Vector4 < T > & plane ) {
* The distance is negative if the point lies behind the plane .
return dot ( plane . xyz ( ) , point ) + plane . w ( ) ;
*
}
* In cases where the planes normal is a unit vector ,
* @ ref pointPlaneUnnormalized ( ) is more efficient . If merely the sign
/**
* of the distance is of interest , @ ref pointPlaneScaled ( ) is more
@ brief Distance of point from plane
* efficient .
*/
The distance @ f $ d @ f $ is calculated from point @ f $ \ boldsymbol { p } @ f $ and
template < class T > static T pointPlane ( const Vector3 < T > & point , const Vector4 < T > & plane ) {
plane with normal @ f $ \ boldsymbol { n } @ f $ and @ f $ w @ f $ using : @ f [
return pointPlaneScaled < T > ( point , plane ) / plane . xyz ( ) . length ( ) ;
d = \ frac { \ boldsymbol { p } \ cdot \ boldsymbol { n } + w } { \ left | \ boldsymbol { n } \ right | }
}
@ f ]
The distance is negative if the point lies behind the plane .
/**
* @ brief Distance of point from plane , scaled by the length of the planes normal
In cases where the planes normal is a unit vector , @ ref pointPlaneNormalized ( )
*
is more efficient . If merely the sign of the distance is of interest ,
* The distance * * d * * is computed from point * * p * * and plane with
@ ref pointPlaneScaled ( ) is more efficient .
* normal * * n * * and * * w * * using : @ f [
*/
* d = p \ cdot n + w
template < class T > inline T pointPlane ( const Vector3 < T > & point , const Vector4 < T > & plane ) {
* @ f ]
return pointPlaneScaled < T > ( point , plane ) / plane . xyz ( ) . length ( ) ;
* The distance is negative if the point lies behind the plane .
}
*
* More efficient than @ ref pointPlane ( ) when merely the sign of the
/**
* distance is of interest , for example when testing on which half
@ brief Distance of point from plane with normalized normal
* space of the plane the point lies .
* @ see @ ref pointPlaneNormalized ( )
The distance @ f $ d @ f $ is calculated from point @ f $ \ boldsymbol { p } @ f $ and plane
*/
with normal @ f $ \ boldsymbol { n } @ f $ and @ f $ w @ f $ using : @ f [
template < class T > static T pointPlaneScaled ( const Vector3 < T > & point , const Vector4 < T > & plane ) {
d = \ boldsymbol { p } \ cdot \ boldsymbol { n } + w
return Math : : dot ( plane . xyz ( ) , point ) + plane . w ( ) ;
@ f ]
}
The distance is negative if the point lies behind the plane . Expects that
@ p plane normal is normalized .
/**
* @ brief Distance of point from plane with normalized normal
More efficient than @ ref pointPlane ( ) in cases where the plane ' s normal is
*
normalized . Equivalent to @ ref pointPlaneScaled ( ) but with assertion added on
* The distance * * d * * is computed from point * * p * * and plane with
top .
* normal * * n * * and * * w * * using : @ f [
*/
* d = p \ cdot n + w
template < class T > inline T pointPlaneNormalized ( const Vector3 < T > & point , const Vector4 < T > & plane ) {
* @ f ]
CORRADE_ASSERT ( plane . xyz ( ) . isNormalized ( ) ,
* The distance is negative if the point lies behind the plane . Expects
" Math::Geometry::Distance::pointPlaneNormalized(): plane normal is not an unit vector " , { } ) ;
* that @ p plane normal is normalized .
return pointPlaneScaled < T > ( point , plane ) ;
*
}
* More efficient than @ ref pointPlane ( ) in cases where the planes
* normal is normalized . Equivalent to @ ref pointPlaneScaled ( ) but with
template < class T > T lineSegmentPoint ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
* assertion added on top .
*/
template < class T > static T pointPlaneNormalized ( const Vector3 < T > & point , const Vector4 < T > & plane ) {
CORRADE_ASSERT ( plane . xyz ( ) . isNormalized ( ) ,
" Math::Geometry::Distance::pointPlaneNormalized(): plane normal is not an unit vector " , { } ) ;
return pointPlaneScaled < T > ( point , plane ) ;
}
} ;
template < class T > T Distance : : lineSegmentPoint ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
const Vector2 < T > pointMinusA = point - a ;
const Vector2 < T > pointMinusA = point - a ;
const Vector2 < T > pointMinusB = point - b ;
const Vector2 < T > pointMinusB = point - b ;
const Vector2 < T > bMinusA = b - a ;
const Vector2 < T > bMinusA = b - a ;
@ -242,7 +232,7 @@ template<class T> T Distance::lineSegmentPoint(const Vector2<T>& a, const Vector
return std : : abs ( cross ( bMinusA , - pointMinusA ) ) / std : : sqrt ( bDistanceA ) ;
return std : : abs ( cross ( bMinusA , - pointMinusA ) ) / std : : sqrt ( bDistanceA ) ;
}
}
template < class T > T Distance : : lineSegmentPointSquared ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
template < class T > T lineSegmentPointSquared ( const Vector2 < T > & a , const Vector2 < T > & b , const Vector2 < T > & point ) {
const Vector2 < T > pointMinusA = point - a ;
const Vector2 < T > pointMinusA = point - a ;
const Vector2 < T > pointMinusB = point - b ;
const Vector2 < T > pointMinusB = point - b ;
const Vector2 < T > bMinusA = b - a ;
const Vector2 < T > bMinusA = b - a ;
@ -262,7 +252,7 @@ template<class T> T Distance::lineSegmentPointSquared(const Vector2<T>& a, const
return Math : : pow < 2 > ( cross ( bMinusA , - pointMinusA ) ) / bDistanceA ;
return Math : : pow < 2 > ( cross ( bMinusA , - pointMinusA ) ) / bDistanceA ;
}
}
template < class T > T Distance : : lineSegmentPointSquared ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
template < class T > T lineSegmentPointSquared ( const Vector3 < T > & a , const Vector3 < T > & b , const Vector3 < T > & point ) {
const Vector3 < T > pointMinusA = point - a ;
const Vector3 < T > pointMinusA = point - a ;
const Vector3 < T > pointMinusB = point - b ;
const Vector3 < T > pointMinusB = point - b ;
const T pointDistanceA = pointMinusA . dot ( ) ;
const T pointDistanceA = pointMinusA . dot ( ) ;
@ -281,6 +271,6 @@ template<class T> T Distance::lineSegmentPointSquared(const Vector3<T>& a, const
return cross ( pointMinusA , pointMinusB ) . dot ( ) / bDistanceA ;
return cross ( pointMinusA , pointMinusB ) . dot ( ) / bDistanceA ;
}
}
} } }
} } } }
# endif
# endif