Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IntersectionHelper2D.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file IntersectionHelper2D.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 
10 
14 
15 #include <cmath>
16 
18  const Vector2& s0, const Vector2& s1, const Vector2& origin,
19  const Vector2& dir, bool boundCheck) {
20  using Line = Eigen::ParametrizedLine<ActsScalar, 2>;
21  using Plane = Eigen::Hyperplane<ActsScalar, 2>;
22 
23  Vector2 edge(s1 - s0);
24  ActsScalar det = edge.x() * dir.y() - edge.y() * dir.x();
25  if (std::abs(det) < s_epsilon) {
26  return Intersection2D::invalid();
27  }
28 
29  auto line = Line(origin, dir);
30  auto d = line.intersectionParameter(Plane::Through(s0, s1));
31 
32  Vector2 intersection(origin + d * dir);
33  Intersection2D::Status status = Intersection2D::Status::reachable;
34  if (boundCheck) {
35  auto edgeToSol = intersection - s0;
36  if (edgeToSol.dot(edge) < 0. or edgeToSol.norm() > (edge).norm()) {
37  status = Intersection2D::Status::unreachable;
38  }
39  }
40  return Intersection2D(intersection, d, status);
41 }
42 
43 std::array<Acts::Intersection2D, 2>
45  ActsScalar Ry,
46  const Vector2& origin,
47  const Vector2& dir) {
48  auto createSolution =
49  [&](const Vector2& sol,
50  const Vector2& alt) -> std::array<Acts::Intersection2D, 2> {
51  Vector2 toSolD(sol - origin);
52  Vector2 toAltD(alt - origin);
53 
54  ActsScalar solD = std::copysign(toSolD.norm(), toSolD.dot(dir));
55  ActsScalar altD = std::copysign(toAltD.norm(), toAltD.dot(dir));
56 
57  if (std::abs(solD) < std::abs(altD)) {
58  return {Intersection2D(sol, solD, Intersection2D::Status::reachable),
59  Intersection2D(alt, altD, Intersection2D::Status::reachable)};
60  }
61  return {Intersection2D(alt, altD, Intersection2D::Status::reachable),
62  Intersection2D(sol, solD, Intersection2D::Status::reachable)};
63  };
64 
65  // Special cases first
66  if (std::abs(dir.x()) < s_epsilon) {
67  ActsScalar solx = origin.x();
68  ActsScalar D = 1. - solx * solx / (Rx * Rx);
69  if (D > 0.) {
70  ActsScalar sqrtD = std::sqrt(D);
71  Vector2 sol(solx, Ry * sqrtD);
72  Vector2 alt(solx, -Ry * sqrtD);
73  return createSolution(sol, alt);
74  } else if (std::abs(D) < s_epsilon) {
75  return {Intersection2D(Vector2(solx, 0.), -origin.y(),
76  Intersection2D::Status::reachable),
78  }
80  } else if (std::abs(dir.y()) < s_epsilon) {
81  ActsScalar soly = origin.y();
82  ActsScalar D = 1. - soly * soly / (Ry * Ry);
83  if (D > 0.) {
84  ActsScalar sqrtD = std::sqrt(D);
85  Vector2 sol(Rx * sqrtD, soly);
86  Vector2 alt(-Rx * sqrtD, soly);
87  return createSolution(sol, alt);
88  } else if (std::abs(D) < s_epsilon) {
89  return {Intersection2D(Vector2(0., soly), -origin.x(),
90  Intersection2D::Status::reachable),
92  }
94  }
95  // General solution
96  ActsScalar k = dir.y() / dir.x();
97  ActsScalar d = origin.y() - k * origin.x();
98  ActsScalar Ry2 = Ry * Ry;
99  ActsScalar alpha = 1. / (Rx * Rx) + k * k / Ry2;
100  ActsScalar beta = 2. * k * d / Ry2;
101  ActsScalar gamma = d * d / Ry2 - 1;
102  Acts::detail::RealQuadraticEquation solver(alpha, beta, gamma);
103  if (solver.solutions == 1) {
104  ActsScalar x = solver.first;
105  Vector2 sol(x, k * x + d);
106  Vector2 toSolD(sol - origin);
107  ActsScalar solD = std::copysign(toSolD.norm(), toSolD.dot(dir));
108  return {Intersection2D(sol, solD, Intersection2D::Status::reachable),
110  } else if (solver.solutions > 1) {
111  ActsScalar x0 = solver.first;
112  ActsScalar x1 = solver.second;
113  Vector2 sol(x0, k * x0 + d);
114  Vector2 alt(x1, k * x1 + d);
115  return createSolution(sol, alt);
116  }
118 }
119 
122  const Vector2& dir) {
123  auto intersections = intersectCircle(R, origin, dir);
124  for (const auto& candidate : intersections) {
125  if (candidate.pathLength() > 0.) {
126  ActsScalar phi = Acts::VectorHelpers::phi(candidate.position());
127  if (phi > phiMin and phi < phiMax) {
128  return candidate;
129  }
130  }
131  }
132  return Intersection2D::invalid();
133 }