Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:01:51

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/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Tolerance.hpp"
0013 
0014 #include <cmath>
0015 #include <numbers>
0016 #include <optional>
0017 #include <span>
0018 #include <utility>
0019 #include <vector>
0020 
0021 /// Helper methods for polyhedron vertices drawing and inside/outside checks.
0022 namespace Acts::detail::VerticesHelper {
0023 
0024 /// A method that inserts the cartesian extrema points and segments
0025 /// a curved segment into sub segments
0026 ///
0027 /// @param phiMin the minimum phi value
0028 /// @param phiMax The second phi value
0029 /// @param phiRef is a vector of reference phi values to be included as well
0030 /// @param quarterSegments number of segments used to approximate a segment quarter
0031 ///
0032 /// @return a vector of generated phi values
0033 std::vector<double> phiSegments(double phiMin = -std::numbers::pi,
0034                                 double phiMax = std::numbers::pi,
0035                                 const std::vector<double>& phiRefs = {},
0036                                 unsigned int quarterSegments = 2u);
0037 
0038 /// Helper method to create a regular 2 or 3 D segment
0039 /// between two phi values with a given number of segments
0040 ///
0041 /// It will insert the phi at extrema points and reference points, it uses
0042 /// a minimum approximation of a circle with 8 segments
0043 ///
0044 /// @tparam vertex_t Type of vertex to be applied
0045 /// @tparam transform_t Optional transform
0046 ///
0047 /// @param rXY The radius description if first +/= second: ellipse
0048 /// @param phiMin the minimum phi value
0049 /// @param phiMax the second phi value
0050 /// @param phiRef is a vector of reference phi values to be included as well
0051 /// @param quarterSegments number of segments used to approximate a segment quarter
0052 /// @param offset The out of plane offset position of the bow
0053 /// @param transform The transform applied (optional)
0054 ///
0055 /// @return a vector of vertices
0056 template <typename vertex_t, typename transform_t>
0057 std::vector<vertex_t> segmentVertices(
0058     std::pair<double, double> rXY, double phiMin, double phiMax,
0059     const std::vector<double>& phiRefs = {}, unsigned int quarterSegments = 2u,
0060     const vertex_t& offset = vertex_t::Zero(),
0061     const transform_t& transform = transform_t::Identity()) {
0062   std::vector<vertex_t> vertices;
0063   std::vector<double> phis =
0064       phiSegments(phiMin, phiMax, phiRefs, quarterSegments);
0065   for (double phi : phis) {
0066     vertex_t vertex = vertex_t::Zero();
0067     vertex(0) = rXY.first * std::cos(phi);
0068     vertex(1) = rXY.second * std::sin(phi);
0069     vertex = vertex + offset;
0070     vertices.push_back(transform * vertex);
0071   }
0072   return vertices;
0073 }
0074 
0075 /// Construct vertices on an ellipse-like bound object.
0076 ///
0077 /// @param innerRx The radius of the inner ellipse (in x), 0 if sector
0078 /// @param innerRy The radius of the inner ellipse (in y), 0 if sector
0079 /// @param outerRx The radius of the outer ellipse (in x)
0080 /// @param outerRy The radius of the outer ellipse (in y)
0081 /// @param avgPhi The phi direction of the center if sector
0082 /// @param halfPhi The half phi sector of the ellipse
0083 /// @param quarterSegments number of segments used to approximate a segment quarter
0084 ///
0085 /// @return a vector of 2d-vectors
0086 std::vector<Vector2> ellipsoidVertices(double innerRx, double innerRy,
0087                                        double outerRx, double outerRy,
0088                                        double avgPhi = 0.,
0089                                        double halfPhi = std::numbers::pi,
0090                                        unsigned int quarterSegments = 2u);
0091 
0092 /// Construct vertices on an disc/wheel-like bound object.
0093 ///
0094 /// @param innerR The radius of the inner circle (sector)
0095 /// @param outerR The radius of the outer circle (sector)
0096 /// @param avgPhi The phi direction of the center if sector
0097 /// @param halfPhi The half phi sector if sector
0098 /// @param quarterSegments number of segments used to approximate a segment quarter
0099 ///
0100 /// @return a vector of 2d-vectors
0101 std::vector<Vector2> circularVertices(double innerR, double outerR,
0102                                       double avgPhi = 0.,
0103                                       double halfPhi = std::numbers::pi,
0104                                       unsigned int quarterSegments = 2u);
0105 
0106 /// Check if the point is inside the polygon w/o any tolerances.
0107 ///
0108 /// @tparam vertex_container_t is an iterable container
0109 ///
0110 /// @param point is the Vector2Type to check
0111 /// @param vertices Forward iterable container of convex polygon vertices.
0112 ///                 Calling `std::begin`/ `std::end` on the container must
0113 ///                 return an iterator where `*it` must be convertible to
0114 ///                 an `Vector2Type`.
0115 /// @return bool for inside/outside
0116 template <typename vertex_t, typename vertex_container_t>
0117 bool isInsidePolygon(const vertex_t& point,
0118                      const vertex_container_t& vertices) {
0119   // when we move along the edges of a convex polygon, a point on the inside of
0120   // the polygon will always appear on the same side of each edge.
0121   // a point on the outside will switch sides at least once.
0122 
0123   // returns which side of the connecting line between `ll0` and `ll1` the point
0124   // `p` is on. computes the sign of the z-component of the cross-product
0125   // between the line normal vector and the vector from `ll0` to `p`.
0126   auto lineSide = [&](auto&& ll0, auto&& ll1) {
0127     auto normal = ll1 - ll0;
0128     auto delta = point - ll0;
0129     return std::signbit((normal[0] * delta[1]) - (normal[1] * delta[0]));
0130   };
0131 
0132   auto iv = std::begin(vertices);
0133   auto l0 = *iv;
0134   auto l1 = *(++iv);
0135   // use vertex0 to vertex1 to define reference sign and compare w/ all edges
0136   auto reference = lineSide(l0, l1);
0137   for (++iv; iv != std::end(vertices); ++iv) {
0138     l0 = l1;
0139     l1 = *iv;
0140     if (lineSide(l0, l1) != reference) {
0141       return false;
0142     }
0143   }
0144   // manual check for last edge from last vertex back to the first vertex
0145   if (lineSide(l1, *std::begin(vertices)) != reference) {
0146     return false;
0147   }
0148   // point was always on the same side. point must be inside.
0149   return true;
0150 }
0151 
0152 /// Check if the point is inside the rectangle.
0153 ///
0154 /// @tparam vertex_t is vector with [0],[1] access
0155 ///
0156 /// @param point is the Vector2Type to check
0157 /// @param vertices Forward iterable container of convex polygon vertices.
0158 ///                 Calling `std::begin`/ `std::end` on the container must
0159 ///                 return an iterator where `*it` must be convertible to
0160 ///                 an `Vector2Type`.
0161 /// @return bool for inside/outside
0162 template <typename vertex_t>
0163 bool isInsideRectangle(const vertex_t& point, const vertex_t& lowerLeft,
0164                        const vertex_t& upperRight) {
0165   return (lowerLeft[0] <= point[0]) && (point[0] < upperRight[0]) &&
0166          (lowerLeft[1] <= point[1]) && (point[1] < upperRight[1]);
0167 }
0168 
0169 /// This method checks if a cloud of points are on 2D hyper-plane in 3D space.
0170 ///
0171 /// @param vertices The list of vertices to test
0172 /// @param tolerance The allowed out of plane tolerance
0173 /// @return boolean to indicate if all points are inside/outside
0174 bool onHyperPlane(const std::vector<Vector3>& vertices,
0175                   double tolerance = s_onSurfaceTolerance);
0176 
0177 /// Calculate the closest point on the polygon.
0178 Vector2 computeClosestPointOnPolygon(const Vector2& point,
0179                                      std::span<const Vector2> vertices,
0180                                      const SquareMatrix2& metric);
0181 
0182 /// Calculate the closest point on the box
0183 Vector2 computeEuclideanClosestPointOnRectangle(const Vector2& point,
0184                                                 const Vector2& lowerLeft,
0185                                                 const Vector2& upperRight);
0186 
0187 /// Calculate the closest point on the aligned box
0188 Vector2 computeClosestPointOnAlignedBox(const Vector2& lowerLeft,
0189                                         const Vector2& upperRight,
0190                                         const Vector2& point,
0191                                         const SquareMatrix2& metric);
0192 
0193 }  // namespace Acts::detail::VerticesHelper