|
17 | 17 | #include <misc/ArborX_Vector.hpp>
|
18 | 18 |
|
19 | 19 | #include <Kokkos_Array.hpp>
|
| 20 | +#include <Kokkos_Clamp.hpp> |
20 | 21 | #include <Kokkos_MathematicalFunctions.hpp>
|
21 | 22 |
|
22 | 23 | namespace ArborX::Details
|
@@ -550,6 +551,53 @@ struct intersects<PointTag, EllipsoidTag, Point, Ellipsoid>
|
550 | 551 | }
|
551 | 552 | };
|
552 | 553 |
|
| 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 | + |
553 | 601 | } // namespace Dispatch
|
554 | 602 |
|
555 | 603 | } // namespace ArborX::Details
|
|
0 commit comments