Skip to content

Commit 13de0b4

Browse files
committed
Add intersects ellipse-box
1 parent a6109b2 commit 13de0b4

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/geometry/algorithms/ArborX_Intersects.hpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "ArborX_Distance.hpp"
1515
#include "ArborX_Expand.hpp"
1616
#include <ArborX_GeometryTraits.hpp>
17+
#include <ArborX_Segment.hpp>
1718
#include <misc/ArborX_Vector.hpp>
1819

1920
#include <Kokkos_Array.hpp>
@@ -577,7 +578,7 @@ struct intersects<EllipsoidTag, SegmentTag, Ellipsoid, Segment>
577578

578579
// At^2 + 2B^t + C
579580
auto A = rmt_multiply(ab, rmt, ab);
580-
auto B = rmt_multiply(ab, rmt, ca);
581+
auto B = rmt_multiply(ca, rmt, ab);
581582
auto C = rmt_multiply(ca, rmt, ca);
582583
auto t = -B / A;
583584

@@ -598,6 +599,39 @@ struct intersects<SegmentTag, EllipsoidTag, Segment, Ellipsoid>
598599
}
599600
};
600601

602+
template <typename Ellipsoid, typename Box>
603+
struct intersects<EllipsoidTag, BoxTag, Ellipsoid, Box>
604+
{
605+
KOKKOS_FUNCTION static constexpr bool apply(Ellipsoid const &ellipsoid,
606+
Box const &box)
607+
{
608+
static_assert(GeometryTraits::dimension_v<Box> == 2,
609+
"Ellipsoid-box intersection is only implemented for 2D");
610+
611+
auto min_corner = box.minCorner();
612+
auto max_corner = box.maxCorner();
613+
using ::ArborX::Experimental::Segment;
614+
// clang-format off
615+
return
616+
Details::intersects(ellipsoid.centroid(), box) ||
617+
Details::intersects(ellipsoid, Segment{min_corner, {min_corner[0], max_corner[1]}}) ||
618+
Details::intersects(ellipsoid, Segment{min_corner, {max_corner[0], min_corner[1]}}) ||
619+
Details::intersects(ellipsoid, Segment{max_corner, {min_corner[0], max_corner[1]}}) ||
620+
Details::intersects(ellipsoid, Segment{max_corner, {max_corner[0], min_corner[1]}});
621+
// clang-format on
622+
}
623+
};
624+
625+
template <typename Box, typename Ellipsoid>
626+
struct intersects<BoxTag, EllipsoidTag, Box, Ellipsoid>
627+
{
628+
KOKKOS_FUNCTION static constexpr bool apply(Box const &box,
629+
Ellipsoid const &ellipsoid)
630+
{
631+
return Details::intersects(ellipsoid, box);
632+
}
633+
};
634+
601635
} // namespace Dispatch
602636

603637
} // namespace ArborX::Details

test/tstDetailsAlgorithms.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(intersects)
343343
BOOST_TEST(intersects(box2, Segment2{{-1, 2}, {2, -1}}));
344344
BOOST_TEST(!intersects(Segment2{{0.5, 1.6}, {2, 0}}, box2));
345345

346-
// ellipsoid
346+
// ellipsoid [2x^2 - 3xy + 2y^2 <= 1]
347347
using Ellipse = ArborX::Experimental::Ellipsoid<2>;
348348
constexpr Ellipse ellipse{{1.f, 1.f}, {{2.f, -1.5f}, {-1.5f, 2.f}}};
349349
BOOST_TEST(intersects(ellipse, Point2{1.f, 1.f}));
@@ -364,6 +364,20 @@ BOOST_AUTO_TEST_CASE(intersects)
364364
BOOST_TEST(intersects(ellipse, Segment2{{0.5, 0.5}, {1.5, 1.5}}));
365365
BOOST_TEST(intersects(ellipse, Segment2{{0.0, 1.9}, {3.0, 1.9}}));
366366
BOOST_TEST(!intersects(ellipse, Segment2{{2.1, 0}, {2.1, 3}}));
367+
368+
using Box2 = ArborX::Box<2>;
369+
BOOST_TEST(intersects(ellipse, Box2{{-10, -10}, {10, 10}}));
370+
BOOST_TEST(intersects(ellipse, Box2{{0.5, 0.5}, {1.0, 1.0}}));
371+
BOOST_TEST(intersects(ellipse, Box2{{-1, -1}, {0, 0}}));
372+
BOOST_TEST(intersects(ellipse, Box2{{2, 2}, {3, 3}}));
373+
BOOST_TEST(intersects(ellipse, Box2{{-1, -1}, {0, 2}}));
374+
BOOST_TEST(intersects(ellipse, Box2{{-1, -1}, {2, 0}}));
375+
BOOST_TEST(intersects(ellipse, Box2{{2, 1}, {3, 3}}));
376+
BOOST_TEST(intersects(ellipse, Box2{{1, 2}, {3, 3}}));
377+
BOOST_TEST(!intersects(ellipse, Box2{{1.5, 0}, {2, 0.5}}));
378+
BOOST_TEST(!intersects(ellipse, Box2{{-1, -1}, {-0.1, -0.1}}));
379+
BOOST_TEST(!intersects(ellipse, Box2{{0, 1.5}, {0.5, 2}}));
380+
BOOST_TEST(!intersects(ellipse, Box2{{2.1, 2.1}, {3, 3}}));
367381
}
368382

369383
BOOST_AUTO_TEST_CASE(equals)

0 commit comments

Comments
 (0)