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