ECCE @ 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 
11 #include <cmath>
12 #include <iomanip>
13 #include <iostream>
14 #include <numeric>
15 
21 
23  : GeometryObject(), Surface(other), m_bounds(other.m_bounds) {}
24 
26  const PlaneSurface& other,
27  const Transform3D& transf)
28  : GeometryObject(),
29  Surface(gctx, other, transf),
30  m_bounds(other.m_bounds) {}
31 
33  : Surface(), m_bounds(nullptr) {
38  Vector3D T = normal.normalized();
39  Vector3D U = std::abs(T.dot(Vector3D::UnitZ())) < s_curvilinearProjTolerance
40  ? Vector3D::UnitZ().cross(T).normalized()
41  : Vector3D::UnitX().cross(T).normalized();
42  Vector3D V = T.cross(U);
43  RotationMatrix3D curvilinearRotation;
44  curvilinearRotation.col(0) = U;
45  curvilinearRotation.col(1) = V;
46  curvilinearRotation.col(2) = T;
47 
48  // curvilinear surfaces are boundless
49  Transform3D transform{curvilinearRotation};
50  transform.pretranslate(center);
51  Surface::m_transform = std::make_shared<const Transform3D>(transform);
52 }
53 
55  const std::shared_ptr<const PlanarBounds>& pbounds,
56  const Acts::DetectorElementBase& detelement)
57  : Surface(detelement), m_bounds(pbounds) {
59  throw_assert(pbounds, "PlaneBounds must not be nullptr");
60 }
61 
62 Acts::PlaneSurface::PlaneSurface(std::shared_ptr<const Transform3D> htrans,
63  std::shared_ptr<const PlanarBounds> pbounds)
64  : Surface(std::move(htrans)), m_bounds(std::move(pbounds)) {}
65 
67  if (this != &other) {
68  Surface::operator=(other);
69  m_bounds = other.m_bounds;
70  }
71  return *this;
72 }
73 
75  return Surface::Plane;
76 }
77 
79  const Vector2D& lposition,
80  const Vector3D& /*gmom*/,
81  Vector3D& position) const {
82  Vector3D loc3Dframe(lposition[Acts::eLOC_X], lposition[Acts::eLOC_Y], 0.);
84  position = transform(gctx) * loc3Dframe;
85 }
86 
88  const Vector3D& position,
89  const Vector3D& /*gmom*/,
90  Acts::Vector2D& lposition) const {
92  Vector3D loc3Dframe = (transform(gctx).inverse()) * position;
93  lposition = Vector2D(loc3Dframe.x(), loc3Dframe.y());
94  return ((loc3Dframe.z() * loc3Dframe.z() >
96  ? false
97  : true);
98 }
99 
100 std::string Acts::PlaneSurface::name() const {
101  return "Acts::PlaneSurface";
102 }
103 
105  if (m_bounds) {
106  return (*m_bounds.get());
107  }
108  return s_noBounds;
109 }
110 
112  const GeometryContext& gctx, size_t lseg) const {
113  // Prepare vertices and faces
114  std::vector<Vector3D> vertices;
115  std::vector<Polyhedron::FaceType> faces;
116  std::vector<Polyhedron::FaceType> triangularMesh;
117 
118  // If you have bounds you can create a polyhedron representation
119  if (m_bounds) {
120  auto vertices2D = m_bounds->vertices(lseg);
121  vertices.reserve(vertices2D.size() + 1);
122  for (const auto& v2D : vertices2D) {
123  vertices.push_back(transform(gctx) * Vector3D(v2D.x(), v2D.y(), 0.));
124  }
125  bool isEllipse = bounds().type() == SurfaceBounds::eEllipse;
126  bool innerExists = false, coversFull = false;
127  if (isEllipse) {
128  auto vStore = bounds().values();
129  innerExists = vStore[EllipseBounds::eInnerRx] > s_epsilon and
131  coversFull =
133  }
134  // All of those can be described as convex
135  // @todo same as for Discs: coversFull is not the right criterium
136  // for triangulation
137  if (not isEllipse or not innerExists or not coversFull) {
138  auto facesMesh = detail::FacesHelper::convexFaceMesh(vertices);
139  faces = facesMesh.first;
140  triangularMesh = facesMesh.second;
141  } else {
142  // Two concentric rings, we use the pure concentric method momentarily,
143  // but that creates too many unneccesarry faces, when only two
144  // are needed to descibe the mesh, @todo investigate merging flag
145  auto facesMesh = detail::FacesHelper::cylindricalFaceMesh(vertices, true);
146  faces = facesMesh.first;
147  triangularMesh = facesMesh.second;
148  }
149  } else {
150  throw std::domain_error(
151  "Polyhedron repr of boundless surface not possible.");
152  }
153  return Polyhedron(vertices, faces, triangularMesh);
154 }