File indexing completed on 2025-11-01 07:55:10
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Geometry/Extent.hpp"
0013 #include "Acts/Geometry/Polyhedron.hpp"
0014 #include "Acts/Surfaces/AnnulusBounds.hpp"
0015 #include "Acts/Surfaces/ConeBounds.hpp"
0016 #include "Acts/Surfaces/ConeSurface.hpp"
0017 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0018 #include "Acts/Surfaces/CylinderBounds.hpp"
0019 #include "Acts/Surfaces/CylinderSurface.hpp"
0020 #include "Acts/Surfaces/DiamondBounds.hpp"
0021 #include "Acts/Surfaces/DiscSurface.hpp"
0022 #include "Acts/Surfaces/DiscTrapezoidBounds.hpp"
0023 #include "Acts/Surfaces/EllipseBounds.hpp"
0024 #include "Acts/Surfaces/PlaneSurface.hpp"
0025 #include "Acts/Surfaces/RadialBounds.hpp"
0026 #include "Acts/Surfaces/RectangleBounds.hpp"
0027 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0028 #include "Acts/Utilities/Logger.hpp"
0029 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0030
0031 #include <tuple>
0032 #include <vector>
0033
0034 using namespace Acts;
0035 using namespace Acts::UnitLiterals;
0036
0037 Logging::Level logLevel = Logging::VERBOSE;
0038
0039 namespace ActsTests {
0040
0041
0042 const GeometryContext tgContext = GeometryContext();
0043
0044 const std::vector<std::tuple<std::string, unsigned int>> testModes = {
0045 {"Triangulate", 18}, {"Extrema", 1}};
0046
0047 const Transform3 transform = Transform3::Identity();
0048 const double epsAbs = 1e-12;
0049
0050 BOOST_AUTO_TEST_SUITE(SurfacesSuite)
0051
0052
0053 BOOST_AUTO_TEST_CASE(ConeSurfacePolyhedrons) {
0054 ACTS_LOCAL_LOGGER(
0055 Acts::getDefaultLogger("PolyhedronSurfacesTests", logLevel));
0056 ACTS_INFO("Test: ConeSurfacePolyhedrons");
0057
0058 const double hzPos = 35_mm;
0059 const double hzNeg = -20_mm;
0060 const double alpha = 0.234;
0061
0062 const double rMax = hzPos * std::tan(alpha);
0063
0064 for (const auto& [mode, segments] : testModes) {
0065 ACTS_INFO("\tMode: " << mode);
0066
0067
0068 {
0069 auto cone = std::make_shared<ConeBounds>(alpha, 0_mm, hzPos);
0070 auto oneCone = Surface::makeShared<ConeSurface>(transform, cone);
0071 auto oneConePh = oneCone->polyhedronRepresentation(tgContext, segments);
0072
0073 const auto extent = oneConePh.extent();
0074 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMax, epsAbs);
0075 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs);
0076 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax, epsAbs);
0077 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax, epsAbs);
0078 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0_mm, epsAbs);
0079 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs);
0080 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0_mm, epsAbs);
0081 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs);
0082
0083 const unsigned int expectedFaces = 4 * segments;
0084 BOOST_CHECK_EQUAL(oneConePh.faces.size(), expectedFaces);
0085
0086 BOOST_CHECK_EQUAL(oneConePh.vertices.size(), expectedFaces + 2);
0087 }
0088
0089
0090 {
0091 const double hzpMin = 10_mm;
0092 const double rMin = hzpMin * std::tan(alpha);
0093
0094 auto conePiece = std::make_shared<ConeBounds>(alpha, hzpMin, hzPos);
0095 auto oneConePiece =
0096 Surface::makeShared<ConeSurface>(transform, conePiece);
0097 auto oneConePiecePh =
0098 oneConePiece->polyhedronRepresentation(tgContext, segments);
0099
0100 const auto extent = oneConePiecePh.extent();
0101 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMax, epsAbs);
0102 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs);
0103 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax, epsAbs);
0104 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax, epsAbs);
0105 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), rMin, epsAbs);
0106 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs);
0107 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), hzpMin, epsAbs);
0108 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs);
0109
0110 const unsigned int expectedFaces = 4 * segments;
0111 BOOST_CHECK_EQUAL(oneConePiecePh.faces.size(), expectedFaces);
0112 BOOST_CHECK_EQUAL(oneConePiecePh.vertices.size(),
0113 (expectedFaces + 1) * 2);
0114 }
0115
0116
0117 {
0118 auto coneBoth = std::make_shared<ConeBounds>(alpha, hzNeg, hzPos);
0119 auto twoCones = Surface::makeShared<ConeSurface>(transform, coneBoth);
0120 auto twoConesPh = twoCones->polyhedronRepresentation(tgContext, segments);
0121
0122 const auto extent = twoConesPh.extent();
0123 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMax, epsAbs);
0124 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs);
0125 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax, epsAbs);
0126 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax, epsAbs);
0127 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0_mm, epsAbs);
0128 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs);
0129 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), hzNeg, epsAbs);
0130 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs);
0131
0132 const unsigned int expectedFaces = 2 * segments * 4;
0133 const unsigned int expectedVertices = 2 * (4 * segments + 1) + 1;
0134
0135 BOOST_CHECK_EQUAL(twoConesPh.faces.size(), expectedFaces);
0136 BOOST_CHECK_EQUAL(twoConesPh.vertices.size(), expectedVertices);
0137 }
0138
0139
0140 {
0141 const double phiSector = 0.358;
0142
0143 auto sectoralBoth =
0144 std::make_shared<ConeBounds>(alpha, hzNeg, hzPos, phiSector, 0.);
0145 auto sectoralCones =
0146 Surface::makeShared<ConeSurface>(transform, sectoralBoth);
0147 auto sectoralConesPh =
0148 sectoralCones->polyhedronRepresentation(tgContext, segments);
0149
0150 const auto extent = sectoralConesPh.extent();
0151 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), 0, epsAbs);
0152 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs);
0153 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(),
0154 -rMax * std::sin(phiSector), epsAbs);
0155 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(),
0156 rMax * std::sin(phiSector), epsAbs);
0157 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0_mm, epsAbs);
0158 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs);
0159 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), hzNeg, epsAbs);
0160 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs);
0161
0162
0163 }
0164 }
0165 }
0166
0167
0168 BOOST_AUTO_TEST_CASE(CylinderSurfacePolyhedrons) {
0169 ACTS_LOCAL_LOGGER(
0170 Acts::getDefaultLogger("PolyhedronSurfacesTests", logLevel));
0171 ACTS_INFO("Test: CylinderSurfacePolyhedrons");
0172
0173 const double r = 25_mm;
0174 const double hZ = 35_mm;
0175
0176 for (const auto& mode : testModes) {
0177 ACTS_INFO("\tMode: " << std::get<std::string>(mode));
0178 const unsigned int segments = std::get<unsigned int>(mode);
0179
0180
0181 {
0182 auto cylinder = std::make_shared<CylinderBounds>(r, hZ);
0183 auto fullCylinder =
0184 Surface::makeShared<CylinderSurface>(transform, cylinder);
0185 auto fullCylinderPh =
0186 fullCylinder->polyhedronRepresentation(tgContext, segments);
0187
0188 const auto extent = fullCylinderPh.extent();
0189 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -r, epsAbs);
0190 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), r, epsAbs);
0191 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -r, epsAbs);
0192 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), r, epsAbs);
0193 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), r, epsAbs);
0194 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), r, epsAbs);
0195 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), -hZ, epsAbs);
0196 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hZ, epsAbs);
0197
0198 const unsigned int expectedFaces = 4 * segments;
0199 const unsigned int expectedVertices = (4 * segments + 1) * 2;
0200 BOOST_CHECK_EQUAL(fullCylinderPh.faces.size(), expectedFaces);
0201 BOOST_CHECK_EQUAL(fullCylinderPh.vertices.size(), expectedVertices);
0202 }
0203
0204
0205 {
0206 const double phiSector = 0.458;
0207
0208 auto sectorCentered = std::make_shared<CylinderBounds>(r, hZ, phiSector);
0209 auto centerSectoredCylinder =
0210 Surface::makeShared<CylinderSurface>(transform, sectorCentered);
0211 auto centerSectoredCylinderPh =
0212 centerSectoredCylinder->polyhedronRepresentation(tgContext, segments);
0213
0214 const auto extent = centerSectoredCylinderPh.extent();
0215 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(),
0216 r * std::cos(phiSector), epsAbs);
0217 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), r, epsAbs);
0218 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(),
0219 -r * std::sin(phiSector), epsAbs);
0220 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(),
0221 r * std::sin(phiSector), epsAbs);
0222 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), r, epsAbs);
0223 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), r, epsAbs);
0224 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), -hZ, epsAbs);
0225 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hZ, epsAbs);
0226 }
0227 }
0228 }
0229
0230
0231 BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) {
0232 ACTS_LOCAL_LOGGER(
0233 Acts::getDefaultLogger("PolyhedronSurfacesTests", logLevel));
0234 ACTS_INFO("Test: DiscSurfacePolyhedrons");
0235
0236 const double innerR = 10_mm;
0237 const double outerR = 25_mm;
0238 const double phiSector = 0.345;
0239
0240 for (const auto& mode : testModes) {
0241 ACTS_INFO("\tMode: " << std::get<std::string>(mode));
0242 const unsigned int segments = std::get<unsigned int>(mode);
0243
0244
0245 {
0246 auto disc = std::make_shared<RadialBounds>(0_mm, outerR);
0247 auto fullDisc = Surface::makeShared<DiscSurface>(transform, disc);
0248 auto fullDiscPh = fullDisc->polyhedronRepresentation(tgContext, segments);
0249
0250 const auto extent = fullDiscPh.extent();
0251 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -outerR,
0252 epsAbs);
0253 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs);
0254 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -outerR,
0255 epsAbs);
0256 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), outerR, epsAbs);
0257 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs);
0258 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs);
0259 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0260 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0261
0262 const unsigned int expectedFaces = 1;
0263
0264 const unsigned int expectedVertices = 4 * segments + 1 + 1;
0265 BOOST_CHECK_EQUAL(fullDiscPh.faces.size(), expectedFaces);
0266 BOOST_CHECK_EQUAL(fullDiscPh.vertices.size(), expectedVertices);
0267 }
0268
0269
0270 {
0271 auto radial = std::make_shared<RadialBounds>(innerR, outerR);
0272 auto radialDisc = Surface::makeShared<DiscSurface>(transform, radial);
0273 auto radialPh = radialDisc->polyhedronRepresentation(tgContext, segments);
0274
0275 const auto extent = radialPh.extent();
0276 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -outerR,
0277 epsAbs);
0278 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs);
0279 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -outerR,
0280 epsAbs);
0281 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), outerR, epsAbs);
0282 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), innerR, epsAbs);
0283 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs);
0284 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0285 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0286 }
0287
0288
0289 {
0290 auto sector = std::make_shared<RadialBounds>(0., outerR, phiSector);
0291 auto sectorDisc = Surface::makeShared<DiscSurface>(transform, sector);
0292 auto sectorPh = sectorDisc->polyhedronRepresentation(tgContext, segments);
0293
0294 const auto extent = sectorPh.extent();
0295 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), 0., epsAbs);
0296 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs);
0297 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(),
0298 -outerR * std::sin(phiSector), epsAbs);
0299 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(),
0300 outerR * std::sin(phiSector), epsAbs);
0301 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs);
0302 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs);
0303 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0304 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0305 }
0306
0307
0308 {
0309 auto sectorRing =
0310 std::make_shared<RadialBounds>(innerR, outerR, phiSector);
0311 auto sectorRingDisc =
0312 Surface::makeShared<DiscSurface>(transform, sectorRing);
0313 auto sectorRingDiscPh =
0314 sectorRingDisc->polyhedronRepresentation(tgContext, segments);
0315
0316 const auto extent = sectorRingDiscPh.extent();
0317 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(),
0318 innerR * std::cos(phiSector), epsAbs);
0319 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs);
0320 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(),
0321 -outerR * std::sin(phiSector), epsAbs);
0322 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(),
0323 outerR * std::sin(phiSector), epsAbs);
0324 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), innerR, epsAbs);
0325 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs);
0326 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0327 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0328 }
0329
0330
0331 {
0332 const double halfXmin = 10_mm;
0333 const double halfXmax = 20_mm;
0334
0335 auto trapezoidDisc = std::make_shared<DiscTrapezoidBounds>(
0336 halfXmin, halfXmax, innerR, outerR, 0.);
0337 auto trapezoidDiscSf =
0338 Surface::makeShared<DiscSurface>(transform, trapezoidDisc);
0339 auto trapezoidDiscSfPh =
0340 trapezoidDiscSf->polyhedronRepresentation(tgContext, segments);
0341 const auto extent = trapezoidDiscSfPh.extent();
0342
0343 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(),
0344 -std::abs(outerR - innerR) / 2., epsAbs);
0345 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(),
0346 std::abs(outerR - innerR) / 2., epsAbs);
0347 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -halfXmax,
0348 epsAbs);
0349 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), halfXmax,
0350 epsAbs);
0351 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs);
0352 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0353 std::hypot(std::abs(outerR - innerR) / 2., halfXmax),
0354 epsAbs);
0355 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0356 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0357 }
0358
0359
0360 {
0361 const double minRadius = 7.;
0362 const double maxRadius = 12.;
0363 const double minPhiA = 0.75;
0364 const double maxPhiA = 1.4;
0365 const Vector2 offset(0., 0.);
0366
0367 auto annulus = std::make_shared<AnnulusBounds>(minRadius, maxRadius,
0368 minPhiA, maxPhiA, offset);
0369 auto annulusDisc = Surface::makeShared<DiscSurface>(transform, annulus);
0370 auto annulusDiscPh =
0371 annulusDisc->polyhedronRepresentation(tgContext, segments);
0372 const auto extent = annulusDiscPh.extent();
0373 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), minRadius,
0374 epsAbs);
0375 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), maxRadius,
0376 epsAbs);
0377 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0378 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0379 }
0380 }
0381 }
0382
0383
0384 BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) {
0385 ACTS_LOCAL_LOGGER(
0386 Acts::getDefaultLogger("PolyhedronSurfacesTests", logLevel));
0387 ACTS_INFO("Test: PlaneSurfacePolyhedrons");
0388
0389 for (const auto& mode : testModes) {
0390 ACTS_INFO("\tMode: " << std::get<std::string>(mode));
0391 const unsigned int segments = std::get<unsigned int>(mode);
0392
0393
0394 {
0395 const double rhX = 10_mm;
0396 const double rhY = 25_mm;
0397
0398 auto rectangular = std::make_shared<RectangleBounds>(rhX, rhY);
0399 auto rectangularPlane =
0400 Surface::makeShared<PlaneSurface>(transform, rectangular);
0401 auto rectangularPh =
0402 rectangularPlane->polyhedronRepresentation(tgContext, segments);
0403
0404 const auto extent = rectangularPh.extent();
0405 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rhX, epsAbs);
0406 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rhX, epsAbs);
0407 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rhY, epsAbs);
0408 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rhY, epsAbs);
0409 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs);
0410 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0411 std::hypot(rhX, rhY), epsAbs);
0412 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0413 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0414
0415 BOOST_CHECK_EQUAL(rectangularPh.vertices.size(), 4);
0416 BOOST_CHECK_EQUAL(rectangularPh.faces.size(), 1);
0417
0418 const std::vector<std::size_t> expectedRect = {0, 1, 2, 3};
0419 BOOST_CHECK(rectangularPh.faces[0] == expectedRect);
0420 }
0421
0422
0423 {
0424 const double thX1 = 10_mm;
0425 const double thX2 = 25_mm;
0426 const double thY = 35_mm;
0427
0428 auto trapezoid = std::make_shared<TrapezoidBounds>(thX1, thX2, thY);
0429 auto trapezoidalPlane =
0430 Surface::makeShared<PlaneSurface>(transform, trapezoid);
0431 auto trapezoidalPh =
0432 trapezoidalPlane->polyhedronRepresentation(tgContext, segments);
0433
0434 const auto extent = trapezoidalPh.extent();
0435 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(),
0436 -std::max(thX1, thX2), epsAbs);
0437 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(),
0438 std::max(thX1, thX2), epsAbs);
0439 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -thY, epsAbs);
0440 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), thY, epsAbs);
0441 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs);
0442 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0443 std::hypot(std::max(thX1, thX2), thY), epsAbs);
0444 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0445 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0446
0447 BOOST_CHECK_EQUAL(trapezoidalPh.vertices.size(), 4);
0448 BOOST_CHECK_EQUAL(trapezoidalPh.faces.size(), 1);
0449
0450 const std::vector<std::size_t> expectedTra = {0, 1, 2, 3};
0451 BOOST_CHECK(trapezoidalPh.faces[0] == expectedTra);
0452 }
0453
0454
0455 {
0456 const double rMinX = 0_mm;
0457 const double rMinY = 0_mm;
0458 const double rMaxX = 30_mm;
0459 const double rMaxY = 40_mm;
0460 auto ellipse =
0461 std::make_shared<EllipseBounds>(rMinX, rMinY, rMaxX, rMaxY);
0462 auto ellipsoidPlane =
0463 Surface::makeShared<PlaneSurface>(transform, ellipse);
0464 auto ellipsoidPh =
0465 ellipsoidPlane->polyhedronRepresentation(tgContext, segments);
0466
0467 const auto extent = ellipsoidPh.extent();
0468 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMaxX, epsAbs);
0469 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMaxX, epsAbs);
0470 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMaxY, epsAbs);
0471 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMaxY, epsAbs);
0472 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(),
0473 std::min(rMinX, rMinY), epsAbs);
0474 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0475 std::max(rMaxX, rMaxY), epsAbs);
0476 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0477 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0478 }
0479
0480 {
0481 const double rMinX = 10_mm;
0482 const double rMinY = 20_mm;
0483 const double rMaxX = 30_mm;
0484 const double rMaxY = 40_mm;
0485 auto ellipseRing =
0486 std::make_shared<EllipseBounds>(rMinX, rMinY, rMaxX, rMaxY);
0487 auto ellipsoidRingPlane =
0488 Surface::makeShared<PlaneSurface>(transform, ellipseRing);
0489 auto ellipsoidRingPh =
0490 ellipsoidRingPlane->polyhedronRepresentation(tgContext, segments);
0491
0492 const auto extent = ellipsoidRingPh.extent();
0493 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMaxX, epsAbs);
0494 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMaxX, epsAbs);
0495 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMaxY, epsAbs);
0496 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMaxY, epsAbs);
0497 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(),
0498 std::min(rMinX, rMinY), epsAbs);
0499 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0500 std::max(rMaxX, rMaxY), epsAbs);
0501 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0502 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0503 }
0504
0505
0506 {
0507 std::vector<Vector2> vtxs = {
0508 Vector2(-40_mm, -10_mm), Vector2(-10_mm, -30_mm),
0509 Vector2(30_mm, -20_mm), Vector2(10_mm, 20_mm),
0510 Vector2(-20_mm, 50_mm), Vector2(-30_mm, 30_mm)};
0511
0512 auto hexagon = std::make_shared<ConvexPolygonBounds<6>>(vtxs);
0513 auto hexagonPlane = Surface::makeShared<PlaneSurface>(transform, hexagon);
0514 auto hexagonPlanePh =
0515 hexagonPlane->polyhedronRepresentation(tgContext, segments);
0516
0517 const auto extent = hexagonPlanePh.extent();
0518 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -40, epsAbs);
0519 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), 30, epsAbs);
0520 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -30, epsAbs);
0521 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), 50, epsAbs);
0522 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0, epsAbs);
0523 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::sqrt(2900),
0524 epsAbs);
0525 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0526 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0527 }
0528
0529
0530 {
0531 const double hMinX = 10_mm;
0532 const double hMedX = 20_mm;
0533 const double hMaxX = 15_mm;
0534 const double hMinY = 40_mm;
0535 const double hMaxY = 50_mm;
0536
0537 auto diamond =
0538 std::make_shared<DiamondBounds>(hMinX, hMedX, hMaxX, hMinY, hMaxY);
0539 auto diamondPlane = Surface::makeShared<PlaneSurface>(transform, diamond);
0540 auto diamondPh =
0541 diamondPlane->polyhedronRepresentation(tgContext, segments);
0542
0543 const auto extent = diamondPh.extent();
0544 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -hMedX, epsAbs);
0545 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), hMedX, epsAbs);
0546 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -hMinY, epsAbs);
0547 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), hMaxY, epsAbs);
0548 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs);
0549 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0550 std::hypot(hMaxX, hMaxY), epsAbs);
0551 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0552 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0553
0554 BOOST_CHECK_EQUAL(diamondPh.vertices.size(), 6);
0555 BOOST_CHECK_EQUAL(diamondPh.faces.size(), 1);
0556 }
0557 }
0558 }
0559
0560
0561 BOOST_AUTO_TEST_CASE(ShiftedSurfacePolyhedrons) {
0562 ACTS_LOCAL_LOGGER(
0563 Acts::getDefaultLogger("PolyhedronSurfacesTests", logLevel));
0564 ACTS_INFO("Test: ShiftedSurfacePolyhedrons");
0565
0566 const double shiftY = 50_mm;
0567 Vector3 shift(0., shiftY, 0.);
0568 Transform3 shiftedTransform = Transform3::Identity();
0569 shiftedTransform.pretranslate(shift);
0570
0571 for (const auto& mode : testModes) {
0572 ACTS_INFO("\tMode: " << std::get<std::string>(mode));
0573 const unsigned int segments = std::get<unsigned int>(mode);
0574
0575
0576 {
0577 const double rhX = 10_mm;
0578 const double rhY = 25_mm;
0579
0580 auto rectangular = std::make_shared<RectangleBounds>(rhX, rhY);
0581 auto rectangularPlane =
0582 Surface::makeShared<PlaneSurface>(shiftedTransform, rectangular);
0583 auto rectangularPh =
0584 rectangularPlane->polyhedronRepresentation(tgContext, segments);
0585
0586 const auto extent = rectangularPh.extent();
0587 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rhX, epsAbs);
0588 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rhX, epsAbs);
0589 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rhY + shiftY,
0590 epsAbs);
0591 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rhY + shiftY,
0592 epsAbs);
0593 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 25, epsAbs);
0594 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(),
0595 std::hypot(rhX, rhY + shiftY), epsAbs);
0596 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs);
0597 CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs);
0598
0599 BOOST_CHECK_EQUAL(rectangularPh.vertices.size(), 4);
0600 BOOST_CHECK_EQUAL(rectangularPh.faces.size(), 1);
0601
0602 const std::vector<std::size_t> expectedRect = {0, 1, 2, 3};
0603 BOOST_CHECK(rectangularPh.faces[0] == expectedRect);
0604 }
0605 }
0606 }
0607 BOOST_AUTO_TEST_SUITE_END()
0608
0609 }