File indexing completed on 2026-01-06 09:23:49
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/Definitions/Tolerance.hpp"
0014 #include "Acts/Geometry/BoundarySurfaceFace.hpp"
0015 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Geometry/VolumeBounds.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0021
0022 #include <algorithm>
0023 #include <array>
0024 #include <memory>
0025 #include <stdexcept>
0026 #include <utility>
0027 #include <vector>
0028
0029 using namespace Acts;
0030
0031 namespace ActsTests {
0032
0033 GeometryContext gctx = GeometryContext();
0034
0035 double hx{10.}, hy{20.}, hz{30.};
0036
0037 BOOST_AUTO_TEST_SUITE(GeometrySuite)
0038
0039 BOOST_AUTO_TEST_CASE(CuboidVolumeConstruction) {
0040
0041 CuboidVolumeBounds box(hx, hy, hz);
0042
0043
0044 CuboidVolumeBounds init(
0045 {{CuboidVolumeBounds::BoundValues::eHalfLengthX, hx},
0046 {CuboidVolumeBounds::BoundValues::eHalfLengthY, hy},
0047 {CuboidVolumeBounds::BoundValues::eHalfLengthZ, hz}});
0048
0049
0050 CuboidVolumeBounds copied(box);
0051 BOOST_CHECK_EQUAL(box, copied);
0052
0053
0054 CuboidVolumeBounds assigned = box;
0055 BOOST_CHECK_EQUAL(box, assigned);
0056 }
0057
0058 BOOST_AUTO_TEST_CASE(CuboidVolumeRecreation) {
0059 CuboidVolumeBounds original(hx, hy, hz);
0060 auto valvector = original.values();
0061 std::array<double, CuboidVolumeBounds::eSize> values{};
0062 std::copy_n(valvector.begin(), CuboidVolumeBounds::eSize, values.begin());
0063 CuboidVolumeBounds recreated(values);
0064 BOOST_CHECK_EQUAL(original, recreated);
0065 }
0066
0067 BOOST_AUTO_TEST_CASE(CuboidVolumeException) {
0068
0069 BOOST_CHECK_THROW(CuboidVolumeBounds(-hx, hy, hz), std::logic_error);
0070
0071 BOOST_CHECK_THROW(CuboidVolumeBounds(hx, -hy, hz), std::logic_error);
0072
0073 BOOST_CHECK_THROW(CuboidVolumeBounds(hx, hy, -hz), std::logic_error);
0074
0075 BOOST_CHECK_THROW(CuboidVolumeBounds(-hx, hy, -hz), std::logic_error);
0076
0077 BOOST_CHECK_THROW(CuboidVolumeBounds(-hx, -hy, hz), std::logic_error);
0078
0079 BOOST_CHECK_THROW(CuboidVolumeBounds(hx, -hy, -hz), std::logic_error);
0080
0081 BOOST_CHECK_THROW(CuboidVolumeBounds(-hx, -hy, -hz), std::logic_error);
0082
0083 BOOST_CHECK_THROW(
0084 CuboidVolumeBounds({{CuboidVolumeBounds::BoundValues::eHalfLengthX, hx},
0085 {CuboidVolumeBounds::BoundValues::eHalfLengthZ, hz}}),
0086 std::logic_error);
0087 }
0088
0089 BOOST_AUTO_TEST_CASE(CuboidVolumeProperties) {
0090 CuboidVolumeBounds box(hx, hy, hz);
0091
0092 BOOST_CHECK_EQUAL(box.type(), VolumeBounds::eCuboid);
0093
0094 CHECK_CLOSE_ABS(box.get(CuboidVolumeBounds::eHalfLengthX), hx, s_epsilon);
0095
0096 CHECK_CLOSE_ABS(box.get(CuboidVolumeBounds::eHalfLengthY), hy, s_epsilon);
0097
0098 CHECK_CLOSE_ABS(box.get(CuboidVolumeBounds::eHalfLengthZ), hz, s_epsilon);
0099
0100 std::vector<double> actvalues = box.values();
0101 std::vector<double> refvalues = {hx, hy, hz};
0102 BOOST_CHECK_EQUAL_COLLECTIONS(actvalues.begin(), actvalues.end(),
0103 refvalues.begin(), refvalues.end());
0104
0105
0106 Vector3 inside({5., 10., 8.});
0107
0108 std::vector<Vector3> outsides = {
0109 {20., 1., -2.}, {1., -30., 2.}, {-1., 2., 100.}};
0110
0111
0112 BOOST_CHECK(box.inside(inside, s_onSurfaceTolerance));
0113
0114
0115 for (const auto& outside : outsides) {
0116 BOOST_CHECK(!box.inside(outside, s_onSurfaceTolerance));
0117 }
0118
0119
0120 CHECK_CLOSE_ABS(box.referenceBorder(AxisDirection::AxisX), hx, s_epsilon);
0121 CHECK_CLOSE_ABS(box.referenceBorder(AxisDirection::AxisY), hy, s_epsilon);
0122 CHECK_CLOSE_ABS(box.referenceBorder(AxisDirection::AxisZ), hz, s_epsilon);
0123 CHECK_CLOSE_ABS(box.referenceBorder(AxisDirection::AxisR),
0124 std::sqrt(hx * hx + hy * hy), s_epsilon);
0125 }
0126
0127 BOOST_AUTO_TEST_CASE(CuboidVolumeBoundarySurfaces) {
0128 CuboidVolumeBounds box(5, 8, 7);
0129 auto cvbOrientedSurfaces = box.orientedSurfaces(Transform3::Identity());
0130
0131 BOOST_CHECK_EQUAL(cvbOrientedSurfaces.size(), 6);
0132
0133 auto geoCtx = GeometryContext();
0134
0135 for (auto& os : cvbOrientedSurfaces) {
0136 auto osCenter = os.surface->center(geoCtx);
0137 const auto* pSurface = dynamic_cast<const PlaneSurface*>(os.surface.get());
0138 BOOST_REQUIRE_MESSAGE(pSurface != nullptr,
0139 "The surface is not a plane surface");
0140 auto osNormal = pSurface->normal(geoCtx);
0141
0142 Vector3 insideBox = osCenter + os.direction * osNormal;
0143 Vector3 outsideBox = osCenter - os.direction * osNormal;
0144 BOOST_CHECK(box.inside(insideBox));
0145 BOOST_CHECK(!box.inside(outsideBox));
0146 }
0147
0148 Vector3 xaxis(1., 0., 0.);
0149 Vector3 yaxis(0., 1., 0.);
0150 Vector3 zaxis(0., 0., 1.);
0151
0152
0153 auto nFaceXY =
0154 cvbOrientedSurfaces[negativeFaceXY].surface->transform(geoCtx).rotation();
0155 BOOST_CHECK(nFaceXY.col(0).isApprox(xaxis));
0156 BOOST_CHECK(nFaceXY.col(1).isApprox(yaxis));
0157 BOOST_CHECK(nFaceXY.col(2).isApprox(zaxis));
0158
0159 auto pFaceXY =
0160 cvbOrientedSurfaces[positiveFaceXY].surface->transform(geoCtx).rotation();
0161 BOOST_CHECK(pFaceXY.col(0).isApprox(xaxis));
0162 BOOST_CHECK(pFaceXY.col(1).isApprox(yaxis));
0163 BOOST_CHECK(pFaceXY.col(2).isApprox(zaxis));
0164
0165 auto nFaceYZ =
0166 cvbOrientedSurfaces[negativeFaceYZ].surface->transform(geoCtx).rotation();
0167 BOOST_CHECK(nFaceYZ.col(0).isApprox(yaxis));
0168 BOOST_CHECK(nFaceYZ.col(1).isApprox(zaxis));
0169 BOOST_CHECK(nFaceYZ.col(2).isApprox(xaxis));
0170
0171 auto pFaceYZ =
0172 cvbOrientedSurfaces[positiveFaceYZ].surface->transform(geoCtx).rotation();
0173 BOOST_CHECK(pFaceYZ.col(0).isApprox(yaxis));
0174 BOOST_CHECK(pFaceYZ.col(1).isApprox(zaxis));
0175 BOOST_CHECK(pFaceYZ.col(2).isApprox(xaxis));
0176
0177 auto nFaceZX =
0178 cvbOrientedSurfaces[negativeFaceZX].surface->transform(geoCtx).rotation();
0179 BOOST_CHECK(nFaceZX.col(0).isApprox(zaxis));
0180 BOOST_CHECK(nFaceZX.col(1).isApprox(xaxis));
0181 BOOST_CHECK(nFaceZX.col(2).isApprox(yaxis));
0182
0183 auto pFaceZX =
0184 cvbOrientedSurfaces[positiveFaceZX].surface->transform(geoCtx).rotation();
0185 BOOST_CHECK(pFaceZX.col(0).isApprox(zaxis));
0186 BOOST_CHECK(pFaceZX.col(1).isApprox(xaxis));
0187 BOOST_CHECK(pFaceZX.col(2).isApprox(yaxis));
0188 }
0189
0190 BOOST_AUTO_TEST_CASE(CuboidVolumeBoundsSetValues) {
0191 CuboidVolumeBounds box(5, 8, 7);
0192
0193 for (auto bValue :
0194 {CuboidVolumeBounds::eHalfLengthX, CuboidVolumeBounds::eHalfLengthY,
0195 CuboidVolumeBounds::eHalfLengthZ}) {
0196 double target = 0.5 * box.get(bValue);
0197 double previous = box.get(bValue);
0198 BOOST_CHECK_THROW(box.set(bValue, -1), std::logic_error);
0199 BOOST_CHECK_EQUAL(box.get(bValue), previous);
0200 box.set(bValue, target);
0201 BOOST_CHECK_EQUAL(box.get(bValue), target);
0202 }
0203
0204 auto previous = box.values();
0205
0206 BOOST_CHECK_THROW(box.set({
0207 {CuboidVolumeBounds::eHalfLengthX, -1},
0208 {CuboidVolumeBounds::eHalfLengthY, 1},
0209 }),
0210 std::logic_error);
0211 auto act = box.values();
0212 BOOST_CHECK_EQUAL_COLLECTIONS(previous.begin(), previous.end(), act.begin(),
0213 act.end());
0214 }
0215
0216 BOOST_AUTO_TEST_SUITE_END()
0217
0218 }