File indexing completed on 2026-05-27 07:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/containers.hpp"
0014 #include "detray/definitions/detail/qualifiers.hpp"
0015 #include "detray/definitions/indexing.hpp"
0016 #include "detray/definitions/math.hpp"
0017 #include "detray/geometry/coordinates/cartesian2D.hpp"
0018 #include "detray/geometry/detail/shape_utils.hpp"
0019
0020
0021 #include <limits>
0022 #include <ostream>
0023 #include <string_view>
0024
0025 namespace detray {
0026
0027
0028
0029
0030 class rectangle2D {
0031 public:
0032
0033 static constexpr std::string_view name = "rectangle2D";
0034
0035 enum boundaries : unsigned int {
0036 e_half_x = 0u,
0037 e_half_y = 1u,
0038 e_size = 2u,
0039 };
0040
0041
0042 template <concepts::scalar scalar_t>
0043 using bounds_type = darray<scalar_t, boundaries::e_size>;
0044
0045
0046 template <concepts::algebra algebra_t>
0047 using local_frame_type = cartesian2D<algebra_t>;
0048
0049
0050 template <typename bool_t>
0051 using result_type = detail::boundary_check_result<bool_t>;
0052
0053
0054 static constexpr std::size_t dim{2u};
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template <concepts::scalar scalar_t, concepts::point point_t>
0066 DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
0067 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
0068 return math::min(math::fabs(math::fabs(loc_p[0]) - bounds[e_half_x]),
0069 math::fabs(math::fabs(loc_p[1]) - bounds[e_half_y]));
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 template <concepts::algebra algebra_t>
0081 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
0082 const bounds_type<dscalar<algebra_t>> &bounds,
0083 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
0084 const dscalar<algebra_t> tol =
0085 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
0086 const dscalar<algebra_t> edge_tol = 0.f) const {
0087
0088 const dpoint2D<algebra_t> loc_p =
0089 local_frame_type<algebra_t>::global_to_local(trf, glob_p, {});
0090
0091 return check_boundaries(bounds, loc_p, tol, edge_tol);
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 template <concepts::scalar scalar_t, concepts::point point_t>
0104 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
0105 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
0106 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
0107 const scalar_t edge_tol = 0.f) const {
0108 const scalar_t loc_0{math::fabs(loc_p[0])};
0109 const scalar_t loc_1{math::fabs(loc_p[1])};
0110
0111 auto inside_mask{(loc_0 <= (bounds[e_half_x] + tol) &&
0112 loc_1 <= (bounds[e_half_y] + tol))};
0113
0114 decltype(inside_mask) inside_edge{false};
0115 if (detail::any_of(edge_tol > 0.f)) {
0116 const scalar_t full_tol{tol + edge_tol};
0117
0118 inside_edge = (loc_0 <= (bounds[e_half_x] + full_tol) &&
0119 loc_1 <= (bounds[e_half_y] + full_tol));
0120 }
0121
0122 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
0123 }
0124
0125
0126
0127
0128
0129
0130
0131 template <concepts::scalar scalar_t>
0132 DETRAY_HOST_DEVICE constexpr scalar_t measure(
0133 const bounds_type<scalar_t> &bounds) const {
0134 return area(bounds);
0135 }
0136
0137
0138
0139
0140
0141
0142 template <concepts::scalar scalar_t>
0143 DETRAY_HOST_DEVICE constexpr scalar_t area(
0144 const bounds_type<scalar_t> &bounds) const {
0145 return 4.f * bounds[e_half_x] * bounds[e_half_y];
0146 }
0147
0148
0149
0150
0151
0152
0153
0154 template <concepts::scalar scalar_t>
0155 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
0156 const bounds_type<scalar_t> &bounds,
0157 const bounds_type<scalar_t> &o_bounds) const {
0158 bounds_type<scalar_t> new_bounds{};
0159
0160 new_bounds[e_half_x] = math::max(bounds[e_half_x], o_bounds[e_half_x]);
0161 new_bounds[e_half_y] = math::max(bounds[e_half_y], o_bounds[e_half_y]);
0162
0163 return new_bounds;
0164 }
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 template <concepts::algebra algebra_t>
0176 DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
0177 const bounds_type<dscalar<algebra_t>> &bounds,
0178 const dscalar<algebra_t> env =
0179 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
0180 using scalar_t = dscalar<algebra_t>;
0181
0182 assert(env > 0.f);
0183 const scalar_t x_bound{bounds[e_half_x] + env};
0184 const scalar_t y_bound{bounds[e_half_y] + env};
0185 return {-x_bound, -y_bound, -env, x_bound, y_bound, env};
0186 }
0187
0188
0189 template <concepts::algebra algebra_t>
0190 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
0191 const bounds_type<dscalar<algebra_t>> & ) const {
0192 return {0.f, 0.f, 0.f};
0193 }
0194
0195
0196
0197
0198
0199
0200
0201 template <concepts::algebra algebra_t>
0202 DETRAY_HOST dvector<dpoint3D<algebra_t>> vertices(
0203 const bounds_type<dscalar<algebra_t>> &bounds, dindex ) const {
0204 using point3_t = dpoint3D<algebra_t>;
0205
0206
0207 point3_t lh_lc{-bounds[e_half_x], -bounds[e_half_y],
0208 static_cast<dscalar<algebra_t>>(0.f)};
0209
0210 point3_t rh_lc{bounds[e_half_x], -bounds[e_half_y],
0211 static_cast<dscalar<algebra_t>>(0.f)};
0212
0213 point3_t rh_uc{bounds[e_half_x], bounds[e_half_y],
0214 static_cast<dscalar<algebra_t>>(0.f)};
0215
0216 point3_t lh_uc{-bounds[e_half_x], bounds[e_half_y],
0217 static_cast<dscalar<algebra_t>>(0.f)};
0218
0219
0220 return {lh_lc, rh_lc, rh_uc, lh_uc};
0221 }
0222
0223
0224
0225
0226
0227
0228
0229 template <concepts::scalar scalar_t>
0230 DETRAY_HOST constexpr bool check_consistency(
0231 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
0232 if (constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
0233 bounds[e_half_x] < tol || bounds[e_half_y] < tol) {
0234 os << "DETRAY ERROR (HOST): Half lengths must be in the range (0, "
0235 "numeric_max)"
0236 << std::endl;
0237 return false;
0238 }
0239
0240 return true;
0241 }
0242 };
0243
0244 }