Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IntersectionHelper2DTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file IntersectionHelper2DTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
12 
18 
19 #include <array>
20 
21 namespace Acts {
22 
23 namespace Test {
24 
25 BOOST_AUTO_TEST_SUITE(Surfaces)
26 
27 void basicChecks(bool circleCase = false) {
28  double rY = 10.;
29  double rX = circleCase ? rY : 5.;
30 
31  // Line along x - not intersecting
32  Vector2 start(12., 0.);
33  Vector2 direction(0., -1.);
34 
35  auto nosol = circleCase ? detail::IntersectionHelper2D::intersectCircle(
36  rY, start, direction)
38  rX, rY, start, direction);
39  BOOST_CHECK(not nosol[0]);
40  BOOST_CHECK(not nosol[1]);
41 
42  start = Vector2(4., -4.);
43  auto twosol = circleCase ? detail::IntersectionHelper2D::intersectCircle(
44  rY, start, direction)
46  rX, rY, start, direction);
47 
48  BOOST_CHECK(twosol[0]);
49  BOOST_CHECK(twosol[1]);
50 
51  start = Vector2(-4., 10.);
52  direction = Vector2(1., 0.);
53 
54  auto onesolY = circleCase ? detail::IntersectionHelper2D::intersectCircle(
55  rY, start, direction)
57  rX, rY, start, direction);
58 
59  BOOST_CHECK(onesolY[0]);
60  CHECK_CLOSE_ABS(onesolY[0].position().x(), 0., s_epsilon);
61  BOOST_CHECK(not onesolY[1]);
62 
63  start = Vector2(rX, -4);
64  direction = Vector2(0., 1.);
65 
66  auto onesolX = circleCase ? detail::IntersectionHelper2D::intersectCircle(
67  rY, start, direction)
69  rX, rY, start, direction);
70 
71  BOOST_CHECK(onesolX[0]);
72  CHECK_CLOSE_ABS(onesolX[0].position().y(), 0., s_epsilon);
73  BOOST_CHECK(not onesolX[1]);
74 }
75 
77 BOOST_AUTO_TEST_CASE(LineLineIntersection) {
78  Vector2 start(1., 1.);
79  Vector2 dir(1., 1.);
80 
81  // Not possible
83  Vector2(5., 3.), Vector2(6., 4), start, dir.normalized());
84 
85  BOOST_CHECK(not solution);
86 
87  // Possible
89  Vector2(5., 3.), Vector2(3., -1.), start, dir.normalized());
90 
91  BOOST_CHECK(solution);
92 
93  // In principle possible, but out of bound
94  start = Vector2(2, 3);
95  dir = Vector2(2, 1).normalized();
96 
98  Vector2(-1., -2.5), Vector2(3., 2.5), start, dir);
99 
100  BOOST_CHECK(solution);
101 
103  Vector2(-1., -2.5), Vector2(3., 2.5), start, dir, true);
104 
105  BOOST_CHECK(not solution);
106 }
107 
109 BOOST_AUTO_TEST_CASE(EllipseIntersection) {
110  // Basic checks for ellipse
111  basicChecks();
112 
113  // Specific checks for ellipse
114  double radiusX = 450.;
115  double radiusY = 275.;
116 
117  Vector2 start(-500., -300.);
118  Vector2 direction = Vector2(10., 4.).normalized();
119 
121  radiusX, radiusY, start, direction);
122 
123  // Numerically checked / per hand calculated
124  BOOST_CHECK(solution[0]);
125 
126  CHECK_CLOSE_ABS(solution[0].position().x(), -283.68, 0.01);
127  CHECK_CLOSE_ABS(solution[0].position().y(), -213.47, 0.01);
128  BOOST_CHECK(solution[0].pathLength() > 0.);
129 
130  BOOST_CHECK(solution[1]);
131 
132  CHECK_CLOSE_ABS(solution[1].position().x(), 433.65, 0.01);
133  CHECK_CLOSE_ABS(solution[1].position().y(), 73.46, 0.01);
134  BOOST_CHECK(solution[1].pathLength() > 0.);
135 
136  // Reverse checks will be done with circle (same code)
137 }
138 
140 BOOST_AUTO_TEST_CASE(CircleIntersection) {
141  // Basic checks for circle
142  basicChecks(true);
143 
144  // Specific checks for circle
145  double radius = 275.;
146 
147  Vector2 start(-500., -300.);
148  Vector2 direction = Vector2(1., 1.).normalized();
149 
150  auto solution =
151  detail::IntersectionHelper2D::intersectCircle(radius, start, direction);
152 
153  // Numerically checked / per hand calculated
154  BOOST_CHECK(solution[0]);
155 
156  CHECK_CLOSE_ABS(solution[0].position().x(), -266.771, 0.001);
157  CHECK_CLOSE_ABS(solution[0].position().y(), -66.771, 0.001);
158  BOOST_CHECK(solution[0].pathLength() > 0.);
159 
160  BOOST_CHECK(solution[1]);
161 
162  CHECK_CLOSE_ABS(solution[1].position().x(), 66.771, 0.001);
163  CHECK_CLOSE_ABS(solution[1].position().y(), 266.771, 0.001);
164  BOOST_CHECK(solution[1].pathLength() > 0.);
165 
166  // Reverse
167  start = Vector2(1500., 1700.);
168  direction = Vector2(1., 1.).normalized();
169  solution =
170  detail::IntersectionHelper2D::intersectCircle(radius, start, direction);
171 
172  BOOST_CHECK(solution[0]);
173  CHECK_CLOSE_ABS(solution[0].position().x(), 66.771, 0.001);
174  CHECK_CLOSE_ABS(solution[0].position().y(), 266.771, 0.001);
175  BOOST_CHECK(solution[0].pathLength() < 0.);
176 
177  BOOST_CHECK(solution[1]);
178  CHECK_CLOSE_ABS(solution[1].position().x(), -266.771, 0.001);
179  CHECK_CLOSE_ABS(solution[1].position().y(), -66.771, 0.001);
180  BOOST_CHECK(solution[1].pathLength() < 0.);
181 
182  // Reverse with reverse direction
183  direction = Vector2(-1., -1.).normalized();
184  solution =
185  detail::IntersectionHelper2D::intersectCircle(radius, start, direction);
186 
187  BOOST_CHECK(solution[0]);
188  CHECK_CLOSE_ABS(solution[0].position().x(), 66.771, 0.001);
189  CHECK_CLOSE_ABS(solution[0].position().y(), 266.771, 0.001);
190  BOOST_CHECK(solution[0].pathLength() > 0.);
191 
192  BOOST_CHECK(solution[1]);
193  CHECK_CLOSE_ABS(solution[1].position().x(), -266.771, 0.001);
194  CHECK_CLOSE_ABS(solution[1].position().y(), -66.771, 0.001);
195  BOOST_CHECK(solution[1].pathLength() > 0.);
196 }
197 
198 BOOST_AUTO_TEST_SUITE_END()
199 
200 } // namespace Test
201 } // namespace Acts