Browse Source

Math: added Distance::pointPoint() and Intersection::pointSphere().

Those add nothing of value as they only wrap trivial code, but make the
operations easier to discover, and that's what matters.
pull/537/head
Vladimír Vondruš 5 years ago
parent
commit
e9f2101b15
  1. 4
      doc/changelog.dox
  2. 62
      src/Magnum/Math/Distance.h
  3. 48
      src/Magnum/Math/Intersection.h
  4. 44
      src/Magnum/Math/Test/DistanceTest.cpp
  5. 30
      src/Magnum/Math/Test/IntersectionTest.cpp
  6. 6
      src/Magnum/Math/Vector.h

4
doc/changelog.dox

@ -127,6 +127,10 @@ See also:
- Added @ref Math::RectangularMatrix::RectangularMatrix(IdentityInitT, T)
constructor as it might be useful to create non-square identity matrices as
well
- Added @ref Math::Distance::pointPoint() and
@ref Math::Intersection::pointCircle() /
@relativeref{Math::Intersection,pointSphere()}, which are just wrappers
over trivial code but easier to discover
@subsubsection changelog-latest-new-meshtools MeshTools library

62
src/Magnum/Math/Distance.h

@ -36,6 +36,68 @@
namespace Magnum { namespace Math { namespace Distance {
/**
@brief Distance of two points in 2D, squared
@param a First point
@param b Second point
@m_since_latest
Same as @cpp (b - a).dot() @ce. More efficient than @ref pointPoint(const Vector2<T>&, const Vector2<T>&)
for comparing distance with other values, because it doesn't calculate the
square root.
@see @ref Vector::dot()
*/
template<class T> T pointPointSquared(const Vector2<T>& a, const Vector2<T>& b) {
return (b - a).dot();
}
/**
@brief Distance of two points in 2D
@param a First point
@param b Second point
@m_since_latest
Same as @cpp (b - a).length() @ce: @f[
d = |\boldsymbol{b} - \boldsymbol{a}|
@f]
@see @ref pointPointSquared(const Vector2<T>&, const Vector2<T>&),
@ref Vector::length()
*/
template<class T> T pointPoint(const Vector2<T>& a, const Vector2<T>& b) {
return (b - a).length();
}
/**
@brief Distance of two points in 3D, squared
@param a First point
@param b Second point
@m_since_latest
Same as @cpp (b - a).dot() @ce. More efficient than @ref pointPoint(const Vector3<T>&, const Vector3<T>&)
for comparing distance with other values, because it doesn't calculate the
square root.
*/
template<class T> T pointPointSquared(const Vector3<T>& a, const Vector3<T>& b) {
return (b - a).dot();
}
/**
@brief Distance of two points in 3D
@param a First point
@param b Second point
@m_since_latest
Same as @cpp (b - a).length() @ce: @f[
d = |\boldsymbol{b} - \boldsymbol{a}|
@f]
@see @ref pointPointSquared(const Vector3<T>&, const Vector3<T>&)
*/
template<class T> T pointPoint(const Vector3<T>& a, const Vector3<T>& b) {
return (b - a).length();
}
/**
@brief Distance of line and point in 2D, squared
@param a First point of the line

48
src/Magnum/Math/Intersection.h

@ -40,6 +40,54 @@
namespace Magnum { namespace Math { namespace Intersection {
/**
@brief Intersection of a point and a circle in 2D
@param point Point
@param circleCenter Circle center
@param circleRadius Circle radius
@return @cpp true @ce if the the point intersects the sphere, @cpp false @ce
otherwise
@m_since_latest
Same as @cpp (circleCenter - point).dot() <= Math::pow<2>(circleRadius) @ce. A
point @f$ \boldsymbol{p} @f$ intersects with a circle of a center
@f$ \boldsymbol{c} @f$ and radius @f$ r @f$ if the following holds: @f[
\begin{array}{rcl}
|\boldsymbol{c} - \boldsymbol{p}| & < & r \\
(\boldsymbol{c} - \boldsymbol{p}) \cdot (\boldsymbol{c} - \boldsymbol{p}) & < & r^2
\end{array}
@f]
@see @ref Distance::pointPointSquared(), @ref Vector::dot(), @ref pow(T)
*/
template<class T> inline bool pointCircle(const Vector2<T>& point, const Vector2<T>& circleCenter, T circleRadius) {
return (circleCenter - point).dot() <= circleRadius*circleRadius;
}
/**
@brief Intersection of a point and a sphere in 3D
@param point Point
@param sphereCenter Sphere center
@param sphereRadius Sphere radius
@return @cpp true @ce if the the point intersects the sphere, @cpp false @ce
otherwise
@m_since_latest
Same as @cpp (sphereCenter - point).dot() <= Math::pow<2>(sphereRadius) @ce. A
point @f$ \boldsymbol{p} @f$ intersects with a sphere of a center
@f$ \boldsymbol{c} @f$ and radius @f$ r @f$ if the following holds: @f[
\begin{array}{rcl}
|\boldsymbol{c} - \boldsymbol{p}| & < & r \\
(\boldsymbol{c} - \boldsymbol{p}) \cdot (\boldsymbol{c} - \boldsymbol{p}) & < & r^2
\end{array}
@f]
@see @ref Distance::pointPointSquared(), @ref Vector::dot(), @ref pow(T)
*/
template<class T> inline bool pointSphere(const Vector3<T>& point, const Vector3<T>& sphereCenter, T sphereRadius) {
return (sphereCenter - point).dot() <= sphereRadius*sphereRadius;
}
/**
@brief Intersection of two line segments in 2D
@param p Starting point of first line segment

44
src/Magnum/Math/Test/DistanceTest.cpp

@ -36,6 +36,9 @@ namespace Magnum { namespace Math { namespace Test { namespace {
struct DistanceTest: Corrade::TestSuite::Tester {
explicit DistanceTest();
void pointPoint2D();
void pointPoint3D();
void linePoint2D();
void linePoint3D();
void lineSegmentPoint2D();
@ -53,7 +56,10 @@ typedef Math::Vector4<Float> Vector4;
typedef Math::Constants<Float> Constants;
DistanceTest::DistanceTest() {
addTests({&DistanceTest::linePoint2D,
addTests({&DistanceTest::pointPoint2D,
&DistanceTest::pointPoint3D,
&DistanceTest::linePoint2D,
&DistanceTest::linePoint3D,
&DistanceTest::lineSegmentPoint2D,
&DistanceTest::lineSegmentPoint3D,
@ -64,6 +70,42 @@ DistanceTest::DistanceTest() {
&DistanceTest::pointPlaneNormalizedNotNormalized});
}
void DistanceTest::pointPoint2D() {
CORRADE_COMPARE(Distance::pointPoint(Vector2{5.0f, 1.0f},
Vector2{6.0f, 1.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPointSquared(Vector2{5.0f, 1.0f},
Vector2{6.0f, 1.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPoint(Vector2{5.0f, 1.0f},
Vector2{5.0f, 2.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPointSquared(Vector2{5.0f, 1.0f},
Vector2{5.0f, 2.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPoint(Vector2{5.0f, 1.0f},
Vector2{6.0f, 2.0f}),
Constants::sqrt2());
CORRADE_COMPARE(Distance::pointPointSquared(Vector2{5.0f, 1.0f},
Vector2{6.0f, 2.0f}), 2.0f);
}
void DistanceTest::pointPoint3D() {
CORRADE_COMPARE(Distance::pointPoint(Vector3{5.0f, 1.0f, -2.0f},
Vector3{6.0f, 1.0f, -2.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPointSquared(Vector3{5.0f, 1.0f, -2.0f},
Vector3{6.0f, 1.0f, -2.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPoint(Vector3{5.0f, 1.0f, -2.0f},
Vector3{5.0f, 2.0f, -2.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPointSquared(Vector3{5.0f, 1.0f, -2.0f},
Vector3{5.0f, 2.0f, -2.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPoint(Vector3{5.0f, 1.0f, -2.0f},
Vector3{5.0f, 1.0f, -3.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPointSquared(Vector3{5.0f, 1.0f, -2.0f},
Vector3{5.0f, 1.0f, -3.0f}), 1.0f);
CORRADE_COMPARE(Distance::pointPoint(Vector3{5.0f, 1.0f, -2.0f},
Vector3{6.0f, 2.0f, -3.0f}),
Constants::sqrt3());
CORRADE_COMPARE(Distance::pointPointSquared(Vector3{5.0f, 1.0f, -2.0f},
Vector3{6.0f, 2.0f, -3.0f}), 3.0f);
}
void DistanceTest::linePoint2D() {
Vector2 a(0.0f);
Vector2 b(1.0f);

30
src/Magnum/Math/Test/IntersectionTest.cpp

@ -38,6 +38,9 @@ using namespace Literals;
struct IntersectionTest: Corrade::TestSuite::Tester {
explicit IntersectionTest();
void pointCircle();
void pointSphere();
void planeLine();
void lineLine();
@ -69,7 +72,10 @@ typedef Math::Rad<Float> Rad;
typedef Math::Rad<Double> Radd;
IntersectionTest::IntersectionTest() {
addTests({&IntersectionTest::planeLine,
addTests({&IntersectionTest::pointCircle,
&IntersectionTest::pointSphere,
&IntersectionTest::planeLine,
&IntersectionTest::lineLine,
&IntersectionTest::pointFrustum,
@ -87,6 +93,28 @@ IntersectionTest::IntersectionTest() {
&IntersectionTest::aabbCone});
}
void IntersectionTest::pointCircle() {
CORRADE_VERIFY(Intersection::pointCircle(
Vector2{5.0f, 1.0f},
Vector2{6.0f, 2.0f},
Constants::sqrt2() + TypeTraits<Float>::epsilon()));
CORRADE_VERIFY(!Intersection::pointCircle(
Vector2{5.0f, 1.0f},
Vector2{6.0f, 2.0f},
Constants::sqrt2() - TypeTraits<Float>::epsilon()));
}
void IntersectionTest::pointSphere() {
CORRADE_VERIFY(Intersection::pointSphere(
Vector3{5.0f, 1.0f, -2.0f},
Vector3{6.0f, 2.0f, -3.0f},
Constants::sqrt3() + TypeTraits<Float>::epsilon()));
CORRADE_VERIFY(!Intersection::pointSphere(
Vector3{5.0f, 1.0f, -2.0f},
Vector3{6.0f, 2.0f, -3.0f},
Constants::sqrt3() - TypeTraits<Float>::epsilon()));
}
void IntersectionTest::planeLine() {
const Vector3 planePosition(-1.0f, 1.0f, 0.5f);
const Vector3 planeNormal(0.0f, 0.0f, 1.0f);

6
src/Magnum/Math/Vector.h

@ -500,7 +500,8 @@ template<std::size_t size, class T> class Vector {
* \boldsymbol a \cdot \boldsymbol a = \sum_{i=0}^{n-1} \boldsymbol a_i^2
* @f]
* @see @ref dot(const Vector<size, T>&, const Vector<size, T>&),
* @ref isNormalized()
* @ref isNormalized(), @ref Distance::pointPointSquared(),
* @ref Intersection::pointSphere()
*/
T dot() const { return Math::dot(*this, *this); }
@ -525,7 +526,8 @@ template<std::size_t size, class T> class Vector {
* @snippet MagnumMath.cpp Vector-length-manhattan
*
* @see @ref lengthInverted(), @ref Math::sqrt(), @ref normalized(),
* @ref resized()
* @ref resized(), @ref Distance::pointPoint(),
* @ref Intersection::pointSphere()
* @todo something like std::hypot() for possibly better precision?
*/
T length() const { return T(std::sqrt(dot())); }

Loading…
Cancel
Save