File indexing completed on 2025-08-06 08:11:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Geometry/GenericCuboidVolumeBounds.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/PlanarBounds.hpp"
0016 #include "Acts/Surfaces/PlaneSurface.hpp"
0017 #include "Acts/Surfaces/Surface.hpp"
0018 #include "Acts/Surfaces/SurfaceBounds.hpp"
0019 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0020 #include "Acts/Utilities/BoundingBox.hpp"
0021 #include "Acts/Utilities/Helpers.hpp"
0022 #include "Acts/Visualization/IVisualization3D.hpp"
0023 #include "Acts/Visualization/PlyVisualization3D.hpp"
0024
0025 #include <array>
0026 #include <cmath>
0027 #include <fstream>
0028 #include <memory>
0029 #include <utility>
0030 #include <vector>
0031
0032 namespace Acts::Test {
0033
0034 GeometryContext gctx = GeometryContext();
0035
0036 BOOST_AUTO_TEST_SUITE(Volumes)
0037
0038 BOOST_AUTO_TEST_CASE(construction_test) {
0039 std::array<Vector3, 8> vertices;
0040 vertices = {{{0, 0, 0},
0041 {2, 0, 0},
0042 {2, 1, 0},
0043 {0, 1, 0},
0044 {0, 0, 1},
0045 {2, 0, 1},
0046 {2, 1, 1},
0047 {0, 1, 1}}};
0048 GenericCuboidVolumeBounds cubo(vertices);
0049
0050 BOOST_CHECK(cubo.inside({0.5, 0.5, 0.5}));
0051 BOOST_CHECK(cubo.inside({1.5, 0.5, 0.5}));
0052 BOOST_CHECK(!cubo.inside({2.5, 0.5, 0.5}));
0053 BOOST_CHECK(!cubo.inside({0.5, 1.5, 0.5}));
0054 BOOST_CHECK(!cubo.inside({0.5, 0.5, 1.5}));
0055 BOOST_CHECK(!cubo.inside({-0.5, 0.5, 0.5}));
0056
0057 BOOST_CHECK(!cubo.inside({2.2, 1, 1}, 0.1));
0058 BOOST_CHECK(cubo.inside({2.2, 1, 1}, 0.21));
0059 BOOST_CHECK(cubo.inside({2.2, 1, 1}, 0.3));
0060 }
0061
0062 BOOST_AUTO_TEST_CASE(GenericCuboidBoundsOrientedSurfaces) {
0063 std::array<Vector3, 8> vertices;
0064 vertices = {{{0, 0, 0},
0065 {2, 0, 0},
0066 {2, 1, 0},
0067 {0, 1, 0},
0068 {0, 0, 1},
0069 {2, 0, 1},
0070 {2, 1, 1},
0071 {0, 1, 1}}};
0072 GenericCuboidVolumeBounds cubo(vertices);
0073
0074 auto is_in = [](const auto& tvtx, const auto& vertices_) {
0075 for (const auto& vtx : vertices_) {
0076 if (checkCloseAbs(vtx, tvtx, 1e-9)) {
0077 return true;
0078 }
0079 }
0080 return false;
0081 };
0082
0083 auto surfaces = cubo.orientedSurfaces(Transform3::Identity());
0084 for (const auto& srf : surfaces) {
0085 auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.surface->bounds());
0086 for (const auto& vtx : pbounds->vertices()) {
0087 Vector3 glob = srf.surface->localToGlobal(gctx, vtx, {});
0088
0089 BOOST_CHECK(is_in(glob, vertices));
0090 }
0091 }
0092
0093 vertices = {{{0, 0, 0},
0094 {2, 0, 0.4},
0095 {2, 1, 0.4},
0096 {0, 1, 0},
0097 {0, 0, 1},
0098 {1.8, 0, 1},
0099 {1.8, 1, 1},
0100 {0, 1, 1}}};
0101 cubo = GenericCuboidVolumeBounds(vertices);
0102
0103 surfaces = cubo.orientedSurfaces(Transform3::Identity());
0104 for (const auto& srf : surfaces) {
0105 auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.surface->bounds());
0106 for (const auto& vtx : pbounds->vertices()) {
0107 Vector3 glob = srf.surface->localToGlobal(gctx, vtx, {});
0108
0109 BOOST_CHECK(is_in(glob, vertices));
0110 }
0111 }
0112
0113 Transform3 trf;
0114 trf = Translation3(Vector3(0, 8, -5)) *
0115 AngleAxis3(M_PI / 3., Vector3(1, -3, 9).normalized());
0116
0117 surfaces = cubo.orientedSurfaces(trf);
0118 for (const auto& srf : surfaces) {
0119 auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.surface->bounds());
0120 for (const auto& vtx : pbounds->vertices()) {
0121 Vector3 glob = srf.surface->localToGlobal(gctx, vtx, {});
0122
0123 BOOST_CHECK(is_in(trf.inverse() * glob, vertices));
0124 }
0125 }
0126 }
0127
0128 BOOST_AUTO_TEST_CASE(ply_test) {
0129 std::array<Vector3, 8> vertices;
0130 vertices = {{{0, 0, 0},
0131 {2, 0, 0},
0132 {2, 1, 0},
0133 {0, 1, 0},
0134 {0, 0, 1},
0135 {2, 0, 1},
0136 {2, 1, 1},
0137 {0, 1, 1}}};
0138 GenericCuboidVolumeBounds cubo(vertices);
0139 PlyVisualization3D<double> ply;
0140 cubo.draw(ply);
0141
0142 std::ofstream os("cuboid.ply");
0143 os << ply << std::flush;
0144 os.close();
0145 }
0146
0147 BOOST_AUTO_TEST_CASE(bounding_box_creation) {
0148 float tol = 1e-4;
0149 std::array<Vector3, 8> vertices;
0150 vertices = {{{0, 0, 0},
0151 {2, 0, 0.4},
0152 {2, 1, 0.4},
0153 {0, 1, 0},
0154 {0, 0, 1},
0155 {1.8, 0, 1},
0156 {1.8, 1, 1},
0157 {0, 1, 1}}};
0158
0159 GenericCuboidVolumeBounds gcvb(vertices);
0160 auto bb = gcvb.boundingBox();
0161
0162 Transform3 rot;
0163 rot = AngleAxis3(M_PI / 2., Vector3::UnitX());
0164
0165 BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0166 BOOST_CHECK_EQUAL(bb.max(), Vector3(2, 1, 1));
0167 BOOST_CHECK_EQUAL(bb.min(), Vector3(0., 0., 0.));
0168
0169 bb = gcvb.boundingBox(&rot);
0170
0171 BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0172 CHECK_CLOSE_ABS(bb.max(), Vector3(2, 0, 1), tol);
0173 BOOST_CHECK_EQUAL(bb.min(), Vector3(0, -1, 0));
0174
0175 rot = AngleAxis3(M_PI / 2., Vector3::UnitZ());
0176 bb = gcvb.boundingBox(&rot);
0177 BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0178 CHECK_CLOSE_ABS(bb.max(), Vector3(0, 2, 1), tol);
0179 CHECK_CLOSE_ABS(bb.min(), Vector3(-1, 0., 0.), tol);
0180
0181 rot = AngleAxis3(0.542, Vector3::UnitZ()) *
0182 AngleAxis3(M_PI / 5., Vector3(1, 3, 6).normalized());
0183
0184 bb = gcvb.boundingBox(&rot);
0185 BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0186 CHECK_CLOSE_ABS(bb.max(), Vector3(1.00976, 2.26918, 1.11988), tol);
0187 CHECK_CLOSE_ABS(bb.min(), Vector3(-0.871397, 0, -0.0867708), tol);
0188
0189
0190 const auto boundValues = gcvb.values();
0191 BOOST_CHECK_EQUAL(boundValues.size(), 24u);
0192
0193 auto bValueArrray =
0194 to_array<GenericCuboidVolumeBounds::BoundValues::eSize, ActsScalar>(
0195 boundValues);
0196 GenericCuboidVolumeBounds gcvbCopy(bValueArrray);
0197 BOOST_CHECK_EQUAL(gcvbCopy.values().size(), 24u);
0198
0199
0200 rot = AngleAxis3(0.542, Vector3::UnitZ()) *
0201 AngleAxis3(M_PI / 5., Vector3(1, 3, 6).normalized());
0202
0203 bb = gcvbCopy.boundingBox(&rot);
0204 BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0205 CHECK_CLOSE_ABS(bb.max(), Vector3(1.00976, 2.26918, 1.11988), tol);
0206 CHECK_CLOSE_ABS(bb.min(), Vector3(-0.871397, 0, -0.0867708), tol);
0207 }
0208
0209 BOOST_AUTO_TEST_CASE(GenericCuboidVolumeBoundarySurfaces) {
0210 std::array<Vector3, 8> vertices;
0211 vertices = {{{0, 0, 0},
0212 {4, 0, 0},
0213 {4, 2, 0},
0214 {0, 2, 0},
0215 {0, 0, 2},
0216 {4, 0, 2},
0217 {4, 2, 2},
0218 {0, 2, 2}}};
0219
0220 GenericCuboidVolumeBounds cubo(vertices);
0221
0222 auto gcvbOrientedSurfaces = cubo.orientedSurfaces(Transform3::Identity());
0223 BOOST_CHECK_EQUAL(gcvbOrientedSurfaces.size(), 6);
0224
0225 for (auto& os : gcvbOrientedSurfaces) {
0226 auto geoCtx = GeometryContext();
0227 auto osCenter = os.surface->center(geoCtx);
0228 const auto* pSurface =
0229 dynamic_cast<const Acts::PlaneSurface*>(os.surface.get());
0230 BOOST_REQUIRE_MESSAGE(pSurface != nullptr,
0231 "The surface is not a plane surface");
0232 auto osNormal = pSurface->normal(geoCtx);
0233
0234 Vector3 insideGcvb = osCenter + os.direction * osNormal;
0235 Vector3 outsideGcvb = osCenter - os.direction * osNormal;
0236 BOOST_CHECK(cubo.inside(insideGcvb));
0237 BOOST_CHECK(!cubo.inside(outsideGcvb));
0238 }
0239 }
0240
0241 BOOST_AUTO_TEST_SUITE_END()
0242 }