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