File indexing completed on 2025-07-06 07:51:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/Logger.hpp"
0013
0014 #include <algorithm>
0015 #include <array>
0016 #include <cstddef>
0017 #include <cstdint>
0018 #include <limits>
0019 #include <span>
0020 #include <type_traits>
0021
0022 #include <boost/container/static_vector.hpp>
0023
0024 namespace Acts {
0025
0026
0027 enum class IntersectionStatus : int {
0028 unreachable = 0,
0029 reachable = 1,
0030 onSurface = 2
0031 };
0032
0033
0034 inline std::ostream& operator<<(std::ostream& os, IntersectionStatus status) {
0035 constexpr static std::array<const char*, 3> names = {
0036 {"missed/unreachable", "reachable", "onSurface"}};
0037
0038 os << names[static_cast<std::size_t>(status)];
0039 return os;
0040 }
0041
0042
0043
0044
0045 template <unsigned int DIM>
0046 class Intersection {
0047 public:
0048
0049 using Position = Eigen::Map<const ActsVector<DIM>>;
0050
0051
0052
0053
0054
0055
0056 constexpr Intersection(const ActsVector<DIM>& position, double pathLength,
0057 IntersectionStatus status) noexcept
0058 : Intersection(std::span<const double, DIM>{position.data(), DIM},
0059 pathLength, status) {}
0060
0061 constexpr Intersection(const Position& position, double pathLength,
0062 IntersectionStatus status) noexcept
0063 : Intersection(std::span<const double, DIM>{position.data(), DIM},
0064 pathLength, status) {}
0065
0066 constexpr Intersection(std::span<const double, DIM> position,
0067 double pathLength, IntersectionStatus status) noexcept
0068 : m_pathLength(pathLength), m_status(status) {
0069 std::ranges::copy(position, m_position.begin());
0070 }
0071
0072 Intersection(const Intersection&) noexcept = default;
0073 Intersection(Intersection&&) noexcept = default;
0074 Intersection& operator=(const Intersection&) noexcept = default;
0075 Intersection& operator=(Intersection&&) noexcept = default;
0076
0077
0078 constexpr bool isValid() const {
0079 return m_status != IntersectionStatus::unreachable;
0080 }
0081
0082
0083 constexpr Position position() const { return Position{m_position.data()}; }
0084
0085
0086 constexpr double pathLength() const { return m_pathLength; }
0087
0088
0089 constexpr IntersectionStatus status() const { return m_status; }
0090
0091
0092 constexpr static Intersection invalid() { return Intersection(); }
0093
0094
0095
0096 constexpr static bool pathLengthOrder(const Intersection& aIntersection,
0097 const Intersection& bIntersection) {
0098 auto a = aIntersection.pathLength();
0099 auto b = bIntersection.pathLength();
0100 return a < b;
0101 }
0102
0103
0104
0105 constexpr static bool closestOrder(const Intersection& aIntersection,
0106 const Intersection& bIntersection) {
0107 if ((aIntersection.status() == IntersectionStatus::unreachable) &&
0108 (bIntersection.status() != IntersectionStatus::unreachable)) {
0109 return false;
0110 }
0111 if ((aIntersection.status() != IntersectionStatus::unreachable) &&
0112 (bIntersection.status() == IntersectionStatus::unreachable)) {
0113 return true;
0114 }
0115
0116 auto a = aIntersection.pathLength();
0117 auto b = bIntersection.pathLength();
0118 return std::abs(a) < std::abs(b);
0119 }
0120
0121
0122
0123 constexpr static bool closestForwardOrder(const Intersection& aIntersection,
0124 const Intersection& bIntersection) {
0125 auto a = aIntersection.pathLength();
0126 auto b = bIntersection.pathLength();
0127 return std::signbit(a) == std::signbit(b) ? std::abs(a) < std::abs(b)
0128 : a > b;
0129 }
0130
0131 private:
0132
0133 std::array<double, DIM> m_position{};
0134
0135 double m_pathLength = std::numeric_limits<double>::infinity();
0136
0137 IntersectionStatus m_status = IntersectionStatus::unreachable;
0138
0139 constexpr Intersection() = default;
0140 };
0141
0142 using Intersection2D = Intersection<2>;
0143 using Intersection3D = Intersection<3>;
0144
0145 static_assert(std::is_trivially_move_constructible_v<Intersection2D>);
0146 static_assert(std::is_trivially_copy_constructible_v<Intersection2D>);
0147 static_assert(std::is_trivially_move_assignable_v<Intersection2D>);
0148
0149 static constexpr std::uint8_t s_maximumNumberOfIntersections = 2;
0150 using MultiIntersection3D =
0151 boost::container::static_vector<Intersection3D,
0152 s_maximumNumberOfIntersections>;
0153
0154 template <typename object_t>
0155 class ObjectIntersection {
0156 public:
0157
0158
0159
0160
0161
0162 constexpr ObjectIntersection(const Intersection3D& intersection,
0163 const object_t* object,
0164 std::uint8_t index = 0) noexcept
0165 : m_intersection(intersection), m_object(object), m_index(index) {}
0166
0167 ObjectIntersection(const ObjectIntersection&) noexcept = default;
0168 ObjectIntersection(ObjectIntersection&&) noexcept = default;
0169 ObjectIntersection& operator=(const ObjectIntersection&) noexcept = default;
0170 ObjectIntersection& operator=(ObjectIntersection&&) noexcept = default;
0171
0172
0173 constexpr bool isValid() const { return m_intersection.isValid(); }
0174
0175
0176 constexpr const Intersection3D& intersection() const {
0177 return m_intersection;
0178 }
0179
0180
0181 Intersection3D::Position position() const {
0182 return m_intersection.position();
0183 }
0184
0185
0186 constexpr double pathLength() const { return m_intersection.pathLength(); }
0187
0188
0189 constexpr IntersectionStatus status() const {
0190 return m_intersection.status();
0191 }
0192
0193
0194 constexpr const object_t* object() const { return m_object; }
0195
0196 constexpr std::uint8_t index() const { return m_index; }
0197
0198 constexpr static ObjectIntersection invalid(
0199 const object_t* object = nullptr) {
0200 return ObjectIntersection(Intersection3D::invalid(), object);
0201 }
0202
0203 constexpr static bool pathLengthOrder(
0204 const ObjectIntersection& aIntersection,
0205 const ObjectIntersection& bIntersection) {
0206 return Intersection3D::pathLengthOrder(aIntersection.intersection(),
0207 bIntersection.intersection());
0208 }
0209
0210 constexpr static bool closestOrder(const ObjectIntersection& aIntersection,
0211 const ObjectIntersection& bIntersection) {
0212 return Intersection3D::closestOrder(aIntersection.intersection(),
0213 bIntersection.intersection());
0214 }
0215
0216 constexpr static bool closestForwardOrder(
0217 const ObjectIntersection& aIntersection,
0218 const ObjectIntersection& bIntersection) {
0219 return Intersection3D::closestForwardOrder(aIntersection.intersection(),
0220 bIntersection.intersection());
0221 }
0222
0223 private:
0224
0225 Intersection3D m_intersection = Intersection3D::invalid();
0226
0227 const object_t* m_object = nullptr;
0228
0229 std::uint8_t m_index = 0;
0230
0231 constexpr ObjectIntersection() = default;
0232 };
0233
0234 static_assert(std::is_trivially_move_constructible_v<ObjectIntersection<int>>);
0235 static_assert(std::is_trivially_move_assignable_v<ObjectIntersection<int>>);
0236
0237 template <typename object_t>
0238 class ObjectMultiIntersection {
0239 public:
0240 using SplitIntersections =
0241 boost::container::static_vector<ObjectIntersection<object_t>,
0242 s_maximumNumberOfIntersections>;
0243
0244
0245
0246
0247
0248 constexpr ObjectMultiIntersection(const MultiIntersection3D& intersections,
0249 const object_t* object)
0250 : m_intersections(intersections), m_object(object) {}
0251
0252 constexpr ObjectIntersection<object_t> operator[](std::uint8_t index) const {
0253 return {m_intersections[index], m_object, index};
0254 }
0255
0256 constexpr const MultiIntersection3D& intersections() const {
0257 return m_intersections;
0258 }
0259
0260 constexpr std::size_t size() const { return m_intersections.size(); }
0261
0262 constexpr const object_t* object() const { return m_object; }
0263
0264 constexpr SplitIntersections split() const {
0265 SplitIntersections result;
0266 for (std::size_t i = 0; i < size(); ++i) {
0267 result.push_back(operator[](i));
0268 }
0269 return result;
0270 }
0271
0272 constexpr ObjectIntersection<object_t> closest() const {
0273 auto splitIntersections = split();
0274 return *std::min_element(splitIntersections.begin(),
0275 splitIntersections.end(),
0276 ObjectIntersection<object_t>::closestOrder);
0277 }
0278
0279 constexpr ObjectIntersection<object_t> closestForward() const {
0280 auto splitIntersections = split();
0281 return *std::min_element(splitIntersections.begin(),
0282 splitIntersections.end(),
0283 ObjectIntersection<object_t>::closestForwardOrder);
0284 }
0285
0286 private:
0287
0288 MultiIntersection3D m_intersections;
0289
0290 const object_t* m_object = nullptr;
0291 };
0292
0293 namespace detail {
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 bool checkPathLength(double pathLength, double nearLimit, double farLimit,
0304 const Logger& logger = getDummyLogger());
0305
0306 }
0307
0308 }