EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PlaneSurface.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PlaneSurface.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-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 
17 
18 #include <cmath>
19 #include <iomanip>
20 #include <iostream>
21 #include <numeric>
22 
24  : GeometryObject(), Surface(other), m_bounds(other.m_bounds) {}
25 
27  const PlaneSurface& other,
28  const Transform3D& shift)
29  : GeometryObject(), Surface(gctx, other, shift), m_bounds(other.m_bounds) {}
30 
31 Acts::PlaneSurface::PlaneSurface(const Vector3D& center, const Vector3D& normal)
32  : Surface(), m_bounds(nullptr) {
37  Vector3D T = normal.normalized();
38  Vector3D U = std::abs(T.dot(Vector3D::UnitZ())) < s_curvilinearProjTolerance
39  ? Vector3D::UnitZ().cross(T).normalized()
40  : Vector3D::UnitX().cross(T).normalized();
41  Vector3D V = T.cross(U);
42  RotationMatrix3D curvilinearRotation;
43  curvilinearRotation.col(0) = U;
44  curvilinearRotation.col(1) = V;
45  curvilinearRotation.col(2) = T;
46 
47  // curvilinear surfaces are boundless
48  m_transform = Transform3D{curvilinearRotation};
49  m_transform.pretranslate(center);
50 }
51 
53  const std::shared_ptr<const PlanarBounds>& pbounds,
54  const Acts::DetectorElementBase& detelement)
55  : Surface(detelement), m_bounds(pbounds) {
57  throw_assert(pbounds, "PlaneBounds must not be nullptr");
58 }
59 
61  std::shared_ptr<const PlanarBounds> pbounds)
62  : Surface(transform), m_bounds(std::move(pbounds)) {}
63 
65  if (this != &other) {
66  Surface::operator=(other);
67  m_bounds = other.m_bounds;
68  }
69  return *this;
70 }
71 
73  return Surface::Plane;
74 }
75 
77  const GeometryContext& gctx, const Vector2D& lposition,
78  const Vector3D& /*unused*/) const {
79  return transform(gctx) *
80  Vector3D(lposition[Acts::eBoundLoc0], lposition[Acts::eBoundLoc1], 0.);
81 }
82 
84  const GeometryContext& gctx, const Vector3D& position,
85  const Vector3D& /*unused*/) const {
86  Vector3D loc3Dframe = transform(gctx).inverse() * position;
87  if (loc3Dframe.z() * loc3Dframe.z() >
89  return Result<Vector2D>::failure(SurfaceError::GlobalPositionNotOnSurface);
90  }
91  return Result<Vector2D>::success({loc3Dframe.x(), loc3Dframe.y()});
92 }
93 
94 std::string Acts::PlaneSurface::name() const {
95  return "Acts::PlaneSurface";
96 }
97 
99  if (m_bounds) {
100  return (*m_bounds.get());
101  }
102  return s_noBounds;
103 }
104 
106  const GeometryContext& gctx, size_t lseg) const {
107  // Prepare vertices and faces
108  std::vector<Vector3D> vertices;
109  std::vector<Polyhedron::FaceType> faces;
110  std::vector<Polyhedron::FaceType> triangularMesh;
111  bool exactPolyhedron = true;
112 
113  // If you have bounds you can create a polyhedron representation
114  if (m_bounds) {
115  auto vertices2D = m_bounds->vertices(lseg);
116  vertices.reserve(vertices2D.size() + 1);
117  for (const auto& v2D : vertices2D) {
118  vertices.push_back(transform(gctx) * Vector3D(v2D.x(), v2D.y(), 0.));
119  }
120  bool isEllipse = bounds().type() == SurfaceBounds::eEllipse;
121  bool innerExists = false, coversFull = false;
122  if (isEllipse) {
123  exactPolyhedron = false;
124  auto vStore = bounds().values();
125  innerExists = vStore[EllipseBounds::eInnerRx] > s_epsilon and
127  coversFull =
129  }
130  // All of those can be described as convex
131  // @todo same as for Discs: coversFull is not the right criterium
132  // for triangulation
133  if (not isEllipse or not innerExists or not coversFull) {
134  auto facesMesh = detail::FacesHelper::convexFaceMesh(vertices);
135  faces = facesMesh.first;
136  triangularMesh = facesMesh.second;
137  } else {
138  // Two concentric rings, we use the pure concentric method momentarily,
139  // but that creates too many unneccesarry faces, when only two
140  // are needed to descibe the mesh, @todo investigate merging flag
141  auto facesMesh = detail::FacesHelper::cylindricalFaceMesh(vertices, true);
142  faces = facesMesh.first;
143  triangularMesh = facesMesh.second;
144  }
145  } else {
146  throw std::domain_error(
147  "Polyhedron repr of boundless surface not possible.");
148  }
149  return Polyhedron(vertices, faces, triangularMesh, exactPolyhedron);
150 }