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