ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ConeSurface.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ConeSurface.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018 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 // ConeSurface.ipp, Acts project
12 
13 inline detail::RealQuadraticEquation ConeSurface::intersectionSolver(
14  const GeometryContext& gctx, const Vector3D& position,
15  const Vector3D& direction) const {
16  // Transform into the local frame
17  Transform3D invTrans = transform(gctx).inverse();
18  Vector3D point1 = invTrans * position;
19  Vector3D dir1 = invTrans.linear() * direction;
20 
21  // See file header for the formula derivation
22  double tan2Alpha = bounds().tanAlpha() * bounds().tanAlpha(),
23  A = dir1.x() * dir1.x() + dir1.y() * dir1.y() -
24  tan2Alpha * dir1.z() * dir1.z(),
25  B = 2 * (dir1.x() * point1.x() + dir1.y() * point1.y() -
26  tan2Alpha * dir1.z() * point1.z()),
27  C = point1.x() * point1.x() + point1.y() * point1.y() -
28  tan2Alpha * point1.z() * point1.z();
29  if (A == 0.) {
30  A += 1e-16; // avoid division by zero
31  }
32 
34 }
35 
37  const GeometryContext& gctx, const Vector3D& position,
38  const Vector3D& direction, const BoundaryCheck& bcheck) const {
39  // Solve the quadratic equation
40  auto qe = intersectionSolver(gctx, position, direction);
41 
42  // If no valid solution return a non-valid intersection
43  if (qe.solutions == 0) {
44  return Intersection();
45  }
46 
47  // Absolute smallest solution is taken by default
48  double path =
49  qe.first * qe.first < qe.second * qe.second ? qe.first : qe.second;
50  Vector3D solution = position + path * direction;
51  Intersection::Status status =
53  ? Intersection::Status::onSurface
54  : Intersection::Status::reachable;
55 
56  // Boundary check necessary
57  if (bcheck and not isOnSurface(gctx, solution, direction, bcheck)) {
58  status = Intersection::Status::missed;
59  }
60 
61  // Now return the solution
62  return Intersection(transform(gctx) * solution, path, status);
63 }
64 
65 inline SurfaceIntersection ConeSurface::intersect(
66  const GeometryContext& gctx, const Vector3D& position,
67  const Vector3D& direction, const BoundaryCheck& bcheck) const {
68  // Solve the quadratic equation
69  auto qe = intersectionSolver(gctx, position, direction);
70 
71  // If no valid solution return a non-valid surfaceIntersection
72  if (qe.solutions == 0) {
73  return SurfaceIntersection();
74  }
75 
76  // Check the validity of the first solution
77  Vector3D solution1 = position + qe.first * direction;
78  Intersection::Status status1 =
79  (qe.first * qe.first < s_onSurfaceTolerance * s_onSurfaceTolerance)
80  ? Intersection::Status::onSurface
81  : Intersection::Status::reachable;
82 
83  if (bcheck and not isOnSurface(gctx, solution1, direction, bcheck)) {
84  status1 = Intersection::Status::missed;
85  }
86 
87  // Check the validity of the second solution
88  Vector3D solution2 = position + qe.first * direction;
89  Intersection::Status status2 =
90  (qe.second * qe.second < s_onSurfaceTolerance * s_onSurfaceTolerance)
91  ? Intersection::Status::onSurface
92  : Intersection::Status::reachable;
93  if (bcheck and not isOnSurface(gctx, solution2, direction, bcheck)) {
94  status2 = Intersection::Status::missed;
95  }
96 
97  const auto& tf = transform(gctx);
98  // Set the intersection
99  Intersection first(tf * solution1, qe.first, status1);
100  Intersection second(tf * solution2, qe.second, status2);
101  SurfaceIntersection cIntersection(first, this);
102  // Check one if its valid or neither is valid
103  bool check1 = status1 != Intersection::Status::missed or
104  (status1 == Intersection::Status::missed and
105  status2 == Intersection::Status::missed);
106  // Check and (eventually) go with the first solution
107  if ((check1 and qe.first * qe.first < qe.second * qe.second) or
108  status2 == Intersection::Status::missed) {
109  // And add the alternative
110  if (qe.solutions > 1) {
111  cIntersection.alternative = second;
112  }
113  } else {
114  // And add the alternative
115  if (qe.solutions > 1) {
116  cIntersection.alternative = first;
117  }
118  cIntersection.intersection = second;
119  }
120  return cIntersection;
121 }