11 #include <tracking/trackFindingCDC/geometry/PerigeeCircle.h>
12 #include <tracking/trackFindingCDC/geometry/GeneralizedCircle.h>
13 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
15 #include <gtest/gtest.h>
19 using namespace TrackFindingCDC;
21 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_inheritance)
24 double curvature = 1.0;
25 double phi0 = M_PI / 4.0;
29 PerigeeCircle perigeeCircle(curvature, phi0, impact);
31 const GeneralizedCircle generalizedCircle(perigeeCircle.n0(),
35 EXPECT_NEAR(curvature, generalizedCircle.curvature(), 10e-7);
36 EXPECT_NEAR(impact, generalizedCircle.impact(), 10e-7);
37 EXPECT_NEAR(perigeeCircle.tangential().x(), generalizedCircle.tangential().x(), 10e-7);
38 EXPECT_NEAR(perigeeCircle.tangential().y(), generalizedCircle.tangential().y(), 10e-7);
40 PerigeeCircle roundTripCircle(generalizedCircle);
42 EXPECT_NEAR(curvature, roundTripCircle.curvature(), 10e-7);
43 EXPECT_NEAR(impact, roundTripCircle.impact(), 10e-7);
44 EXPECT_NEAR(cos(phi0), roundTripCircle.phi0Vec().x(), 10e-7);
45 EXPECT_NEAR(sin(phi0), roundTripCircle.phi0Vec().y(), 10e-7);
46 EXPECT_NEAR(phi0, roundTripCircle.phi0(), 10e-7);
48 PerigeeCircle roundTripCircle2;
49 roundTripCircle2.setN(generalizedCircle);
51 EXPECT_NEAR(curvature, roundTripCircle2.curvature(), 10e-7);
52 EXPECT_NEAR(impact, roundTripCircle2.impact(), 10e-7);
53 EXPECT_NEAR(cos(phi0), roundTripCircle2.tangential().x(), 10e-7);
54 EXPECT_NEAR(sin(phi0), roundTripCircle2.tangential().y(), 10e-7);
55 EXPECT_NEAR(phi0, roundTripCircle2.phi0(), 10e-7);
58 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_isLine)
61 Vector2D center = Vector2D(2.0, 0.0);
64 EXPECT_FALSE(circle.isLine());
67 float phi0 = M_PI / 2;
69 PerigeeCircle line = PerigeeCircle(curvature, phi0, impact);
71 EXPECT_TRUE(line.isLine());
74 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_isCircle)
77 Vector2D center = Vector2D(2.0, 0.0);
80 EXPECT_TRUE(circle.isCircle());
83 float phi0 = M_PI / 2;
85 PerigeeCircle line = PerigeeCircle(curvature, phi0, impact);
87 EXPECT_FALSE(line.isCircle());
90 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_orientation)
96 PerigeeCircle circle(curvature, phi0, impact);
97 EXPECT_EQ(ERotation::c_CounterClockwise, circle.orientation());
99 PerigeeCircle reversedCircle = circle.reversed();
100 EXPECT_EQ(ERotation::c_Clockwise, reversedCircle.orientation());
103 PerigeeCircle line(curvature, phi0, impact);
104 EXPECT_EQ(ERotation::c_CounterClockwise, line.orientation());
106 PerigeeCircle reversedLine = line.reversed();
107 EXPECT_EQ(ERotation::c_Clockwise, reversedLine.orientation());
110 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_minimalCylindricalR)
112 double curvature = 1.0 / 2.0;
113 double tangtialPhi = M_PI / 4.0;
114 double impact = -1.0;
117 PerigeeCircle perigeeCircle(curvature, tangtialPhi, impact);
119 EXPECT_EQ(1, perigeeCircle.minimalCylindricalR());
122 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_maximalCylindricalR)
124 double curvature = 1.0 / 2.0;
125 double tangtialPhi = M_PI / 4.0;
126 double impact = -1.0;
129 PerigeeCircle perigeeCircle(curvature, tangtialPhi, impact);
131 EXPECT_EQ(3, perigeeCircle.maximalCylindricalR());
134 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_setCenterAndRadius)
136 PerigeeCircle circle;
137 Vector2D center(0.5, 0.0);
139 circle.setCenterAndRadius(center, radius, ERotation::c_CounterClockwise);
141 EXPECT_TRUE(circle.isCircle());
142 EXPECT_FALSE(circle.isLine());
144 EXPECT_NEAR(1.5, circle.radius(), 10e-7);
145 EXPECT_NEAR(0.5, circle.center().x(), 10e-7);
146 EXPECT_NEAR(0.0, circle.center().y(), 10e-7);
149 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_distance)
152 double curvature = -1.;
153 double phi0 = 3. * M_PI / 4.;
154 double impact = 1. - sqrt(2.);
156 PerigeeCircle circle(curvature, phi0, impact);
158 EXPECT_TRUE(circle.isCircle());
159 EXPECT_FALSE(circle.isLine());
161 EXPECT_NEAR(-1.0, circle.radius(), 10e-7);
162 EXPECT_NEAR(1.0, circle.center().x(), 10e-7);
163 EXPECT_NEAR(1.0, circle.center().y(), 10e-7);
165 EXPECT_NEAR(curvature, circle.curvature(), 10e-7);
166 EXPECT_NEAR(phi0, circle.phi0(), 10e-7);
167 EXPECT_NEAR(impact, circle.impact(), 10e-7);
169 EXPECT_NEAR(0, circle.distance(Vector2D(1.0, 0.0)), 10e-7);
170 EXPECT_NEAR(0, circle.distance(Vector2D(0.0, 1.0)), 10e-7);
171 EXPECT_NEAR(impact, circle.distance(Vector2D(0.0, 0.0)), 10e-7);
173 EXPECT_NEAR(0.5, circle.distance(Vector2D(1.0, 0.5)), 10e-7);
175 EXPECT_NEAR(-0.5, circle.distance(Vector2D(1.0, 2.5)), 10e-7);
176 EXPECT_NEAR(-0.5, circle.distance(Vector2D(2.5, 1.0)), 10e-7);
179 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_invalidate)
181 PerigeeCircle defaultCircle;
182 EXPECT_TRUE(defaultCircle.isInvalid());
184 double curvature = -1.;
185 double phi0 = 3. * M_PI / 4.;
186 double impact = 1. - sqrt(2.0);
188 PerigeeCircle circle(curvature, phi0, impact);
191 EXPECT_TRUE(circle.isInvalid());
194 EXPECT_TRUE(circle.isInvalid());
196 circle = circle.reversed();
197 EXPECT_TRUE(circle.isInvalid());
199 GeneralizedCircle generalizedCircle;
200 generalizedCircle.invalidate();
201 circle.setN(generalizedCircle);
203 EXPECT_TRUE(circle.isInvalid());
206 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_passiveMoveBy)
208 Vector2D center(4.0, 2.0);
212 circle.passiveMoveBy(Vector2D(4.0, 0.0));
214 EXPECT_NEAR(5.0, circle.radius(), 10e-7);
215 EXPECT_NEAR(0.0, circle.perigee().x(), 10e-7);
216 EXPECT_NEAR(-3.0, circle.perigee().y(), 10e-7);
219 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_conformalTranform)
221 Vector2D center(1.0, 0.0);
226 Vector2D firstPos = circle.atArcLength(1);
227 Vector2D secondPos = circle.atArcLength(2);
229 EXPECT_NEAR(1.0, circle.curvature(), 10e-7);
230 EXPECT_NEAR(-M_PI / 2.0, circle.phi0(), 10e-7);
231 EXPECT_NEAR(0.0, circle.impact(), 10e-7);
232 EXPECT_NEAR(0.0, circle.distance(firstPos), 10e-7);
233 EXPECT_NEAR(0.0, circle.distance(secondPos), 10e-7);
235 circle.conformalTransform();
236 firstPos.conformalTransform();
237 secondPos.conformalTransform();
239 EXPECT_NEAR(0.0, circle.curvature(), 10e-7);
240 EXPECT_NEAR(M_PI / 2.0, circle.phi0(), 10e-7);
241 EXPECT_NEAR(-1.0 / 2.0, circle.impact(), 10e-7);
243 double firstConformalArcLength = circle.arcLengthTo(firstPos);
244 double secondConformalArcLength = circle.arcLengthTo(secondPos);
245 EXPECT_LT(firstConformalArcLength, secondConformalArcLength);
247 EXPECT_NEAR(0.0, circle.distance(firstPos), 10e-7);
248 EXPECT_NEAR(0.0, circle.distance(secondPos), 10e-7);
251 PerigeeCircle conformalCopy = circle.conformalTransformed();
252 EXPECT_NEAR(1.0, conformalCopy.curvature(), 10e-7);
253 EXPECT_NEAR(-M_PI / 2.0, conformalCopy.phi0(), 10e-7);
254 EXPECT_NEAR(0.0, conformalCopy.impact(), 10e-7);
257 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_closest)
259 PerigeeCircle circle(1.0, Vector2D(0.0, -1.0), 1.0);
260 Vector2D up(2.0, 2.0);
261 Vector2D far(5.0, 0.0);
263 EXPECT_EQ(Vector2D(2.0, 1.0), circle.closest(up));
264 EXPECT_EQ(Vector2D(3.0, 0.0), circle.closest(far));
267 double smallAngle = M_PI / 100;
268 Vector2D near(2.0 - cos(smallAngle), sin(smallAngle));
270 Vector2D closestOfNear = circle.closest(near);
271 EXPECT_NEAR(near.x(), closestOfNear.x(), 10e-7);
272 EXPECT_NEAR(near.y(), closestOfNear.y(), 10e-7);
275 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_atArcLength)
278 Vector2D center = Vector2D(2.0, 0.0);
282 double smallAngle = M_PI / 100;
283 Vector2D near(2.0 - cos(smallAngle), sin(smallAngle));
285 double nearArcLength =
286 -smallAngle * radius;
288 Vector2D atNear = circle.atArcLength(nearArcLength);
290 EXPECT_NEAR(near.x(), atNear.x(), 10e-7);
291 EXPECT_NEAR(near.y(), atNear.y(), 10e-7);
293 Vector2D down(2.0, -1.0);
294 double downArcLength =
295 +M_PI / 2.0 * radius;
297 Vector2D atDown = circle.atArcLength(downArcLength);
299 EXPECT_NEAR(down.x(), atDown.x(), 10e-7);
300 EXPECT_NEAR(down.y(), atDown.y(), 10e-7);
303 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_arcLengthToCylindricalR)
306 Vector2D center = Vector2D(2.0, 0.0);
310 double closestArcLength = circle.arcLengthToCylindricalR(1);
311 EXPECT_NEAR(0, closestArcLength, 10e-7);
313 double widestArcLength = circle.arcLengthToCylindricalR(3);
314 EXPECT_NEAR(M_PI, widestArcLength, 10e-7);
316 double halfArcLength = circle.arcLengthToCylindricalR(sqrt(5.0));
317 EXPECT_NEAR(M_PI / 2, halfArcLength, 10e-7);
319 double unreachableHighArcLength = circle.arcLengthToCylindricalR(4);
320 EXPECT_TRUE(std::isnan(unreachableHighArcLength));
322 double unreachableLowArcLength = circle.arcLengthToCylindricalR(0.5);
323 EXPECT_TRUE(std::isnan(unreachableLowArcLength));
326 PerigeeCircle reversedCircle = circle.reversed();
328 double closestArcLength = reversedCircle.arcLengthToCylindricalR(1);
329 EXPECT_NEAR(0, closestArcLength, 10e-7);
331 double widestArcLength = reversedCircle.arcLengthToCylindricalR(3);
332 EXPECT_NEAR(M_PI, widestArcLength, 10e-7);
334 double halfArcLength = reversedCircle.arcLengthToCylindricalR(sqrt(5.0));
335 EXPECT_NEAR(M_PI / 2, halfArcLength, 10e-7);
337 double unreachableHighArcLength = reversedCircle.arcLengthToCylindricalR(4);
338 EXPECT_TRUE(std::isnan(unreachableHighArcLength));
340 double unreachableLowArcLength = reversedCircle.arcLengthToCylindricalR(0.5);
341 EXPECT_TRUE(std::isnan(unreachableLowArcLength));
345 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_atCylindricalR)
348 Vector2D center = Vector2D(2.0, 0.0);
351 std::pair<Vector2D, Vector2D> solutions = circle.atCylindricalR(sqrt(5.0));
353 EXPECT_NEAR(2, solutions.first.x(), 10e-7);
354 EXPECT_NEAR(1, solutions.first.y(), 10e-7);
356 EXPECT_NEAR(2, solutions.second.x(), 10e-7);
357 EXPECT_NEAR(-1, solutions.second.y(), 10e-7);
360 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_atCylindricalR_opposite_orientation)
363 Vector2D center = Vector2D(2.0, 0.0);
366 std::pair<Vector2D, Vector2D> solutions = circle.atCylindricalR(sqrt(5.0));
368 EXPECT_NEAR(2, solutions.first.x(), 10e-7);
369 EXPECT_NEAR(-1, solutions.first.y(), 10e-7);
371 EXPECT_NEAR(2, solutions.second.x(), 10e-7);
372 EXPECT_NEAR(1, solutions.second.y(), 10e-7);
375 TEST(TrackFindingCDCTest, geometry_PerigeeCircle_OriginCircleFromPointDirection)
377 double expectedCurvature = 1.0 / 2.0;
378 double expectedPhi0 = M_PI / 4.0;
382 const PerigeeCircle perigeeCircle(expectedCurvature, expectedPhi0, impact);
383 const Vector2D& expectedPhi0Vec = perigeeCircle.phi0Vec();
385 double randomArcLength = 2.0;
386 Vector2D pos2D = perigeeCircle.atArcLength(randomArcLength);
387 Vector2D phiVec = perigeeCircle.tangential(pos2D);
389 double curvature = 2 * pos2D.cross(phiVec) / pos2D.normSquared();
390 Vector2D phi0Vec = phiVec.flippedOver(pos2D);
392 EXPECT_NEAR(expectedCurvature, curvature, 10e-7);
393 EXPECT_NEAR(expectedPhi0Vec.x(), phi0Vec.x(), 10e-7);
394 EXPECT_NEAR(expectedPhi0Vec.y(), phi0Vec.y(), 10e-7);
395 EXPECT_NEAR(expectedPhi0, phi0Vec.phi(), 10e-7);
396 EXPECT_NEAR(1, phi0Vec.norm(), 10e-7);