File indexing completed on 2026-05-27 07:23:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
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
0018 #include <limits>
0019 #include <vector>
0020
0021 namespace detray::detail {
0022
0023
0024 template <detray::concepts::algebra algebra_t>
0025 struct center_of_gravity_rectangle {
0026
0027
0028
0029
0030
0031
0032
0033
0034
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
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
0068 template <detray::concepts::algebra algebra_t>
0069 struct center_of_gravity_generic {
0070
0071
0072
0073
0074
0075
0076
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
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
0110 template <detray::concepts::algebra algebra_t>
0111 struct edges_intersect_generic {
0112
0113
0114
0115
0116
0117
0118
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
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
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 }