Skip to content

Commit dbe330f

Browse files
authored
Merge pull request #1256 from aprokop/distance_point_tet
2 parents 44e5f13 + 44e6433 commit dbe330f

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

src/geometry/algorithms/ArborX_Distance.hpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313

1414
#include "ArborX_Equals.hpp"
1515
#include <ArborX_GeometryTraits.hpp>
16+
#include <ArborX_Triangle.hpp>
1617
#include <misc/ArborX_Vector.hpp>
1718

19+
#include <Kokkos_Array.hpp>
1820
#include <Kokkos_Clamp.hpp>
1921
#include <Kokkos_MathematicalFunctions.hpp>
2022
#include <Kokkos_MinMax.hpp>
@@ -198,6 +200,50 @@ struct distance<PointTag, TriangleTag, Point, Triangle>
198200
}
199201
};
200202

203+
// distance point-tetrahedron
204+
template <typename Point, typename Tetrahedron>
205+
struct distance<PointTag, TetrahedronTag, Point, Tetrahedron>
206+
{
207+
static constexpr int DIM = dimension_v<Point>;
208+
using Coordinate = coordinate_type_t<Tetrahedron>;
209+
210+
KOKKOS_FUNCTION static auto apply(Point const &point, Tetrahedron const &tet)
211+
{
212+
static_assert(GeometryTraits::dimension_v<Point> == 3);
213+
214+
constexpr int N = 4;
215+
Kokkos::Array<decltype(tet.a), N> v = {tet.a, tet.b, tet.c, tet.d};
216+
217+
// For every plane check that the vertex lies within the same halfspace as
218+
// the other tetrahedron vertex (similar to the current intersects
219+
// algorithm). If not, compute the distance to the corresponding triangle.
220+
for (int j = 0; j < N; ++j)
221+
{
222+
auto normal = (v[(j + 1) % N] - v[j]).cross(v[(j + 2) % N] - v[j]);
223+
224+
bool same_half_space =
225+
(normal.dot(v[(j + 3) % N] - v[j]) * normal.dot(point - v[j]) >= 0);
226+
if (!same_half_space)
227+
return Details::distance(
228+
point, Triangle{v[j], v[(j + 1) % N], v[(j + 2) % N]});
229+
}
230+
return static_cast<Coordinate>(0);
231+
}
232+
};
233+
234+
// distance tetrahedron-point
235+
template <typename Tetrahedron, typename Point>
236+
struct distance<TetrahedronTag, PointTag, Tetrahedron, Point>
237+
{
238+
static constexpr int DIM = dimension_v<Point>;
239+
using Coordinate = coordinate_type_t<Tetrahedron>;
240+
241+
KOKKOS_FUNCTION static auto apply(Tetrahedron const &tet, Point const &p)
242+
{
243+
return Details::distance(p, tet);
244+
}
245+
};
246+
201247
// distance box-box
202248
template <typename Box1, typename Box2>
203249
struct distance<BoxTag, BoxTag, Box1, Box2>

test/tstDetailsAlgorithms.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,39 @@ BOOST_AUTO_TEST_CASE(distance_point_triangle)
161161
BOOST_TEST(distance(Point3{1, -1, -1}, triangle3_2) == std::sqrt(3.f));
162162
}
163163

164+
BOOST_AUTO_TEST_CASE(distance_point_tetrahedron)
165+
{
166+
using ArborX::Details::distance;
167+
168+
using Point = ArborX::Point<3>;
169+
170+
constexpr ArborX::ExperimentalHyperGeometry::Tetrahedron tet{
171+
Point{0, 0, 0}, Point{1, 0, 0}, Point{0, 1, 0}, Point{0, 0, 1}};
172+
173+
// vertices
174+
BOOST_TEST(distance(Point{0, 0, 0}, tet) == 0);
175+
BOOST_TEST(distance(Point{1, 0, 0}, tet) == 0);
176+
BOOST_TEST(distance(Point{0, 1, 0}, tet) == 0);
177+
BOOST_TEST(distance(Point{0, 0, 1}, tet) == 0);
178+
179+
// inside
180+
BOOST_TEST(distance(Point{0.4f, 0.4f, 0.1f}, tet) == 0);
181+
BOOST_TEST(distance(Point{0.8f, 0.05f, 0.05f}, tet) == 0);
182+
183+
// same plane as some side
184+
BOOST_TEST(distance(Point{2, 0, 0}, tet) == 1);
185+
BOOST_TEST(distance(Point{0.5f, -0.5f, 0}, tet) == 0.5f);
186+
BOOST_TEST(distance(Point{-0.5f, 0.5f, 0}, tet) == 0.5f);
187+
BOOST_TEST(distance(Point{0, 0, 2}, tet) == 1);
188+
BOOST_TEST(distance(Point{0, -0.5f, 0}, tet) == 0.5f);
189+
190+
// outside
191+
BOOST_TEST(distance(Point{-1, -1, -1}, tet) == std::sqrt(3.f));
192+
BOOST_TEST(distance(Point{-1, -1, 2}, tet) == std::sqrt(3.f));
193+
BOOST_TEST(distance(Point{1.5f, 1.5f, -1}, tet) == std::sqrt(3.f));
194+
BOOST_TEST(distance(Point{1.5f, 1.5f, 0.5f}, tet) == 1.5f);
195+
}
196+
164197
BOOST_AUTO_TEST_CASE(distance_box_box)
165198
{
166199
using ArborX::Details::distance;

0 commit comments

Comments
 (0)