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/Algebra.hpp"
0012 #include "Acts/Definitions/Tolerance.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/ConeSurface.hpp"
0016 #include "Acts/Surfaces/CylinderSurface.hpp"
0017 #include "Acts/Surfaces/PlaneSurface.hpp"
0018 #include "Acts/Surfaces/RectangleBounds.hpp"
0019 #include "Acts/Surfaces/StrawSurface.hpp"
0020 #include "Acts/Surfaces/Surface.hpp"
0021 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0022 #include "Acts/Utilities/Intersection.hpp"
0023
0024 #include <cmath>
0025 #include <memory>
0026 #include <numbers>
0027
0028 using namespace Acts::UnitLiterals;
0029
0030 namespace Acts::Test {
0031
0032
0033 GeometryContext tgContext = GeometryContext();
0034
0035
0036 Transform3 aTransform = Transform3::Identity() *
0037 Translation3(30_cm, 7_m, -87_mm) *
0038 AngleAxis3(0.42, Vector3(-3., 1., 8).normalized());
0039
0040 BOOST_AUTO_TEST_SUITE(Surfaces)
0041
0042
0043
0044 BOOST_AUTO_TEST_CASE(CylinderIntersectionTests) {
0045 const double radius = 1_m;
0046 const double halfZ = 10_m;
0047
0048 auto testCylinderIntersection = [&](const Transform3& transform) -> void {
0049
0050 auto aCylinder =
0051 Surface::makeShared<CylinderSurface>(transform, radius, halfZ);
0052
0053
0054 auto lTransform = transform.linear();
0055
0056
0057 Vector3 onCylinder = transform * Vector3(radius, 0., 0.);
0058 Vector3 outCylinder = transform * Vector3(-radius, 0.6 * radius, 90_cm);
0059 Vector3 atCenter = transform * Vector3(0., 0., 0.);
0060 Vector3 atEdge = transform * Vector3(0.5 * radius, 0., 0.99 * halfZ);
0061
0062 Vector3 alongX = lTransform * Vector3(1., 0., 0.);
0063 Vector3 transXY = lTransform * Vector3(1., 1., 0).normalized();
0064 Vector3 transTZ = lTransform * Vector3(1., 0., 1.).normalized();
0065
0066
0067 auto aIntersection = aCylinder->intersect(tgContext, onCylinder, alongX,
0068 BoundaryTolerance::None());
0069
0070
0071 BOOST_CHECK(aIntersection[0].isValid());
0072
0073 BOOST_CHECK_EQUAL(aIntersection[0].status(), IntersectionStatus::reachable);
0074
0075 CHECK_CLOSE_ABS(aIntersection[0].pathLength(), -2_m, s_onSurfaceTolerance);
0076
0077 BOOST_CHECK(aIntersection[1].isValid());
0078
0079 BOOST_CHECK_EQUAL(aIntersection[1].status(), IntersectionStatus::onSurface);
0080
0081
0082 auto cIntersection = aCylinder->intersect(tgContext, atCenter, alongX,
0083 BoundaryTolerance::None());
0084
0085
0086 BOOST_CHECK(cIntersection[0].isValid());
0087
0088 BOOST_CHECK_EQUAL(cIntersection[0].status(), IntersectionStatus::reachable);
0089
0090 BOOST_CHECK(cIntersection[1].isValid());
0091
0092 BOOST_CHECK_EQUAL(cIntersection[1].status(), IntersectionStatus::reachable);
0093
0094 BOOST_CHECK_LT(
0095 cIntersection[1].pathLength() * cIntersection[0].pathLength(), 0);
0096
0097
0098 auto oIntersection = aCylinder->intersect(tgContext, outCylinder, alongX,
0099 BoundaryTolerance::None());
0100
0101
0102 BOOST_CHECK(oIntersection[0].isValid());
0103
0104 BOOST_CHECK_EQUAL(oIntersection[0].status(), IntersectionStatus::reachable);
0105
0106 BOOST_CHECK(oIntersection[1].isValid());
0107
0108 BOOST_CHECK_EQUAL(oIntersection[1].status(), IntersectionStatus::reachable);
0109
0110 BOOST_CHECK_GT(
0111 oIntersection[1].pathLength() * oIntersection[0].pathLength(), 0);
0112
0113
0114 auto iIntersection = aCylinder->intersect(tgContext, outCylinder, transXY,
0115 BoundaryTolerance::Infinite());
0116
0117
0118 BOOST_CHECK(!iIntersection[0].isValid());
0119
0120
0121 auto eIntersection = aCylinder->intersect(tgContext, atEdge, transTZ,
0122 BoundaryTolerance::Infinite());
0123
0124
0125 BOOST_CHECK(eIntersection[0].isValid());
0126
0127 BOOST_CHECK_LT(eIntersection[0].pathLength(), 0.);
0128
0129 BOOST_CHECK_EQUAL(eIntersection[0].status(), IntersectionStatus::reachable);
0130
0131 BOOST_CHECK(eIntersection[1].isValid());
0132
0133 BOOST_CHECK_EQUAL(eIntersection[1].status(), IntersectionStatus::reachable);
0134
0135 BOOST_CHECK_GT(eIntersection[1].pathLength(), 0.);
0136
0137
0138 eIntersection = aCylinder->intersect(tgContext, atEdge, transTZ,
0139 BoundaryTolerance::None());
0140
0141 BOOST_CHECK_LT(eIntersection[0].pathLength(), 0.);
0142
0143 BOOST_CHECK_EQUAL(eIntersection[0].status(), IntersectionStatus::reachable);
0144
0145 BOOST_CHECK(!eIntersection[1].isValid());
0146
0147 BOOST_CHECK_EQUAL(eIntersection[1].status(),
0148 IntersectionStatus::unreachable);
0149
0150 BOOST_CHECK_GT(eIntersection[1].pathLength(), 0.);
0151 };
0152
0153
0154 testCylinderIntersection(Transform3::Identity());
0155
0156
0157 testCylinderIntersection(aTransform);
0158 }
0159
0160
0161
0162 BOOST_AUTO_TEST_CASE(ConeIntersectionTest) {
0163 const double alpha = std::numbers::pi / 4.;
0164
0165 auto testConeIntersection = [&](const Transform3& transform) -> void {
0166
0167 auto aCone = Surface::makeShared<ConeSurface>(transform, alpha, true);
0168
0169
0170 auto lTransform = transform.linear();
0171
0172
0173 Vector3 onCone =
0174 transform * Vector3(std::numbers::sqrt2, std::numbers::sqrt2, 2.);
0175 Vector3 outCone = transform * Vector3(std::sqrt(4.), std::sqrt(4.), 2.);
0176
0177 Vector3 perpXY = lTransform * Vector3(1., -1., 0.).normalized();
0178 Vector3 transXY = lTransform * Vector3(1., 1., 0).normalized();
0179
0180
0181 BOOST_CHECK(aCone->isOnSurface(tgContext, onCone, transXY,
0182 BoundaryTolerance::Infinite()));
0183 auto aIntersection =
0184 aCone->intersect(tgContext, onCone, transXY, BoundaryTolerance::None());
0185
0186
0187 BOOST_CHECK(aIntersection[0].isValid());
0188
0189 BOOST_CHECK_EQUAL(aIntersection[0].status(), IntersectionStatus::reachable);
0190
0191 CHECK_CLOSE_ABS(aIntersection[0].pathLength(), -4., s_onSurfaceTolerance);
0192
0193 BOOST_CHECK(aIntersection[1].isValid());
0194
0195 BOOST_CHECK_EQUAL(aIntersection[1].status(), IntersectionStatus::onSurface);
0196
0197
0198 auto iIntersection = aCone->intersect(tgContext, outCone, perpXY,
0199 BoundaryTolerance::Infinite());
0200
0201
0202 BOOST_CHECK(!iIntersection[0].isValid());
0203 };
0204
0205
0206 testConeIntersection(Transform3::Identity());
0207
0208
0209 testConeIntersection(aTransform);
0210 }
0211
0212
0213
0214
0215
0216 BOOST_AUTO_TEST_CASE(PlanarIntersectionTest) {
0217 const double halfX = 1_m;
0218 const double halfY = 10_m;
0219
0220 auto testPlanarIntersection = [&](const Transform3& transform) -> void {
0221
0222 auto aPlane = Surface::makeShared<PlaneSurface>(
0223 transform, std::make_shared<RectangleBounds>(halfX, halfY));
0224
0225
0226 Vector3 before = transform * Vector3(-50_cm, -1_m, -1_m);
0227 Vector3 onit = transform * Vector3(11_cm, -22_cm, 0_m);
0228 Vector3 after = transform * Vector3(33_cm, 12_mm, 1_m);
0229 Vector3 outside = transform * Vector3(2. * halfX, 2 * halfY, -1_mm);
0230
0231
0232 auto lTransform = transform.linear();
0233
0234
0235 Vector3 direction = lTransform * Vector3(4_mm, 8_mm, 50_cm).normalized();
0236 Vector3 parallel = lTransform * Vector3(1., 1., 0.).normalized();
0237
0238
0239 auto fIntersection = aPlane->intersect(tgContext, before, direction,
0240 BoundaryTolerance::None());
0241
0242
0243 BOOST_CHECK(fIntersection[0].isValid());
0244
0245 BOOST_CHECK_EQUAL(fIntersection[0].status(), IntersectionStatus::reachable);
0246
0247 BOOST_CHECK_GT(fIntersection[0].pathLength(), 0.);
0248
0249 BOOST_CHECK(!fIntersection[1].isValid());
0250
0251
0252 auto oIntersection = aPlane->intersect(tgContext, onit, direction,
0253 BoundaryTolerance::None());
0254
0255 BOOST_CHECK(oIntersection[0].isValid());
0256
0257 BOOST_CHECK_EQUAL(oIntersection[0].status(), IntersectionStatus::onSurface);
0258
0259 BOOST_CHECK_LT(std::abs(oIntersection[0].pathLength()),
0260 s_onSurfaceTolerance);
0261
0262 BOOST_CHECK(!oIntersection[1].isValid());
0263
0264
0265 auto bIntersection = aPlane->intersect(tgContext, after, direction,
0266 BoundaryTolerance::None());
0267
0268 BOOST_CHECK(bIntersection[0].isValid());
0269
0270 BOOST_CHECK_EQUAL(bIntersection[0].status(), IntersectionStatus::reachable);
0271
0272 BOOST_CHECK_LT(bIntersection[0].pathLength(), 0.);
0273
0274 BOOST_CHECK(!bIntersection[1].isValid());
0275
0276
0277 auto mIntersection = aPlane->intersect(tgContext, outside, direction,
0278 BoundaryTolerance::None());
0279
0280 BOOST_CHECK(!mIntersection[0].isValid());
0281
0282 BOOST_CHECK_EQUAL(mIntersection[0].status(),
0283 IntersectionStatus::unreachable);
0284
0285 BOOST_CHECK_GT(mIntersection[0].pathLength(), 0.);
0286
0287 BOOST_CHECK(!mIntersection[1].isValid());
0288
0289
0290 auto iIntersection = aPlane->intersect(tgContext, before, parallel,
0291 BoundaryTolerance::None());
0292
0293 BOOST_CHECK(!iIntersection[0].isValid());
0294
0295 BOOST_CHECK_EQUAL(iIntersection[0].status(),
0296 IntersectionStatus::unreachable);
0297
0298 BOOST_CHECK(!iIntersection[1].isValid());
0299 };
0300
0301
0302 testPlanarIntersection(Transform3::Identity());
0303
0304
0305 testPlanarIntersection(aTransform);
0306 }
0307
0308
0309
0310
0311
0312 BOOST_AUTO_TEST_CASE(LineIntersectionTest) {
0313 const double radius = 1_m;
0314 const double halfZ = 10_m;
0315
0316 auto testLineAppraoch = [&](const Transform3& transform) -> void {
0317
0318 auto aLine = Surface::makeShared<StrawSurface>(transform, radius, halfZ);
0319
0320
0321 Vector3 before = transform * Vector3(-50_cm, -1_m, -1_m);
0322 Vector3 onit1 = transform * Vector3(0_m, 0_m, 0_m);
0323 Vector3 onitP = transform * Vector3(1_cm, 0_m, 23_um);
0324 Vector3 after = transform * Vector3(33_cm, 12_mm, 1_m);
0325 Vector3 outside = transform * Vector3(2., 0., 100_m);
0326
0327
0328 auto lTransform = transform.linear();
0329 Vector3 direction = lTransform * Vector3(2_cm, 3_cm, 5_cm).normalized();
0330 Vector3 normalP = lTransform * Vector3(0, 1., 0.).normalized();
0331 Vector3 parallel = lTransform * Vector3(0, 0., 1.).normalized();
0332
0333
0334
0335 auto fIntersection = aLine->intersect(tgContext, before, direction,
0336 BoundaryTolerance::None());
0337
0338 BOOST_CHECK(fIntersection[0].isValid());
0339
0340 BOOST_CHECK_EQUAL(fIntersection[0].status(), IntersectionStatus::reachable);
0341
0342 BOOST_CHECK_GT(fIntersection[0].pathLength(), 0.);
0343
0344 BOOST_CHECK(!fIntersection[1].isValid());
0345
0346
0347 auto oIntersection = aLine->intersect(tgContext, onit1, direction,
0348 BoundaryTolerance::None());
0349
0350 BOOST_CHECK(oIntersection[0].isValid());
0351
0352 BOOST_CHECK_EQUAL(oIntersection[0].status(), IntersectionStatus::onSurface);
0353
0354 BOOST_CHECK_LT(std::abs(oIntersection[0].pathLength()),
0355 s_onSurfaceTolerance);
0356
0357 BOOST_CHECK(!oIntersection[1].isValid());
0358
0359
0360 oIntersection =
0361 aLine->intersect(tgContext, onitP, normalP, BoundaryTolerance::None());
0362
0363 BOOST_CHECK(oIntersection[0].isValid());
0364
0365 BOOST_CHECK_EQUAL(oIntersection[0].status(), IntersectionStatus::onSurface);
0366
0367 BOOST_CHECK_LT(std::abs(oIntersection[0].pathLength()),
0368 s_onSurfaceTolerance);
0369
0370 BOOST_CHECK(!oIntersection[1].isValid());
0371
0372
0373 auto bIntersection = aLine->intersect(tgContext, after, direction,
0374 BoundaryTolerance::None());
0375
0376 BOOST_CHECK(bIntersection[0].isValid());
0377
0378 BOOST_CHECK_EQUAL(bIntersection[0].status(), IntersectionStatus::reachable);
0379
0380 BOOST_CHECK_LT(bIntersection[0].pathLength(), 0.);
0381
0382 BOOST_CHECK(!bIntersection[1].isValid());
0383
0384
0385 auto mIntersection = aLine->intersect(tgContext, outside, direction,
0386 BoundaryTolerance::None());
0387
0388 BOOST_CHECK(!mIntersection[0].isValid());
0389
0390 BOOST_CHECK_EQUAL(mIntersection[0].status(),
0391 IntersectionStatus::unreachable);
0392
0393 BOOST_CHECK_LT(mIntersection[0].pathLength(), 0.);
0394
0395 BOOST_CHECK(!mIntersection[1].isValid());
0396
0397
0398 auto iIntersection = aLine->intersect(tgContext, before, parallel,
0399 BoundaryTolerance::None());
0400
0401 BOOST_CHECK(!iIntersection[0].isValid());
0402
0403 BOOST_CHECK_EQUAL(iIntersection[0].status(),
0404 IntersectionStatus::unreachable);
0405
0406 BOOST_CHECK(!iIntersection[1].isValid());
0407 };
0408
0409
0410 testLineAppraoch(Transform3::Identity());
0411
0412
0413 testLineAppraoch(aTransform);
0414 }
0415
0416 BOOST_AUTO_TEST_SUITE_END()
0417
0418 }