ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
trapezoid2D.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/definitions/algebra.hpp"
13#include "detray/definitions/containers.hpp"
14#include "detray/definitions/detail/qualifiers.hpp"
15#include "detray/definitions/indexing.hpp"
16#include "detray/definitions/math.hpp"
17#include "detray/geometry/coordinates/cartesian2D.hpp"
18#include "detray/geometry/coordinates/cartesian3D.hpp"
19#include "detray/geometry/detail/shape_utils.hpp"
20
21// System include(s)
22#include <limits>
23#include <ostream>
24#include <string_view>
25
26namespace detray {
27
35 public:
37 static constexpr std::string_view name = "trapezoid2D";
38
40 enum boundaries : unsigned int {
41 e_half_length_0 = 0u,
42 e_half_length_1 = 1u,
43 e_half_length_2 = 2u,
44 e_divisor = 3u, // 1 / (2 * bounds[e_half_length_2])
45 e_size = 4u,
46 };
47
49 template <concepts::scalar scalar_t>
51
53 template <concepts::algebra algebra_t>
55
57 template <typename bool_t>
58 using result_type = detail::boundary_check_result<bool_t>;
59
61 static constexpr std::size_t dim{2u};
62
72 template <concepts::scalar scalar_t, concepts::point point_t>
73 DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
74 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
75 // Minimum distance between loc point and line between corner points
76 const scalar_t d_y = -2.f * bounds[e_half_length_2];
77 const scalar_t d_x = bounds[e_half_length_1] - bounds[e_half_length_0];
78
79 const scalar_t denom = math::sqrt(d_y * d_y + d_x * d_x);
80 const scalar_t dist_to_line =
81 math::fabs(d_y * loc_p[0] - d_x * loc_p[1] -
82 bounds[e_half_length_2] *
83 (bounds[e_half_length_1] + bounds[e_half_length_0])) /
84 denom;
85
86 return math::min(dist_to_line, math::fabs(math::fabs(loc_p[1]) -
87 bounds[e_half_length_2]));
88 }
89
99 template <concepts::algebra algebra_t>
100 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
101 const bounds_type<dscalar<algebra_t>> &bounds,
102 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
103 const dscalar<algebra_t> tol =
104 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
105 const dscalar<algebra_t> edge_tol = 0.f) const {
106 // Get the full local position
107 const dpoint3D<algebra_t> loc_p =
109
110 return check_boundaries(bounds, loc_p, tol, edge_tol);
111 }
112
123 template <concepts::scalar scalar_t, concepts::point point_t>
124 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
125 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
126 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
127 const scalar_t edge_tol = 0.f) const {
128 const scalar_t rel_y =
129 (bounds[e_half_length_2] + loc_p[1]) * bounds[e_divisor];
130 const scalar_t bound_x{
131 bounds[e_half_length_0] +
132 rel_y * (bounds[e_half_length_1] - bounds[e_half_length_0])};
133
134 auto inside_mask{(math::fabs(loc_p[0]) <= (bound_x + tol) &&
135 math::fabs(loc_p[1]) <= (bounds[e_half_length_2] + tol))};
136
137 decltype(inside_mask) inside_edge{false};
138 if (detail::any_of(edge_tol > 0.f)) {
139 const scalar_t full_tol{tol + edge_tol};
140
141 inside_edge =
142 (math::fabs(loc_p[0]) <= (bound_x + full_tol) &&
143 math::fabs(loc_p[1]) <= (bounds[e_half_length_2] + full_tol));
144 }
145
146 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
147 }
148
149
155 template <concepts::scalar scalar_t>
156 DETRAY_HOST_DEVICE constexpr scalar_t measure(
157 const bounds_type<scalar_t> &bounds) const {
158 return area(bounds);
159 }
160
166 template <concepts::scalar scalar_t>
167 DETRAY_HOST_DEVICE constexpr scalar_t area(
168 const bounds_type<scalar_t> &bounds) const {
169 return 2.f * (bounds[e_half_length_0] + bounds[e_half_length_1]) *
170 bounds[e_half_length_2];
171 }
172
179 template <concepts::scalar scalar_t>
180 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
181 const bounds_type<scalar_t> &bounds,
182 const bounds_type<scalar_t> &o_bounds) const {
183 bounds_type<scalar_t> new_bounds{};
184
185 new_bounds[e_half_length_0] =
186 math::max(bounds[e_half_length_0], o_bounds[e_half_length_0]);
187 new_bounds[e_half_length_1] =
188 math::max(bounds[e_half_length_1], o_bounds[e_half_length_1]);
189 new_bounds[e_half_length_2] =
190 math::max(bounds[e_half_length_2], o_bounds[e_half_length_2]);
191
192 // Recalculate the memoized divisor
193 new_bounds[e_divisor] = 1.f / (2.f * new_bounds[e_half_length_2]);
194
195 return new_bounds;
196 }
197
207 template <concepts::algebra algebra_t>
208 DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
209 const bounds_type<dscalar<algebra_t>> &bounds,
210 const dscalar<algebra_t> env =
211 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
212 using scalar_t = dscalar<algebra_t>;
213
214 assert(env > 0.f);
215 const scalar_t x_bound{(bounds[e_half_length_0] > bounds[e_half_length_1]
216 ? bounds[e_half_length_0]
217 : bounds[e_half_length_1]) +
218 env};
219 const scalar_t y_bound{bounds[e_half_length_2] + env};
220 return {-x_bound, -y_bound, -env, x_bound, y_bound, env};
221 }
222
225 template <concepts::algebra algebra_t>
226 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
227 const bounds_type<dscalar<algebra_t>> &bounds) const {
228 using scalar_t = dscalar<algebra_t>;
229
230 const scalar_t h_2{bounds[e_half_length_2]};
231 const scalar_t a_2{bounds[e_half_length_1]};
232 const scalar_t b_2{bounds[e_half_length_0]};
233
234 const scalar_t y{2.f * h_2 * (2.f * a_2 + b_2) * 1.f / (3.f * (a_2 + b_2))};
235
236 return {static_cast<scalar_t>(0), y - h_2, static_cast<scalar_t>(0)};
237 }
238
244 template <concepts::algebra algebra_t>
246 const bounds_type<dscalar<algebra_t>> &bounds, dindex /*ignored*/) const {
247 using point3_t = dpoint3D<algebra_t>;
248
249 // left hand lower corner
250 point3_t lh_lc{-bounds[e_half_length_0], -bounds[e_half_length_2],
251 static_cast<dscalar<algebra_t>>(0.f)};
252 // right hand lower corner
253 point3_t rh_lc{bounds[e_half_length_0], -bounds[e_half_length_2],
254 static_cast<dscalar<algebra_t>>(0.f)};
255 // right hand upper corner
256 point3_t rh_uc{bounds[e_half_length_1], bounds[e_half_length_2],
257 static_cast<dscalar<algebra_t>>(0.f)};
258 // left hand upper corner
259 point3_t lh_uc{-bounds[e_half_length_1], bounds[e_half_length_2],
260 static_cast<dscalar<algebra_t>>(0.f)};
261
262 // Return the confining vertices
263 return {lh_lc, rh_lc, rh_uc, lh_uc};
264 }
265
272 template <concepts::scalar scalar_t>
273 DETRAY_HOST constexpr bool check_consistency(
274 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
275 constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
276
277 if (bounds[e_half_length_0] < tol || bounds[e_half_length_1] < tol) {
278 os << "DETRAY ERROR (HOST): Half length in x must be in the range "
279 "(0, "
280 "numeric_max)"
281 << std::endl;
282 return false;
283 }
284 if (bounds[e_half_length_2] < tol) {
285 os << "DETRAY ERROR (HOST): Half length in y must be in the range "
286 "(0, "
287 "numeric_max)"
288 << std::endl;
289 return false;
290 }
291
292 if (const auto div{1.f / (2.f * bounds[e_half_length_2])};
293 math::fabs(bounds[e_divisor] - div) > tol) {
294 os << "DETRAY ERROR (HOST): Divisor incorrect. Should be: " << div
295 << std::endl;
296 return false;
297 }
298
299 return true;
300 }
301};
302
303} // namespace detray
Geometrical shape of a trapezoid2D.
Definition trapezoid2D.hpp:34
constexpr scalar_t measure(const bounds_type< scalar_t > &bounds) const
Measure of the shape: Area.
Definition trapezoid2D.hpp:156
constexpr bool check_consistency(const bounds_type< scalar_t > &bounds, std::ostream &os) const
Check consistency of boundary values.
Definition trapezoid2D.hpp:273
constexpr result_type< dbool< algebra_t > > check_boundaries(const bounds_type< dscalar< algebra_t > > &bounds, const dtransform3D< algebra_t > &trf, const dpoint3D< algebra_t > &glob_p, const dscalar< algebra_t > tol=std::numeric_limits< dscalar< algebra_t > >::epsilon(), const dscalar< algebra_t > edge_tol=0.f) const
Check boundary values for a local point.
Definition trapezoid2D.hpp:100
dvector< dpoint3D< algebra_t > > vertices(const bounds_type< dscalar< algebra_t > > &bounds, dindex) const
Generate vertices in local cartesian frame.
Definition trapezoid2D.hpp:245
constexpr scalar_t area(const bounds_type< scalar_t > &bounds) const
The area of a the shape.
Definition trapezoid2D.hpp:167
dpoint3D< algebra_t > centroid(const bounds_type< dscalar< algebra_t > > &bounds) const
Definition trapezoid2D.hpp:226
detail::boundary_check_result< bool_t > result_type
Result type of a boundary check.
Definition trapezoid2D.hpp:58
scalar_t min_dist_to_boundary(const bounds_type< scalar_t > &bounds, const point_t &loc_p) const
Find the minimum distance to any boundary.
Definition trapezoid2D.hpp:73
darray< scalar_t, boundaries::e_size > bounds_type
Container definition for the shape boundary values.
Definition trapezoid2D.hpp:50
static constexpr std::size_t dim
Dimension of the local coordinate system.
Definition trapezoid2D.hpp:61
static constexpr std::string_view name
The name for this shape.
Definition trapezoid2D.hpp:37
constexpr auto check_boundaries(const bounds_type< scalar_t > &bounds, const point_t &loc_p, const scalar_t tol=std::numeric_limits< scalar_t >::epsilon(), const scalar_t edge_tol=0.f) const
Definition trapezoid2D.hpp:124
constexpr bounds_type< scalar_t > merge(const bounds_type< scalar_t > &bounds, const bounds_type< scalar_t > &o_bounds) const
Merge two trapezoid shapes.
Definition trapezoid2D.hpp:180
boundaries
Indices describing the entries in the shape boundary array.
Definition trapezoid2D.hpp:40
darray< dscalar< algebra_t >, 6 > local_min_bounds(const bounds_type< dscalar< algebra_t > > &bounds, const dscalar< algebra_t > env=std::numeric_limits< dscalar< algebra_t > >::epsilon()) const
Lower and upper point for minimal axis aligned bounding box.
Definition trapezoid2D.hpp:208
cartesian2D< algebra_t > local_frame_type
Local coordinate frame for boundary checks.
Definition trapezoid2D.hpp:54
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
unsigned int dindex
Default index type.
Definition indexing.hpp:18
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
Projection into a 2D cartesian coordinate frame.
Definition cartesian2D.hpp:19
static loc_point global_to_local(const transform3_type &trf, const point3_type &p, const vector3_type &)
This method transforms a point from a global cartesian 3D frame to a local 3D cartesian point Convert...
Definition cartesian3D.hpp:57