Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Polyhedron.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Polyhedron.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 <algorithm>
16 #include <cmath>
17 #include <limits>
18 #include <utility>
19 
21  size_t cvert = vertices.size();
22  vertices.insert(vertices.end(), other.vertices.begin(), other.vertices.end());
24  auto join = [&](std::vector<FaceType>& existing,
25  const std::vector<FaceType>& additional) -> void {
26  for (const auto& aface : additional) {
27  FaceType nface = aface;
28  std::transform(nface.begin(), nface.end(), nface.begin(),
29  [&](size_t x) { return (x + cvert); });
30  existing.push_back(nface);
31  }
32  };
33  // For faces and triangular mesh
34  join(faces, other.faces);
36 }
37 
39  for_each(vertices.begin(), vertices.end(),
40  [&](auto& v) { v = transform * v; });
41 }
42 
44  Extent extent;
45  auto vtxs = vertices;
46  std::transform(vtxs.begin(), vtxs.end(), vtxs.begin(), [&](auto& v) {
47  auto vt = (transform * v);
48  extent.extend(vt);
49  return (vt);
50  });
51 
52  // Special checks of binR for hyper plane surfaces
54  // Check inclusion of origin (i.e. convex around origin)
55  Vector3 origin = transform * Vector3(0., 0., extent.medium(binZ));
56  for (const auto& face : faces) {
57  std::vector<Vector3> tface;
58  tface.reserve(face.size());
59  for (auto f : face) {
60  tface.push_back(vtxs[f]);
61  }
62  if (detail::VerticesHelper::isInsidePolygon(origin, tface)) {
63  extent.range(binR).setMin(0.);
64  extent.range(binPhi).set(-M_PI, M_PI);
65  break;
66  }
67  }
68  if (exact) {
69  // Check for radial extend in 2D
70  auto radialDistance = [&](const Vector3& pos1,
71  const Vector3& pos2) -> double {
72  Vector2 O(0, 0);
73  Vector2 p1p2 = (pos2.block<2, 1>(0, 0) - pos1.block<2, 1>(0, 0));
74  double L = p1p2.norm();
75  Vector2 p1O = (O - pos1.block<2, 1>(0, 0));
76 
77  // Don't try parallel lines
78  if (L < 1e-7) {
79  return std::numeric_limits<double>::max();
80  }
81  double f = p1p2.dot(p1O) / L;
82 
83  // Clamp to [0, |p1p2|]
84  f = std::min(L, std::max(0., f));
85  Vector2 closest = f * p1p2.normalized() + pos1.block<2, 1>(0, 0);
86  double dist = (closest - O).norm();
87  return dist;
88  };
89 
90  for (size_t iv = 1; iv < vtxs.size() + 1; ++iv) {
91  size_t fpoint = iv < vtxs.size() ? iv : 0;
92  double testR = radialDistance(vtxs[fpoint], vtxs[iv - 1]);
93  extent.range(binR).expandMin(testR);
94  }
95  }
96  }
97  return extent;
98 }