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