File indexing completed on 2026-05-27 07:24:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/geometry/shapes/rectangle2D.hpp"
0011
0012 #include "detray/definitions/units.hpp"
0013 #include "detray/geometry/concepts.hpp"
0014 #include "detray/geometry/mask.hpp"
0015
0016
0017 #include "detray/test/framework/types.hpp"
0018 #include "detray/test/utils/ratio_test.hpp"
0019
0020
0021 #include <gtest/gtest.h>
0022
0023 using namespace detray;
0024
0025 using test_algebra = test::algebra;
0026 using scalar = test::scalar;
0027 using point3 = test::point3;
0028
0029 constexpr scalar tol{1e-7f};
0030
0031 constexpr scalar hx{1.f * unit<scalar>::mm};
0032 constexpr scalar hy{9.3f * unit<scalar>::mm};
0033 constexpr scalar hz{0.5f * unit<scalar>::mm};
0034
0035
0036 GTEST_TEST(detray_masks, rectangle2D) {
0037 static_assert(concepts::shape<rectangle2D, test_algebra>);
0038 static_assert(concepts::rectilinear_shape<rectangle2D, test_algebra>);
0039 static_assert(concepts::planar_shape<rectangle2D, test_algebra>);
0040
0041 point3 p2_in = {0.5f, -9.f, 0.f};
0042 point3 p2_edge = {1.f, 9.3f, 0.f};
0043 point3 p2_out = {1.5f, -9.f, 0.f};
0044
0045 mask<rectangle2D, test_algebra> r2{0u, hx, hy};
0046
0047 ASSERT_NEAR(r2[rectangle2D::e_half_x], hx, tol);
0048 ASSERT_NEAR(r2[rectangle2D::e_half_y], hy, tol);
0049
0050 ASSERT_TRUE(r2.is_inside(p2_in));
0051 ASSERT_TRUE(r2.is_inside(p2_edge));
0052 ASSERT_FALSE(r2.is_inside(p2_out));
0053
0054 ASSERT_TRUE(r2.is_inside(p2_out, 1.f));
0055
0056
0057 const scalar a{r2.area()};
0058 EXPECT_NEAR(a, 37.2f * unit<scalar>::mm2, tol);
0059 ASSERT_EQ(a, r2.measure());
0060
0061
0062 constexpr scalar envelope{0.01f};
0063 const auto loc_bounds = r2.local_min_bounds(envelope);
0064 ASSERT_NEAR(loc_bounds[cuboid3D::e_min_x], -(hx + envelope), tol);
0065 ASSERT_NEAR(loc_bounds[cuboid3D::e_min_y], -(hy + envelope), tol);
0066 ASSERT_NEAR(loc_bounds[cuboid3D::e_min_z], -envelope, tol);
0067 ASSERT_NEAR(loc_bounds[cuboid3D::e_max_x], (hx + envelope), tol);
0068 ASSERT_NEAR(loc_bounds[cuboid3D::e_max_y], (hy + envelope), tol);
0069 ASSERT_NEAR(loc_bounds[cuboid3D::e_max_z], envelope, tol);
0070
0071 const auto centroid = r2.centroid();
0072 ASSERT_NEAR(centroid[0], 0.f, tol);
0073 ASSERT_NEAR(centroid[1], 0.f, tol);
0074 ASSERT_NEAR(centroid[2], 0.f, tol);
0075 }
0076
0077
0078 GTEST_TEST(detray_masks, rectangle2D_ratio_test) {
0079 struct mask_check {
0080 bool operator()(const point3 &p, const mask<rectangle2D, test_algebra> &r,
0081 const test::transform3 &trf, const scalar t) {
0082 return r.is_inside(trf, p, t);
0083 }
0084 };
0085
0086 constexpr mask<rectangle2D, test_algebra> r{0u, 3.f, 4.f};
0087
0088 constexpr scalar t{0.f};
0089 const test::transform3 trf{};
0090 constexpr scalar size{10.f * unit<scalar>::mm};
0091 const auto n_points{static_cast<std::size_t>(std::pow(500, 3))};
0092
0093
0094 std::vector<point3> points =
0095 test::generate_regular_points<cuboid3D>(n_points, {size});
0096
0097 scalar ratio = test::ratio_test<mask_check>(points, r, trf, t);
0098
0099 const scalar area{r.measure()};
0100 const scalar world{size * size};
0101
0102 ASSERT_NEAR(ratio, area / world, 0.02f);
0103 }
0104
0105
0106 GTEST_TEST(detray_masks, cuboid3D) {
0107 static_assert(concepts::shape<cuboid3D, test_algebra>);
0108 static_assert(concepts::rectilinear_shape<cuboid3D, test_algebra>);
0109
0110 point3 p2_in = {0.5f, 8.0f, -0.4f};
0111 point3 p2_edge = {1.f, 9.3f, 0.5f};
0112 point3 p2_out = {1.5f, -9.f, 0.55f};
0113
0114 mask<cuboid3D, test_algebra> c3{0u, -hx, -hy, -hz, hx, hy, hz};
0115
0116 ASSERT_NEAR(c3[cuboid3D::e_min_x], -hx, tol);
0117 ASSERT_NEAR(c3[cuboid3D::e_min_y], -hy, tol);
0118 ASSERT_NEAR(c3[cuboid3D::e_min_z], -hz, tol);
0119 ASSERT_NEAR(c3[cuboid3D::e_max_x], hx, tol);
0120 ASSERT_NEAR(c3[cuboid3D::e_max_y], hy, tol);
0121 ASSERT_NEAR(c3[cuboid3D::e_max_z], hz, tol);
0122
0123 ASSERT_TRUE(c3.is_inside(p2_in));
0124 ASSERT_TRUE(c3.is_inside(p2_edge));
0125 ASSERT_FALSE(c3.is_inside(p2_out));
0126
0127 ASSERT_TRUE(c3.is_inside(p2_out, 1.f));
0128
0129
0130 const scalar v{c3.volume()};
0131 EXPECT_NEAR(v, 37.2f * unit<scalar>::mm3, tol);
0132 ASSERT_EQ(v, c3.measure());
0133
0134
0135 constexpr scalar envelope{0.01f};
0136 const auto loc_bounds = c3.local_min_bounds(envelope);
0137 ASSERT_NEAR(loc_bounds[cuboid3D::e_min_x], -(hx + envelope), tol);
0138 ASSERT_NEAR(loc_bounds[cuboid3D::e_min_y], -(hy + envelope), tol);
0139 ASSERT_NEAR(loc_bounds[cuboid3D::e_min_z], -(hz + envelope), tol);
0140 ASSERT_NEAR(loc_bounds[cuboid3D::e_max_x], (hx + envelope), tol);
0141 ASSERT_NEAR(loc_bounds[cuboid3D::e_max_y], (hy + envelope), tol);
0142 ASSERT_NEAR(loc_bounds[cuboid3D::e_max_z], (hz + envelope), tol);
0143 }
0144
0145
0146 GTEST_TEST(detray_masks, cuboid3D_ratio_test) {
0147 struct mask_check {
0148 bool operator()(const point3 &p, const mask<cuboid3D, test_algebra> &cb,
0149 const test::transform3 &trf, const scalar t) {
0150 const point3 loc_p{cb.to_local_frame3D(trf, p)};
0151 return cb.is_inside(loc_p, t);
0152 }
0153 };
0154
0155 constexpr mask<cuboid3D, test_algebra> cb{0u, 0.f, 0.f, 0.f, 3.f, 4.f, 1.f};
0156
0157 constexpr scalar t{0.f};
0158 const test::transform3 trf{};
0159 constexpr scalar size{10.f * unit<scalar>::mm};
0160 const auto n_points{static_cast<std::size_t>(std::pow(500, 3))};
0161
0162 std::vector<point3> points =
0163 test::generate_regular_points<cuboid3D>(n_points, {size});
0164
0165 scalar ratio = test::ratio_test<mask_check>(points, cb, trf, t);
0166
0167 const scalar volume{cb.measure()};
0168 const scalar world{size * size * size};
0169
0170 ASSERT_NEAR(ratio, volume / world, 0.002f);
0171 }