File indexing completed on 2026-05-27 07:24:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/utils/bounding_volume.hpp"
0011
0012 #include "detray/definitions/units.hpp"
0013 #include "detray/geometry/mask.hpp"
0014 #include "detray/geometry/shapes.hpp"
0015
0016
0017 #include "detray/test/framework/types.hpp"
0018
0019
0020 #include <gtest/gtest.h>
0021
0022 using namespace detray;
0023
0024 using test_algebra = test::algebra;
0025 using scalar = test::scalar;
0026 using point3 = test::point3;
0027 using vector3 = test::vector3;
0028 using transform3 = test::transform3;
0029
0030 namespace {
0031
0032
0033 constexpr scalar envelope{0.01f};
0034
0035
0036 constexpr scalar tol{1e-5f};
0037
0038 }
0039
0040
0041 GTEST_TEST(detray_utils, bounding_cuboid3D) {
0042
0043 constexpr scalar hx{1.f * unit<scalar>::mm};
0044 constexpr scalar hy{9.3f * unit<scalar>::mm};
0045 constexpr scalar hz{0.5f * unit<scalar>::mm};
0046
0047 point3 p2_in = {0.5f, 8.0f, -0.4f};
0048 point3 p2_edge = {1.f, 9.3f, 0.5f};
0049 point3 p2_out = {1.5f, -9.f, 0.55f};
0050
0051 mask<cuboid3D, test_algebra> c3{0u, -hx, -hy, -hz, hx, hy, hz};
0052
0053 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{c3, 0u, envelope};
0054
0055
0056 ASSERT_EQ(aabb.id(), 0u);
0057
0058
0059 const auto bounds = aabb.bounds();
0060 ASSERT_NEAR(bounds[cuboid3D::e_min_x], -hx - envelope, tol);
0061 ASSERT_NEAR(bounds[cuboid3D::e_min_y], -hy - envelope, tol);
0062 ASSERT_NEAR(bounds[cuboid3D::e_min_z], -hz - envelope, tol);
0063 ASSERT_NEAR(bounds[cuboid3D::e_max_x], hx + envelope, tol);
0064 ASSERT_NEAR(bounds[cuboid3D::e_max_y], hy + envelope, tol);
0065 ASSERT_NEAR(bounds[cuboid3D::e_max_z], hz + envelope, tol);
0066
0067 ASSERT_TRUE(aabb.is_inside(p2_in));
0068 ASSERT_TRUE(aabb.is_inside(p2_edge));
0069 ASSERT_FALSE(aabb.is_inside(p2_out));
0070
0071 ASSERT_TRUE(aabb.is_inside(p2_out, 1.f));
0072 }
0073
0074
0075 GTEST_TEST(detray_utils, bounding_cylinder3D) {
0076
0077 constexpr scalar r{3.f * unit<scalar>::mm};
0078 constexpr scalar hz{4.f * unit<scalar>::mm};
0079
0080 point3 p3_in = {r, static_cast<scalar>(0.f), static_cast<scalar>(-1.f)};
0081 point3 p3_edge = {static_cast<scalar>(0.f), r, hz};
0082 point3 p3_out = {r * constant<scalar>::inv_sqrt2,
0083 r * constant<scalar>::inv_sqrt2, static_cast<scalar>(4.5f)};
0084 point3 p3_off = {1.f, 1.f, -9.f};
0085
0086 axis_aligned_bounding_volume<cylinder3D, test_algebra> aabc{
0087 0u, 0.f, -constant<scalar>::pi, -hz, r, constant<scalar>::pi, hz};
0088
0089
0090 ASSERT_EQ(aabc.id(), 0u);
0091
0092
0093 const auto bounds = aabc.bounds();
0094 ASSERT_NEAR(bounds[cylinder3D::e_min_r], 0.f, tol);
0095 ASSERT_NEAR(bounds[cylinder3D::e_max_r], r, tol);
0096 ASSERT_NEAR(bounds[cylinder3D::e_min_phi], -constant<scalar>::pi, tol);
0097 ASSERT_NEAR(bounds[cylinder3D::e_max_phi], constant<scalar>::pi, tol);
0098 ASSERT_NEAR(bounds[cylinder3D::e_min_z], -hz, tol);
0099 ASSERT_NEAR(bounds[cylinder3D::e_max_z], hz, tol);
0100
0101 ASSERT_TRUE(aabc.is_inside(p3_in));
0102 ASSERT_TRUE(aabc.is_inside(p3_edge));
0103 ASSERT_FALSE(aabc.is_inside(p3_out));
0104 ASSERT_FALSE(aabc.is_inside(p3_off));
0105
0106 ASSERT_TRUE(aabc.is_inside(p3_out, 0.6f));
0107 }
0108
0109
0110 GTEST_TEST(detray_utils, annulus2D_aabb) {
0111 constexpr scalar minR{7.2f * unit<scalar>::mm};
0112 constexpr scalar maxR{12.0f * unit<scalar>::mm};
0113 constexpr scalar minPhi{0.74195f};
0114 constexpr scalar maxPhi{1.33970f};
0115 typename transform3::point2 offset = {-2.f, 2.f};
0116
0117 mask<annulus2D, test_algebra> ann2{0u, minR, maxR, minPhi,
0118 maxPhi, 0.f, offset[0], offset[1]};
0119
0120
0121 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{ann2, 0u, envelope};
0122
0123
0124 const vector3 new_x{0.f, -1.f, 0.f};
0125 const vector3 new_z{0.f, 0.f, 1.f};
0126 const vector3 t{1.f, 2.f, 3.f};
0127 const transform3 trf{t, new_z, new_x};
0128
0129 const auto glob_aabb = aabb.transform(trf);
0130 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], 2.39186f - envelope + t[0], tol);
0131 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -10.50652f - envelope + t[1], tol);
0132 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -envelope + t[2], tol);
0133 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], 10.89317f + envelope + t[0], tol);
0134 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], -3.8954f + envelope + t[1], tol);
0135 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], envelope + t[2], tol);
0136 }
0137
0138
0139 GTEST_TEST(detray_utils, cylinder2D_aabb) {
0140 constexpr scalar r{3.f * unit<scalar>::mm};
0141 constexpr scalar hz{4.f * unit<scalar>::mm};
0142
0143 mask<cylinder2D, test_algebra> c{0u, r, -hz, hz};
0144
0145
0146 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{c, 0u, envelope};
0147
0148
0149 const vector3 new_x{0.f, -1.f, 0.f};
0150 const vector3 new_z{0.f, 0.f, 1.f};
0151 const vector3 t{1.f, 2.f, 3.f};
0152 const transform3 trf{t, new_z, new_x};
0153
0154 const auto glob_aabb = aabb.transform(trf);
0155 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(r + envelope) + t[0], tol);
0156 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(r + envelope) + t[1], tol);
0157 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -(hz + envelope) + t[2], tol);
0158 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (r + envelope) + t[0], tol);
0159 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (r + envelope) + t[1], tol);
0160 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], (hz + envelope) + t[2], tol);
0161 }
0162
0163
0164 GTEST_TEST(detray_utils, line2D_aabb) {
0165 constexpr scalar cell_size{1.f * unit<scalar>::mm};
0166 constexpr scalar hz{50.f * unit<scalar>::mm};
0167
0168 const mask<line_circular, test_algebra> ln_r{0u, cell_size, hz};
0169 const mask<line_square, test_algebra> ln_sq{0u, cell_size, hz};
0170
0171
0172 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb_r{ln_r, 0u,
0173 envelope};
0174 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb_sq{ln_sq, 0u,
0175 envelope};
0176
0177
0178 const vector3 new_x{0.f, -1.f, 0.f};
0179 const vector3 new_z{0.f, 0.f, 1.f};
0180 const vector3 t{1.f, 2.f, 3.f};
0181 const transform3 trf{t, new_z, new_x};
0182
0183
0184 const auto glob_aabb_r = aabb_r.transform(trf);
0185 ASSERT_NEAR(glob_aabb_r[cuboid3D::e_min_x], -(cell_size + envelope) + t[0],
0186 tol);
0187 ASSERT_NEAR(glob_aabb_r[cuboid3D::e_min_y], -(cell_size + envelope) + t[1],
0188 tol);
0189 ASSERT_NEAR(glob_aabb_r[cuboid3D::e_min_z], -(hz + envelope) + t[2], tol);
0190 ASSERT_NEAR(glob_aabb_r[cuboid3D::e_max_x], (cell_size + envelope) + t[0],
0191 tol);
0192 ASSERT_NEAR(glob_aabb_r[cuboid3D::e_max_y], (cell_size + envelope) + t[1],
0193 tol);
0194 ASSERT_NEAR(glob_aabb_r[cuboid3D::e_max_z], (hz + envelope) + t[2], tol);
0195
0196
0197 const auto glob_aabb_sq = aabb_sq.transform(trf);
0198 ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_min_x], -(cell_size + envelope) + t[0],
0199 tol);
0200 ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_min_y], -(cell_size + envelope) + t[1],
0201 tol);
0202 ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_min_z], -(hz + envelope) + t[2], tol);
0203 ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_max_x], (cell_size + envelope) + t[0],
0204 tol);
0205 ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_max_y], (cell_size + envelope) + t[1],
0206 tol);
0207 ASSERT_NEAR(glob_aabb_sq[cuboid3D::e_max_z], (hz + envelope) + t[2], tol);
0208 }
0209
0210
0211 GTEST_TEST(detray_utils, rectangle2D_aabb) {
0212 constexpr scalar hx{1.f * unit<scalar>::mm};
0213 constexpr scalar hy{9.3f * unit<scalar>::mm};
0214
0215 mask<rectangle2D, test_algebra> r2{0u, hx, hy};
0216
0217
0218 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{r2, 0u, envelope};
0219
0220
0221 const vector3 new_x{0.f, -1.f, 0.f};
0222 const vector3 new_z{0.f, 0.f, 1.f};
0223 const vector3 t{1.f, 2.f, 3.f};
0224 const transform3 trf{t, new_z, new_x};
0225
0226 const auto glob_aabb = aabb.transform(trf);
0227 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(hy + envelope) + t[0], tol);
0228 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(hx + envelope) + t[1], tol);
0229 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -(envelope) + t[2], tol);
0230 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (hy + envelope) + t[0], tol);
0231 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (hx + envelope) + t[1], tol);
0232 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], (envelope) + t[2], tol);
0233 }
0234
0235
0236 GTEST_TEST(detray_utils, ring2D_aabb) {
0237 constexpr scalar inner_r{0.f * unit<scalar>::mm};
0238 constexpr scalar outer_r{3.5f * unit<scalar>::mm};
0239
0240 mask<ring2D, test_algebra> r2{0u, inner_r, outer_r};
0241
0242
0243 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{r2, 0u, envelope};
0244
0245
0246 const vector3 new_x{0.f, -1.f, 0.f};
0247 const vector3 new_z{0.f, 0.f, 1.f};
0248 const vector3 t{1.f, 2.f, 3.f};
0249 const transform3 trf{t, new_z, new_x};
0250
0251 const auto glob_aabb = aabb.transform(trf);
0252 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(outer_r + envelope) + t[0], tol);
0253 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(outer_r + envelope) + t[1], tol);
0254 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -(envelope) + t[2], tol);
0255 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (outer_r + envelope) + t[0], tol);
0256 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (outer_r + envelope) + t[1], tol);
0257 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], (envelope) + t[2], tol);
0258 }
0259
0260
0261 GTEST_TEST(detray_utils, trapezoid2D_aabb) {
0262 constexpr scalar hx_miny{1.f * unit<scalar>::mm};
0263 constexpr scalar hx_maxy{3.f * unit<scalar>::mm};
0264 constexpr scalar hy{2.f * unit<scalar>::mm};
0265 constexpr scalar divisor{1.f / (2.f * hy)};
0266
0267 mask<trapezoid2D, test_algebra> t2{0u, hx_miny, hx_maxy, hy, divisor};
0268
0269
0270 axis_aligned_bounding_volume<cuboid3D, test_algebra> aabb{t2, 0u, envelope};
0271
0272
0273 const vector3 new_x{0.f, -1.f, 0.f};
0274 const vector3 new_z{0.f, 0.f, 1.f};
0275 const vector3 t{1.f, 2.f, 3.f};
0276 const transform3 trf{t, new_z, new_x};
0277
0278 const auto glob_aabb = aabb.transform(trf);
0279 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_x], -(hy + envelope) + t[0], tol);
0280 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_y], -(hx_maxy + envelope) + t[1], tol);
0281 ASSERT_NEAR(glob_aabb[cuboid3D::e_min_z], -envelope + t[2], tol);
0282 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_x], (hy + envelope) + t[0], tol);
0283 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_y], (hx_maxy + envelope) + t[1], tol);
0284 ASSERT_NEAR(glob_aabb[cuboid3D::e_max_z], envelope + t[2], tol);
0285 }
0286
0287
0288 GTEST_TEST(detray_utils, wrap_bounding_cuboid3D) {
0289 using box_t = axis_aligned_bounding_volume<cuboid3D, test_algebra>;
0290
0291 box_t b1{0u, -1.f, 0.f, -10.f, -0.5f, 1.f, 0.f};
0292 box_t b2{0u, -2.f, 3.f, 2.f, 2.f, 4.5f, 3.5f};
0293 box_t b3{0u, -1.5f, -0.1f, -2.f, 0.f, 0.1f, 2.f};
0294 box_t b4{0u, 0.f, 0.f, 0.f, 2.f, 2.f, 10.f};
0295
0296 std::vector<box_t> boxes = {b1, b2, b3, b4};
0297
0298 box_t aabb{boxes, 0u, envelope};
0299
0300
0301 ASSERT_EQ(aabb.id(), 0u);
0302
0303
0304 const auto bounds = aabb.bounds();
0305 ASSERT_NEAR(bounds[cuboid3D::e_min_x], -2.f - envelope, tol);
0306 ASSERT_NEAR(bounds[cuboid3D::e_min_y], -0.1f - envelope, tol);
0307 ASSERT_NEAR(bounds[cuboid3D::e_min_z], -10.f - envelope, tol);
0308 ASSERT_NEAR(bounds[cuboid3D::e_max_x], 2.f + envelope, tol);
0309 ASSERT_NEAR(bounds[cuboid3D::e_max_y], 4.5f + envelope, tol);
0310 ASSERT_NEAR(bounds[cuboid3D::e_max_z], 10.f + envelope, tol);
0311 }