Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-06 08:07:47

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2024 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0012 
0013 namespace Acts::detail {
0014 
0015 /// Check if a point is inside a box.
0016 ///
0017 /// @param lowerLeft The lower left corner of the box.
0018 /// @param upperRight The upper right corner of the box.
0019 /// @param tolerance The tolerance to use.
0020 /// @param point The point to check.
0021 /// @param jacobianOpt The Jacobian to transform the distance to Cartesian
0022 ///
0023 /// @return True if the point is inside the box.
0024 inline bool insideAlignedBox(const Vector2& lowerLeft,
0025                              const Vector2& upperRight,
0026                              const BoundaryTolerance& tolerance,
0027                              const Vector2& point,
0028                              const std::optional<SquareMatrix2>& jacobianOpt) {
0029   if (tolerance.isInfinite()) {
0030     return true;
0031   }
0032 
0033   if (detail::VerticesHelper::isInsideRectangle(point, lowerLeft, upperRight)) {
0034     return true;
0035   }
0036 
0037   if (!tolerance.hasTolerance()) {
0038     return false;
0039   }
0040 
0041   Vector2 closestPoint;
0042 
0043   if (!tolerance.hasMetric(jacobianOpt.has_value())) {
0044     closestPoint =
0045         detail::VerticesHelper::computeEuclideanClosestPointOnRectangle(
0046             point, lowerLeft, upperRight);
0047   } else {
0048     // TODO there might be a more optimal way to compute the closest point to a
0049     // box with metric
0050 
0051     std::array<Vector2, 4> vertices = {{lowerLeft,
0052                                         {upperRight[0], lowerLeft[1]},
0053                                         upperRight,
0054                                         {lowerLeft[0], upperRight[1]}}};
0055 
0056     SquareMatrix2 metric = tolerance.getMetric(jacobianOpt);
0057 
0058     closestPoint = detail::VerticesHelper::computeClosestPointOnPolygon(
0059         point, vertices, metric);
0060   }
0061 
0062   Vector2 distance = closestPoint - point;
0063 
0064   return tolerance.isTolerated(distance, jacobianOpt);
0065 }
0066 
0067 /// Check if a point is inside a polygon.
0068 ///
0069 /// @param vertices The vertices of the polygon.
0070 /// @param tolerance The tolerance to use.
0071 /// @param point The point to check.
0072 /// @param jacobianOpt The Jacobian to transform the distance to Cartesian
0073 ///
0074 /// @return True if the point is inside the polygon.
0075 template <typename Vector2Container>
0076 inline bool insidePolygon(const Vector2Container& vertices,
0077                           const BoundaryTolerance& tolerance,
0078                           const Vector2& point,
0079                           const std::optional<SquareMatrix2>& jacobianOpt) {
0080   if (tolerance.isInfinite()) {
0081     // The null boundary check always succeeds
0082     return true;
0083   }
0084 
0085   if (detail::VerticesHelper::isInsidePolygon(point, vertices)) {
0086     // If the point falls inside the polygon, the check always succeeds
0087     return true;
0088   }
0089 
0090   if (!tolerance.hasTolerance()) {
0091     // Outside of the polygon, since we've eliminated the case of an absence of
0092     // check above, we know we'll always fail if the tolerance is zero.
0093     //
0094     // This allows us to avoid the expensive computeClosestPointOnPolygon
0095     // computation in this simple case.
0096     return false;
0097   }
0098 
0099   // TODO: When tolerance is not 0, we could also avoid this computation in
0100   //       some cases by testing against a bounding box of the polygon, padded
0101   //       on each side with our tolerance. Check if this optimization is
0102   //       worthwhile in some production workflows, and if so implement it.
0103 
0104   SquareMatrix2 metric = tolerance.getMetric(jacobianOpt);
0105 
0106   // We are outside of the polygon, but there is a tolerance. Must find what
0107   // the closest point on the polygon is and check if it's within tolerance.
0108   auto closestPoint = detail::VerticesHelper::computeClosestPointOnPolygon(
0109       point, vertices, metric);
0110 
0111   Vector2 distance = closestPoint - point;
0112 
0113   return tolerance.isTolerated(distance, jacobianOpt);
0114 }
0115 
0116 }  // namespace Acts::detail