Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:03

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