File indexing completed on 2025-12-04 09:15:37
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 namespace Acts {
0023
0024
0025 enum class IntersectionStatus : int {
0026 unreachable = 0,
0027 reachable = 1,
0028 onSurface = 2
0029 };
0030
0031
0032
0033
0034
0035 inline std::ostream& operator<<(std::ostream& os, IntersectionStatus status) {
0036 constexpr static std::array<const char*, 3> names = {
0037 {"missed/unreachable", "reachable", "onSurface"}};
0038
0039 os << names[static_cast<std::size_t>(status)];
0040 return os;
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
0062
0063
0064
0065 constexpr Intersection(const Position& position, double pathLength,
0066 IntersectionStatus status) noexcept
0067 : Intersection(std::span<const double, DIM>{position.data(), DIM},
0068 pathLength, status) {}
0069
0070
0071
0072
0073
0074 constexpr Intersection(std::span<const double, DIM> position,
0075 double pathLength, IntersectionStatus status) noexcept
0076 : m_pathLength(pathLength), m_status(status) {
0077 std::ranges::copy(position, m_position.begin());
0078 }
0079
0080
0081 constexpr Intersection(const Intersection&) noexcept = default;
0082
0083 constexpr Intersection(Intersection&&) noexcept = default;
0084
0085
0086 constexpr Intersection& operator=(const Intersection&) noexcept = default;
0087
0088
0089 constexpr Intersection& operator=(Intersection&&) noexcept = default;
0090
0091
0092
0093 constexpr bool isValid() const noexcept {
0094 return m_status != IntersectionStatus::unreachable;
0095 }
0096
0097
0098
0099 Position position() const noexcept { return Position{m_position.data()}; }
0100
0101
0102
0103 constexpr double pathLength() const noexcept { return m_pathLength; }
0104
0105
0106
0107 constexpr IntersectionStatus status() const noexcept { return m_status; }
0108
0109
0110
0111 constexpr static Intersection Invalid() noexcept { return Intersection(); }
0112
0113
0114
0115
0116
0117
0118 constexpr static bool pathLengthOrder(
0119 const Intersection& aIntersection,
0120 const Intersection& bIntersection) noexcept {
0121 auto a = aIntersection.pathLength();
0122 auto b = bIntersection.pathLength();
0123 return a < b;
0124 }
0125
0126
0127
0128
0129
0130
0131 constexpr static bool closestOrder(
0132 const Intersection& aIntersection,
0133 const Intersection& bIntersection) noexcept {
0134 using enum IntersectionStatus;
0135
0136 if ((aIntersection.status() == unreachable) &&
0137 (bIntersection.status() != unreachable)) {
0138 return false;
0139 }
0140 if ((aIntersection.status() != unreachable) &&
0141 (bIntersection.status() == unreachable)) {
0142 return true;
0143 }
0144
0145 auto a = aIntersection.pathLength();
0146 auto b = bIntersection.pathLength();
0147 return std::abs(a) < std::abs(b);
0148 }
0149
0150
0151
0152
0153
0154
0155 constexpr static bool closestForwardOrder(
0156 const Intersection& aIntersection,
0157 const Intersection& bIntersection) noexcept {
0158 auto a = aIntersection.pathLength();
0159 auto b = bIntersection.pathLength();
0160 return std::signbit(a) == std::signbit(b) ? std::abs(a) < std::abs(b)
0161 : a > b;
0162 }
0163
0164 private:
0165
0166 std::array<double, DIM> m_position{};
0167
0168 double m_pathLength = std::numeric_limits<double>::infinity();
0169
0170 IntersectionStatus m_status = IntersectionStatus::unreachable;
0171
0172 constexpr Intersection() noexcept = default;
0173 };
0174
0175
0176 using Intersection2D = Intersection<2>;
0177
0178 using Intersection3D = Intersection<3>;
0179
0180 static_assert(std::is_trivially_copy_constructible_v<Intersection2D>);
0181 static_assert(std::is_trivially_move_constructible_v<Intersection2D>);
0182 static_assert(std::is_trivially_move_assignable_v<Intersection2D>);
0183
0184 using IntersectionIndex = std::uint8_t;
0185 static constexpr IntersectionIndex s_maximumNumberOfIntersections = 2;
0186
0187 template <unsigned int DIM>
0188 class MultiIntersection {
0189 public:
0190 using IntersectionType = Intersection<DIM>;
0191 using IndexedIntersection = std::pair<IntersectionType, IntersectionIndex>;
0192
0193 using Container =
0194 std::array<IntersectionType, s_maximumNumberOfIntersections>;
0195
0196 using size_type = IntersectionIndex;
0197
0198 constexpr explicit MultiIntersection(
0199 const IntersectionType& intersection) noexcept
0200 : m_intersections{intersection, IntersectionType::Invalid()}, m_size{1} {}
0201 constexpr MultiIntersection(const IntersectionType& intersection1,
0202 const IntersectionType& intersection2) noexcept
0203 : m_intersections{intersection1, intersection2}, m_size{2} {}
0204
0205 constexpr MultiIntersection(const MultiIntersection&) noexcept = default;
0206 constexpr MultiIntersection(MultiIntersection&&) noexcept = default;
0207 constexpr MultiIntersection& operator=(const MultiIntersection&) noexcept =
0208 default;
0209 constexpr MultiIntersection& operator=(MultiIntersection&&) noexcept =
0210 default;
0211
0212 constexpr const IntersectionType& operator[](IntersectionIndex index) const {
0213 return m_intersections[index];
0214 }
0215
0216 constexpr const IntersectionType& at(IntersectionIndex index) const {
0217 return m_intersections.at(index);
0218 }
0219
0220 constexpr IntersectionIndex size() const noexcept { return m_size; }
0221
0222 constexpr auto begin() const noexcept {
0223 return std::span(m_intersections.data(), m_size).begin();
0224 }
0225 constexpr auto end() const noexcept {
0226 return std::span(m_intersections.data(), m_size).end();
0227 }
0228
0229 constexpr IntersectionType closest() const noexcept {
0230 return closestWithIndex().first;
0231 }
0232 constexpr IndexedIntersection closestWithIndex() const noexcept {
0233 auto min = std::ranges::min_element(m_intersections,
0234 IntersectionType::closestOrder);
0235 return {*min, static_cast<IntersectionIndex>(
0236 std::distance(m_intersections.begin(), min))};
0237 }
0238
0239 constexpr IntersectionType closestForward() const noexcept {
0240 return closestForwardWithIndex().first;
0241 }
0242 constexpr IndexedIntersection closestForwardWithIndex() const noexcept {
0243 auto min = std::ranges::min_element(m_intersections,
0244 IntersectionType::closestForwardOrder);
0245 return {*min, static_cast<IntersectionIndex>(
0246 std::distance(m_intersections.begin(), min))};
0247 }
0248
0249 private:
0250 Container m_intersections{};
0251 IntersectionIndex m_size{};
0252 };
0253
0254 using MultiIntersection2D = MultiIntersection<2>;
0255 using MultiIntersection3D = MultiIntersection<3>;
0256
0257 static_assert(std::is_trivially_copy_constructible_v<MultiIntersection2D>);
0258 static_assert(std::is_trivially_move_constructible_v<MultiIntersection2D>);
0259 static_assert(std::is_trivially_move_assignable_v<MultiIntersection2D>);
0260
0261 namespace detail {
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 bool checkPathLength(double pathLength, double nearLimit, double farLimit,
0272 const Logger& logger = getDummyLogger());
0273
0274 }
0275
0276 }