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