File indexing completed on 2025-01-19 09:23:34
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0014
0015 #include <cfloat>
0016 #include <cmath>
0017 #include <iterator>
0018 #include <vector>
0019
0020 namespace Acts {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 class BoundaryCheck {
0038 public:
0039
0040 explicit BoundaryCheck(bool check);
0041
0042
0043
0044
0045
0046
0047
0048 BoundaryCheck(bool checkLocal0, bool checkLocal1, double tolerance0 = 0,
0049 double tolerance1 = 0);
0050
0051
0052
0053
0054
0055 BoundaryCheck(const SquareMatrix2& localCovariance, double sigmaMax = 1);
0056
0057 bool isEnabled() const { return m_type != Type::eNone; }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 template <typename Vector2Container>
0070 bool isInside(const Vector2& point, const Vector2Container& vertices) const;
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 bool isInside(const Vector2& point, const Vector2& lowerLeft,
0081 const Vector2& upperRight) const;
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename Vector2Container>
0095 double distance(const Vector2& point, const Vector2Container& vertices) const;
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 double distance(const Vector2& point, const Vector2& lowerLeft,
0107 const Vector2& upperRight) const;
0108
0109 enum class Type {
0110 eNone,
0111 eAbsolute,
0112 eChi2
0113 };
0114
0115
0116 Type type() const;
0117
0118
0119 const Vector2& tolerance() const;
0120
0121
0122 SquareMatrix2 covariance() const;
0123
0124 private:
0125
0126
0127
0128
0129 BoundaryCheck transformed(const ActsMatrix<2, 2>& jacobian) const;
0130
0131
0132 bool isTolerated(const Vector2& delta) const;
0133
0134
0135 double squaredNorm(const Vector2& x) const;
0136
0137
0138 template <typename Vector2Container>
0139 Vector2 computeClosestPointOnPolygon(const Vector2& point,
0140 const Vector2Container& vertices) const;
0141
0142
0143 SquareMatrix2 m_weight;
0144
0145
0146 Vector2 m_tolerance;
0147 Type m_type;
0148
0149
0150 friend class CylinderBounds;
0151 friend class RectangleBounds;
0152
0153 friend class CylinderBounds;
0154 friend class DiscTrapezoidBounds;
0155
0156 friend class EllipseBounds;
0157 };
0158
0159 }
0160
0161 inline Acts::BoundaryCheck::Type Acts::BoundaryCheck::type() const {
0162 return m_type;
0163 }
0164
0165 inline const Acts::Vector2& Acts::BoundaryCheck::tolerance() const {
0166 return m_tolerance;
0167 }
0168
0169 inline Acts::SquareMatrix2 Acts::BoundaryCheck::covariance() const {
0170 return m_weight.inverse();
0171 }
0172
0173 inline Acts::BoundaryCheck::BoundaryCheck(bool check)
0174 : m_weight(SquareMatrix2::Identity()),
0175 m_tolerance(0, 0),
0176 m_type(check ? Type::eAbsolute : Type::eNone) {}
0177
0178 inline Acts::BoundaryCheck::BoundaryCheck(bool checkLocal0, bool checkLocal1,
0179 double tolerance0, double tolerance1)
0180 : m_weight(SquareMatrix2::Identity()),
0181 m_tolerance(checkLocal0 ? tolerance0 : DBL_MAX,
0182 checkLocal1 ? tolerance1 : DBL_MAX),
0183 m_type(Type::eAbsolute) {}
0184
0185 inline Acts::BoundaryCheck::BoundaryCheck(const SquareMatrix2& localCovariance,
0186 double sigmaMax)
0187 : m_weight(localCovariance.inverse()),
0188 m_tolerance(sigmaMax, 0),
0189 m_type(Type::eChi2) {}
0190
0191 inline Acts::BoundaryCheck Acts::BoundaryCheck::transformed(
0192 const ActsMatrix<2, 2>& jacobian) const {
0193 BoundaryCheck bc = *this;
0194 if (m_type == Type::eAbsolute) {
0195
0196
0197 bc.m_tolerance = (jacobian * m_tolerance).cwiseAbs();
0198 } else {
0199 bc.m_weight =
0200 (jacobian * m_weight.inverse() * jacobian.transpose()).inverse();
0201 }
0202 return bc;
0203 }
0204
0205 template <typename Vector2Container>
0206 inline bool Acts::BoundaryCheck::isInside(
0207 const Vector2& point, const Vector2Container& vertices) const {
0208 if (m_type == Type::eNone) {
0209
0210 return true;
0211 } else if (detail::VerticesHelper::isInsidePolygon(point, vertices)) {
0212
0213 return true;
0214 } else if (m_tolerance == Vector2(0., 0.)) {
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 return false;
0226 } else {
0227
0228
0229 auto closestPoint = computeClosestPointOnPolygon(point, vertices);
0230 return isTolerated(closestPoint - point);
0231 }
0232 }
0233
0234 inline bool Acts::BoundaryCheck::isInside(const Vector2& point,
0235 const Vector2& lowerLeft,
0236 const Vector2& upperRight) const {
0237 if (detail::VerticesHelper::isInsideRectangle(point, lowerLeft, upperRight)) {
0238 return true;
0239 } else {
0240 Vector2 closestPoint;
0241
0242 if (m_type == Type::eNone || m_type == Type::eAbsolute) {
0243
0244 closestPoint =
0245 detail::VerticesHelper::computeEuclideanClosestPointOnRectangle(
0246 point, lowerLeft, upperRight);
0247
0248 } else {
0249
0250 Vector2 vertices[] = {{lowerLeft[0], lowerLeft[1]},
0251 {upperRight[0], lowerLeft[1]},
0252 {upperRight[0], upperRight[1]},
0253 {lowerLeft[0], upperRight[1]}};
0254 closestPoint = computeClosestPointOnPolygon(point, vertices);
0255 }
0256
0257 return isTolerated(closestPoint - point);
0258 }
0259 }
0260
0261 template <typename Vector2Container>
0262 inline double Acts::BoundaryCheck::distance(
0263 const Acts::Vector2& point, const Vector2Container& vertices) const {
0264
0265 double d = squaredNorm(point - computeClosestPointOnPolygon(point, vertices));
0266 d = std::sqrt(d);
0267 return detail::VerticesHelper::isInsidePolygon(point, vertices) ? -d : d;
0268 }
0269
0270 inline double Acts::BoundaryCheck::distance(const Acts::Vector2& point,
0271 const Vector2& lowerLeft,
0272 const Vector2& upperRight) const {
0273 if (m_type == Type::eNone || m_type == Type::eAbsolute) {
0274
0275 double d = (point -
0276 detail::VerticesHelper::computeEuclideanClosestPointOnRectangle(
0277 point, lowerLeft, upperRight))
0278 .norm();
0279 return detail::VerticesHelper::isInsideRectangle(point, lowerLeft,
0280 upperRight)
0281 ? -d
0282 : d;
0283
0284 } else {
0285 Vector2 vertices[] = {{lowerLeft[0], lowerLeft[1]},
0286 {upperRight[0], lowerLeft[1]},
0287 {upperRight[0], upperRight[1]},
0288 {lowerLeft[0], upperRight[1]}};
0289 return distance(point, vertices);
0290 }
0291 }
0292
0293 inline bool Acts::BoundaryCheck::isTolerated(const Vector2& delta) const {
0294 if (m_type == Type::eNone) {
0295 return true;
0296 } else if (m_type == Type::eAbsolute) {
0297 return (std::abs(delta[0]) <= m_tolerance[0]) &&
0298 (std::abs(delta[1]) <= m_tolerance[1]);
0299 } else {
0300
0301 return (squaredNorm(delta) < (2 * m_tolerance[0]));
0302 }
0303 }
0304
0305 inline double Acts::BoundaryCheck::squaredNorm(const Vector2& x) const {
0306 return (x.transpose() * m_weight * x).value();
0307 }
0308
0309 template <typename Vector2Container>
0310 inline Acts::Vector2 Acts::BoundaryCheck::computeClosestPointOnPolygon(
0311 const Acts::Vector2& point, const Vector2Container& vertices) const {
0312 return detail::VerticesHelper::computeClosestPointOnPolygon(point, vertices,
0313 m_weight);
0314 }