Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:23:55

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 // Project include(s).
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/detail/qualifiers.hpp"
0014 #include "detray/definitions/math.hpp"
0015 #include "detray/utils/concepts.hpp"
0016 
0017 // System include(s).
0018 #include <limits>
0019 #include <vector>
0020 
0021 namespace detray::detail {
0022 
0023 /// Struct that assigns the center of gravity to a rectangular bin
0024 template <detray::concepts::algebra algebra_t>
0025 struct center_of_gravity_rectangle {
0026   /// Call operator to the struct, allows to chain several chain operators
0027   /// together
0028   ///
0029   /// @param bin_contour The contour description of the bin -> target
0030   /// @param surface_contour The contour description of the surface -> test
0031   ///
0032   /// @note the bin_contour is asummed to be a rectangle
0033   ///
0034   /// @return whether this should be associated
0035   bool operator()(
0036       const std::vector<dpoint2D<algebra_t>> &bin_contour,
0037       const std::vector<dpoint2D<algebra_t>> &surface_contour) const {
0038     using scalar_t = dscalar<algebra_t>;
0039     using point2_t = dpoint2D<algebra_t>;
0040 
0041     // Check if centre of gravity is inside bin
0042     point2_t cgs = {0.f, 0.f};
0043     for (const auto &svtx : surface_contour) {
0044       cgs = cgs + svtx;
0045     }
0046     cgs = 1.f / static_cast<scalar_t>(surface_contour.size()) * cgs;
0047     scalar_t min_l0 = std::numeric_limits<scalar_t>::max();
0048     scalar_t max_l0 = -std::numeric_limits<scalar_t>::max();
0049     scalar_t min_l1 = std::numeric_limits<scalar_t>::max();
0050     scalar_t max_l1 = -std::numeric_limits<scalar_t>::max();
0051     for (const auto &b : bin_contour) {
0052       min_l0 = math::min(b[0], min_l0);
0053       max_l0 = math::max(b[0], max_l0);
0054       min_l1 = math::min(b[1], min_l1);
0055       max_l1 = math::max(b[1], max_l1);
0056     }
0057 
0058     if (cgs[0] >= min_l0 && cgs[0] < max_l0 && cgs[1] >= min_l1 &&
0059         cgs[1] < max_l1) {
0060       return true;
0061     }
0062 
0063     return false;
0064   }
0065 };
0066 
0067 /// Check if center of mass is inside a generic polygon bin
0068 template <detray::concepts::algebra algebra_t>
0069 struct center_of_gravity_generic {
0070   /// Call operator to the struct, allows to chain several chain operators
0071   /// together
0072   ///
0073   /// @param bin_contour The contour description of the bin -> target
0074   /// @param surface_contour The contour description of the surface -> test
0075   ///
0076   /// @return whether this should be associated
0077   bool operator()(
0078       const std::vector<dpoint2D<algebra_t>> &bin_contour,
0079       const std::vector<dpoint2D<algebra_t>> &surface_contour) const {
0080     using scalar_t = dscalar<algebra_t>;
0081     using point2_t = dpoint2D<algebra_t>;
0082 
0083     // Check if centre of gravity is inside bin
0084     point2_t cgs = {0.f, 0.f};
0085     for (const auto &svtx : surface_contour) {
0086       cgs = cgs + svtx;
0087     }
0088     cgs = 1.f / static_cast<scalar_t>(surface_contour.size()) * cgs;
0089 
0090     std::size_t i = 0u;
0091     std::size_t j = 0u;
0092     std::size_t num_points = bin_contour.size();
0093 
0094     bool inside = false;
0095     for (i = 0u, j = num_points - 1u; i < num_points; j = i++) {
0096       const auto &pi = bin_contour[i];
0097       const auto &pj = bin_contour[j];
0098       if ((((pi[1] <= cgs[1]) && (cgs[1] < pj[1])) ||
0099            ((pj[1] <= cgs[1]) && (cgs[1] < pi[1]))) &&
0100           (cgs[0] <
0101            (pj[0] - pi[0]) * (cgs[1] - pi[1]) / (pj[1] - pi[1]) + pi[0])) {
0102         inside = !inside;
0103       }
0104     }
0105     return inside;
0106   }
0107 };
0108 
0109 /// Check if the edges of the bin and surface contour overlap
0110 template <detray::concepts::algebra algebra_t>
0111 struct edges_intersect_generic {
0112   /// Call operator to the struct, allows to chain several chain operators
0113   /// together
0114   ///
0115   /// @param bin_contour The contour description of the bin -> target
0116   /// @param surface_contour The contour description of the surface -> test
0117   ///
0118   /// @return whether this should be associated
0119   bool operator()(
0120       const std::vector<dpoint2D<algebra_t>> &bin_contour,
0121       const std::vector<dpoint2D<algebra_t>> &surface_contour) const {
0122     using scalar_t = dscalar<algebra_t>;
0123     using point2_t = dpoint2D<algebra_t>;
0124 
0125     auto intersect = [](const point2_t &pi, const point2_t &pj,
0126                         const point2_t &pk, const point2_t &pl) {
0127       scalar_t d =
0128           (pj[0] - pi[0]) * (pl[1] - pk[1]) - (pj[1] - pi[1]) * (pl[0] - pk[0]);
0129 
0130       if (d != 0.f) {
0131         double r = ((pi[1] - pk[1]) * (pl[0] - pk[0]) -
0132                     (pi[0] - pk[0]) * (pl[1] - pk[1])) /
0133                    d;
0134         double s = ((pi[1] - pk[1]) * (pj[0] - pi[0]) -
0135                     (pi[0] - pk[0]) * (pj[1] - pi[1])) /
0136                    d;
0137         if (r >= 0.f && r <= 1.f && s >= 0.f && s <= 1.f) {
0138           return true;
0139         }
0140       }
0141       return false;
0142     };
0143 
0144     // Loop over bin_contour
0145     for (std::size_t j = 1u; j <= bin_contour.size(); ++j) {
0146       std::size_t i = j - 1u;
0147       std::size_t jc = (j == bin_contour.size()) ? 0u : j;
0148       const auto &pi = bin_contour[i];
0149       const auto &pj = bin_contour[jc];
0150       // Loop over surface_contour
0151       for (std::size_t k = 1u; k <= surface_contour.size(); ++k) {
0152         std::size_t l = k - 1u;
0153         std::size_t kc = (k == surface_contour.size()) ? 0u : k;
0154         const auto &pl = surface_contour[l];
0155         const auto &pk = surface_contour[kc];
0156         if (intersect(pi, pj, pk, pl)) {
0157           return true;
0158         }
0159       }
0160     }
0161     return false;
0162   }
0163 };
0164 
0165 }  // namespace detray::detail