1#include <Core/Geometry/DistanceQueries.hpp>
2#include <Core/Math/LinearAlgebra.hpp>
3#include <Core/Math/Math.hpp>
6#include <catch2/catch_test_macros.hpp>
9TEST_CASE(
"Core/Geometry/DistanceQueries",
"[unittests][Core][Core/Geometry][DistanceQueries]" ) {
12 SECTION(
"Simple tests" ) {
13 Vector3 a( -2.f, 0.f, 0.f );
14 Vector3 b( 2.f, 0.f, 0.f );
15 Vector3 c( 0.f, 3.f, 0.f );
16 Vector3 d( 0.f, -3.f, 0.f );
17 Vector3 e( -4.f, -3.f, 0.f );
18 Vector3 f( 4.f, 3.f, 0.f );
21 Scalar distPointToTri =
std::sqrt( Geometry::pointToTriSq( c, a, b, d ).distanceSquared );
23 REQUIRE( Math::areApproxEqual( distPointToTri, ( c - ( .5_ra * ( a + b ) ) ).norm() ) );
26 const Vector3& lineOrigin = a;
27 Vector3 lineDirection = d - a;
28 const Vector3& segCenter = .5_ra * ( c + b );
29 Vector3 segDirection = b - c;
30 Scalar segExtent = .5_ra *
std::sqrt( ( b - c ).dot( b - c ) );
31 Scalar distLineToSeg =
32 Geometry::lineToSegSq( lineOrigin, lineDirection, segCenter, segDirection, segExtent )
34 REQUIRE( Math::areApproxEqual( distLineToSeg, Geometry::pointToSegmentSq( a, c, b - c ) ) );
37 Vector3 v[3] = { a, d, e };
38 Scalar distLineToTri = Geometry::lineToTriSq( segCenter, segDirection, v ).sqrDistance;
39 REQUIRE( Math::areApproxEqual( distLineToTri, Geometry::pointToSegmentSq( a, c, b - c ) ) );
43 Geometry::segmentToTriSq( segCenter, segDirection, segExtent, v ).sqrDistance;
44 REQUIRE( Math::areApproxEqual( distSegToTri, Geometry::pointToSegmentSq( a, c, b - c ) ) );
47 Vector3 v2[3] = { c, f, b };
48 Scalar distTriToTri = Geometry::triangleToTriSq( v, v2 ).sqrDistance;
49 REQUIRE( Math::areApproxEqual( distTriToTri, Geometry::pointToSegmentSq( a, c, b - c ) ) );
52 Vector3 a( 1_ra, 2.3_ra, 4.5_ra );
53 Vector3 b( -6_ra, 7_ra, 8.9_ra );
54 Vector3 c( -3_ra, 12.3_ra, -42.1_ra );
57 Vector3 m = 0.5_ra * ( a + b );
60 Vector3 na = a - 12_ra * ( b - a );
63 Vector3 nb = a + 42_ra * ( b - a );
66 Math::getOrthogonalVectors( ( b - a ).normalized(), y, z );
68 SECTION(
"Test line queries" ) {
70 REQUIRE( Math::areApproxEqual( Geometry::pointToLineSq( a, a, b - a ), 0_ra ) );
72 REQUIRE( Math::areApproxEqual( Geometry::pointToLineSq( b, a, b - a ), 0_ra ) );
74 REQUIRE( Math::areApproxEqual( Geometry::pointToLineSq( na, a, b - a ), 0_ra ) );
75 REQUIRE( Math::areApproxEqual( Geometry::pointToLineSq( nb, a, b - a ), 0_ra ) );
78 Math::areApproxEqual( Geometry::pointToLineSq( m + y, a, b - a ), y.squaredNorm() ) );
81 SECTION(
"Test segment queries" ) {
83 REQUIRE( Math::areApproxEqual( Geometry::pointToSegmentSq( a, a, b - a ), 0_ra ) );
84 REQUIRE( Math::areApproxEqual( Geometry::pointToSegmentSq( b, a, b - a ), 0_ra ) );
86 REQUIRE( Math::areApproxEqual( Geometry::pointToSegmentSq( na, a, b - a ),
87 ( na - a ).squaredNorm() ) );
88 REQUIRE( Math::areApproxEqual( Geometry::pointToSegmentSq( nb, a, b - a ),
89 ( nb - b ).squaredNorm() ) );
91 REQUIRE( Math::areApproxEqual( Geometry::pointToSegmentSq( m + y, a, b - a ),
95 SECTION(
"Triangle queries: Test that each vertex returns itself" ) {
97 auto da = Geometry::pointToTriSq( a, a, b, c );
98 REQUIRE( Math::areApproxEqual( da.distanceSquared, 0_ra ) );
99 REQUIRE( da.meshPoint == a );
100 REQUIRE( da.flags == Geometry::FlagsInternal::HIT_A );
103 auto db = Geometry::pointToTriSq( b, a, b, c );
104 REQUIRE( Math::areApproxEqual( db.distanceSquared, 0_ra ) );
105 REQUIRE( db.meshPoint == b );
106 REQUIRE( db.flags == Geometry::FlagsInternal::HIT_B );
109 auto dc = Geometry::pointToTriSq( c, a, b, c );
110 REQUIRE( Math::areApproxEqual( dc.distanceSquared, 0_ra ) );
111 REQUIRE( dc.meshPoint == c );
112 REQUIRE( dc.flags == Geometry::FlagsInternal::HIT_C );
115 SECTION(
"Triangle queries: Test midpoints of edges" ) {
116 Vector3 mab = .5_ra * ( a + b );
117 Vector3 mac = .5_ra * ( a + c );
118 Vector3 mbc = .5_ra * ( b + c );
121 auto dmab = Geometry::pointToTriSq( mab, a, b, c );
122 REQUIRE( Math::areApproxEqual( dmab.distanceSquared, 0_ra ) );
123 REQUIRE( dmab.meshPoint.isApprox( mab ) );
124 REQUIRE( dmab.flags == Geometry::FlagsInternal::HIT_AB );
127 auto dmac = Geometry::pointToTriSq( mac, a, b, c );
128 REQUIRE( Math::areApproxEqual( dmac.distanceSquared, 0_ra ) );
129 REQUIRE( dmac.meshPoint.isApprox( mac ) );
130 REQUIRE( dmac.flags == Geometry::FlagsInternal::HIT_CA );
133 auto dmbc = Geometry::pointToTriSq( mbc, a, b, c );
134 REQUIRE( Math::areApproxEqual( dmbc.distanceSquared, 0_ra ) );
135 REQUIRE( dmbc.meshPoint.isApprox( mbc ) );
136 REQUIRE( dmbc.flags == Geometry::FlagsInternal::HIT_BC );
139 SECTION(
"Triangle queries: Test point inside the triangle" ) {
140 Vector3 g = ( 1_ra / 3_ra ) * ( a + b + c );
142 auto dg = Geometry::pointToTriSq( g, a, b, c );
144 REQUIRE( Math::areApproxEqual( dg.distanceSquared, 0_ra ) );
145 REQUIRE( dg.meshPoint.isApprox( g ) );
146 REQUIRE( dg.flags == Geometry::FlagsInternal::HIT_FACE );
This namespace contains everything "low level", related to data, datastuctures, and computation.