Skip to content

Commit a6109b2

Browse files
committed
Add intersects ellipsoid-segment
1 parent a1c6690 commit a6109b2

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/geometry/algorithms/ArborX_Intersects.hpp

+48
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <misc/ArborX_Vector.hpp>
1818

1919
#include <Kokkos_Array.hpp>
20+
#include <Kokkos_Clamp.hpp>
2021
#include <Kokkos_MathematicalFunctions.hpp>
2122

2223
namespace ArborX::Details
@@ -550,6 +551,53 @@ struct intersects<PointTag, EllipsoidTag, Point, Ellipsoid>
550551
}
551552
};
552553

554+
template <typename Ellipsoid, typename Segment>
555+
struct intersects<EllipsoidTag, SegmentTag, Ellipsoid, Segment>
556+
{
557+
KOKKOS_FUNCTION static constexpr bool apply(Ellipsoid const &ellipsoid,
558+
Segment const &segment)
559+
{
560+
// Preliminaries:
561+
// - parametric segment formula: a + t(b-a)
562+
// - ellipsoid formula: (x-c)^T R (x-c) <= 1
563+
//
564+
// Steps:
565+
// - shift coordinates so that ellipsoid center is at origin
566+
// new segment formula: a-c + t(b-a)
567+
// new ellipsoid formula: x^T R x <= 1
568+
// - substitute segment parametric equation into ellipsoid formula
569+
// - find the value of t minimizing it
570+
// t = -(R(b-a), a-c) / (R(b-a), b-a)
571+
// - clamp t to [0, 1]
572+
// - Plug the resulting point into ellipsoid equation
573+
auto const &rmt = ellipsoid.rmt();
574+
575+
auto ab = segment.b - segment.a;
576+
auto ca = segment.a - ellipsoid.centroid();
577+
578+
// At^2 + 2B^t + C
579+
auto A = rmt_multiply(ab, rmt, ab);
580+
auto B = rmt_multiply(ab, rmt, ca);
581+
auto C = rmt_multiply(ca, rmt, ca);
582+
auto t = -B / A;
583+
584+
using Float = coordinate_type_t<Segment>;
585+
t = Kokkos::clamp(t, (Float)0, (Float)1);
586+
587+
return A * t * t + 2 * B * t + C <= 1;
588+
}
589+
};
590+
591+
template <typename Segment, typename Ellipsoid>
592+
struct intersects<SegmentTag, EllipsoidTag, Segment, Ellipsoid>
593+
{
594+
KOKKOS_FUNCTION static constexpr bool apply(Segment const &segment,
595+
Ellipsoid const &ellipsoid)
596+
{
597+
return Details::intersects(ellipsoid, segment);
598+
}
599+
};
600+
553601
} // namespace Dispatch
554602

555603
} // namespace ArborX::Details

test/tstDetailsAlgorithms.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,13 @@ BOOST_AUTO_TEST_CASE(intersects)
357357
BOOST_TEST(!intersects(ellipse, Point2{1.f, 0.29f}));
358358
BOOST_TEST(intersects(ellipse, Point2{1.f, 1.69f}));
359359
BOOST_TEST(intersects(ellipse, Point2{1.f, 1.70f}));
360+
361+
BOOST_TEST(intersects(ellipse, Segment2{{-1, 1}, {1, -1}}));
362+
BOOST_TEST(!intersects(ellipse, Segment2{{-1.1, 1}, {1, -1}}));
363+
BOOST_TEST(intersects(ellipse, Segment2{{0, 0}, {0, 1}}));
364+
BOOST_TEST(intersects(ellipse, Segment2{{0.5, 0.5}, {1.5, 1.5}}));
365+
BOOST_TEST(intersects(ellipse, Segment2{{0.0, 1.9}, {3.0, 1.9}}));
366+
BOOST_TEST(!intersects(ellipse, Segment2{{2.1, 0}, {2.1, 3}}));
360367
}
361368

362369
BOOST_AUTO_TEST_CASE(equals)

0 commit comments

Comments
 (0)