File indexing completed on 2025-01-18 09:11:11
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
0020 #include <boost/container/static_vector.hpp>
0021
0022 namespace Acts {
0023
0024
0025 enum class IntersectionStatus : int {
0026 unreachable = 0,
0027 reachable = 1,
0028 onSurface = 2
0029 };
0030
0031
0032 inline std::ostream& operator<<(std::ostream& os, IntersectionStatus status) {
0033 constexpr static std::array<const char*, 3> names = {
0034 {"missed/unreachable", "reachable", "onSurface"}};
0035
0036 os << names[static_cast<std::size_t>(status)];
0037 return os;
0038 }
0039
0040
0041
0042
0043 template <unsigned int DIM>
0044 class Intersection {
0045 public:
0046
0047 using Position = ActsVector<DIM>;
0048
0049
0050
0051
0052
0053
0054 constexpr Intersection(const Position& position, double pathLength,
0055 IntersectionStatus status)
0056 : m_position(position), m_pathLength(pathLength), m_status(status) {}
0057
0058
0059 constexpr bool isValid() const {
0060 return m_status != IntersectionStatus::unreachable;
0061 }
0062
0063
0064 constexpr const Position& position() const { return m_position; }
0065
0066
0067 constexpr double pathLength() const { return m_pathLength; }
0068
0069
0070 constexpr IntersectionStatus status() const { return m_status; }
0071
0072
0073 constexpr static Intersection invalid() { return Intersection(); }
0074
0075
0076
0077 constexpr static bool pathLengthOrder(const Intersection& aIntersection,
0078 const Intersection& bIntersection) {
0079 auto a = aIntersection.pathLength();
0080 auto b = bIntersection.pathLength();
0081 return a < b;
0082 }
0083
0084
0085
0086 constexpr static bool closestOrder(const Intersection& aIntersection,
0087 const Intersection& bIntersection) {
0088 if ((aIntersection.status() == IntersectionStatus::unreachable) &&
0089 (bIntersection.status() != IntersectionStatus::unreachable)) {
0090 return false;
0091 }
0092 if ((aIntersection.status() != IntersectionStatus::unreachable) &&
0093 (bIntersection.status() == IntersectionStatus::unreachable)) {
0094 return true;
0095 }
0096
0097 auto a = aIntersection.pathLength();
0098 auto b = bIntersection.pathLength();
0099 return std::abs(a) < std::abs(b);
0100 }
0101
0102
0103
0104 constexpr static bool closestForwardOrder(const Intersection& aIntersection,
0105 const Intersection& bIntersection) {
0106 auto a = aIntersection.pathLength();
0107 auto b = bIntersection.pathLength();
0108 return std::signbit(a) == std::signbit(b) ? std::abs(a) < std::abs(b)
0109 : a > b;
0110 }
0111
0112 private:
0113
0114 Position m_position = Position::Zero();
0115
0116 double m_pathLength = std::numeric_limits<double>::infinity();
0117
0118 IntersectionStatus m_status = IntersectionStatus::unreachable;
0119
0120 constexpr Intersection() = default;
0121 };
0122
0123 using Intersection2D = Intersection<2>;
0124 using Intersection3D = Intersection<3>;
0125
0126 static constexpr std::uint8_t s_maximumNumberOfIntersections = 2;
0127 using MultiIntersection3D =
0128 boost::container::static_vector<Intersection3D,
0129 s_maximumNumberOfIntersections>;
0130
0131 template <typename object_t>
0132 class ObjectIntersection {
0133 public:
0134
0135
0136
0137
0138
0139 constexpr ObjectIntersection(const Intersection3D& intersection,
0140 const object_t* object, std::uint8_t index = 0)
0141 : m_intersection(intersection), m_object(object), m_index(index) {}
0142
0143
0144 constexpr bool isValid() const { return m_intersection.isValid(); }
0145
0146
0147 constexpr const Intersection3D& intersection() const {
0148 return m_intersection;
0149 }
0150
0151
0152 constexpr const Intersection3D::Position& position() const {
0153 return m_intersection.position();
0154 }
0155
0156
0157 constexpr double pathLength() const { return m_intersection.pathLength(); }
0158
0159
0160 constexpr IntersectionStatus status() const {
0161 return m_intersection.status();
0162 }
0163
0164
0165 constexpr const object_t* object() const { return m_object; }
0166
0167 constexpr std::uint8_t index() const { return m_index; }
0168
0169 constexpr static ObjectIntersection invalid(
0170 const object_t* object = nullptr) {
0171 return ObjectIntersection(Intersection3D::invalid(), object);
0172 }
0173
0174 constexpr static bool pathLengthOrder(
0175 const ObjectIntersection& aIntersection,
0176 const ObjectIntersection& bIntersection) {
0177 return Intersection3D::pathLengthOrder(aIntersection.intersection(),
0178 bIntersection.intersection());
0179 }
0180
0181 constexpr static bool closestOrder(const ObjectIntersection& aIntersection,
0182 const ObjectIntersection& bIntersection) {
0183 return Intersection3D::closestOrder(aIntersection.intersection(),
0184 bIntersection.intersection());
0185 }
0186
0187 constexpr static bool closestForwardOrder(
0188 const ObjectIntersection& aIntersection,
0189 const ObjectIntersection& bIntersection) {
0190 return Intersection3D::closestForwardOrder(aIntersection.intersection(),
0191 bIntersection.intersection());
0192 }
0193
0194 private:
0195
0196 Intersection3D m_intersection = Intersection3D::invalid();
0197
0198 const object_t* m_object = nullptr;
0199
0200 std::uint8_t m_index = 0;
0201
0202 constexpr ObjectIntersection() = default;
0203 };
0204
0205 template <typename object_t>
0206 class ObjectMultiIntersection {
0207 public:
0208 using SplitIntersections =
0209 boost::container::static_vector<ObjectIntersection<object_t>,
0210 s_maximumNumberOfIntersections>;
0211
0212
0213
0214
0215
0216 constexpr ObjectMultiIntersection(const MultiIntersection3D& intersections,
0217 const object_t* object)
0218 : m_intersections(intersections), m_object(object) {}
0219
0220 constexpr ObjectIntersection<object_t> operator[](std::uint8_t index) const {
0221 return {m_intersections[index], m_object, index};
0222 }
0223
0224 constexpr const MultiIntersection3D& intersections() const {
0225 return m_intersections;
0226 }
0227
0228 constexpr std::size_t size() const { return m_intersections.size(); }
0229
0230 constexpr const object_t* object() const { return m_object; }
0231
0232 constexpr SplitIntersections split() const {
0233 SplitIntersections result;
0234 for (std::size_t i = 0; i < size(); ++i) {
0235 result.push_back(operator[](i));
0236 }
0237 return result;
0238 }
0239
0240 constexpr ObjectIntersection<object_t> closest() const {
0241 auto splitIntersections = split();
0242 return *std::min_element(splitIntersections.begin(),
0243 splitIntersections.end(),
0244 ObjectIntersection<object_t>::closestOrder);
0245 }
0246
0247 constexpr ObjectIntersection<object_t> closestForward() const {
0248 auto splitIntersections = split();
0249 return *std::min_element(splitIntersections.begin(),
0250 splitIntersections.end(),
0251 ObjectIntersection<object_t>::closestForwardOrder);
0252 }
0253
0254 private:
0255
0256 MultiIntersection3D m_intersections;
0257
0258 const object_t* m_object = nullptr;
0259 };
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 }