File indexing completed on 2025-08-05 08:09:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0010
0011 #include <cmath>
0012 #include <cstddef>
0013
0014 std::vector<Acts::ActsScalar> Acts::detail::VerticesHelper::phiSegments(
0015 ActsScalar phiMin, ActsScalar phiMax,
0016 const std::vector<ActsScalar>& phiRefs, ActsScalar phiTolerance) {
0017
0018
0019 std::vector<ActsScalar> phiSegments;
0020 std::vector<ActsScalar> quarters = {-M_PI, -0.5 * M_PI, 0., 0.5 * M_PI, M_PI};
0021
0022 if (phiMin != -M_PI || phiMax != M_PI) {
0023 phiSegments.push_back(phiMin);
0024 for (unsigned int iq = 1; iq < 4; ++iq) {
0025 if (phiMin < quarters[iq] && phiMax > quarters[iq]) {
0026 phiSegments.push_back(quarters[iq]);
0027 }
0028 }
0029 phiSegments.push_back(phiMax);
0030 } else {
0031 phiSegments = quarters;
0032 }
0033
0034 if (!phiRefs.empty()) {
0035 for (const auto& phiRef : phiRefs) {
0036
0037 auto match = std::find_if(
0038 phiSegments.begin(), phiSegments.end(), [&](ActsScalar phiSeg) {
0039 return std::abs(phiSeg - phiRef) < phiTolerance;
0040 });
0041 if (match == phiSegments.end()) {
0042 phiSegments.push_back(phiRef);
0043 }
0044 }
0045 std::sort(phiSegments.begin(), phiSegments.end());
0046 }
0047 return phiSegments;
0048 }
0049
0050 std::vector<Acts::Vector2> Acts::detail::VerticesHelper::ellipsoidVertices(
0051 ActsScalar innerRx, ActsScalar innerRy, ActsScalar outerRx,
0052 ActsScalar outerRy, ActsScalar avgPhi, ActsScalar halfPhi,
0053 unsigned int lseg) {
0054
0055
0056 std::vector<Vector2> rvertices;
0057 std::vector<Vector2> ivertices;
0058 std::vector<Vector2> overtices;
0059
0060 bool innerExists = (innerRx > 0. && innerRy > 0.);
0061 bool closed = std::abs(halfPhi - M_PI) < s_onSurfaceTolerance;
0062
0063
0064 auto phiSegs = detail::VerticesHelper::phiSegments(
0065 avgPhi - halfPhi, avgPhi + halfPhi, {avgPhi});
0066
0067
0068 for (unsigned int iseg = 0; iseg < phiSegs.size() - 1; ++iseg) {
0069 int addon = (iseg == phiSegs.size() - 2 && !closed) ? 1 : 0;
0070 if (innerExists) {
0071 createSegment<Vector2, Transform2>(ivertices, {innerRx, innerRy},
0072 phiSegs[iseg], phiSegs[iseg + 1], lseg,
0073 addon);
0074 }
0075 createSegment<Vector2, Transform2>(overtices, {outerRx, outerRy},
0076 phiSegs[iseg], phiSegs[iseg + 1], lseg,
0077 addon);
0078 }
0079
0080
0081 if (!innerExists) {
0082 if (!closed) {
0083
0084 rvertices.push_back(Vector2(0., 0.));
0085 }
0086 rvertices.insert(rvertices.end(), overtices.begin(), overtices.end());
0087 } else if (!closed) {
0088 rvertices.insert(rvertices.end(), overtices.begin(), overtices.end());
0089 rvertices.insert(rvertices.end(), ivertices.rbegin(), ivertices.rend());
0090 } else {
0091 rvertices.insert(rvertices.end(), overtices.begin(), overtices.end());
0092 rvertices.insert(rvertices.end(), ivertices.begin(), ivertices.end());
0093 }
0094 return rvertices;
0095 }
0096
0097 std::vector<Acts::Vector2> Acts::detail::VerticesHelper::circularVertices(
0098 ActsScalar innerR, ActsScalar outerR, ActsScalar avgPhi, ActsScalar halfPhi,
0099 unsigned int lseg) {
0100 return ellipsoidVertices(innerR, innerR, outerR, outerR, avgPhi, halfPhi,
0101 lseg);
0102 }
0103
0104 bool Acts::detail::VerticesHelper::onHyperPlane(
0105 const std::vector<Acts::Vector3>& vertices, ActsScalar tolerance) {
0106
0107 if (vertices.size() < 4) {
0108 return true;
0109 }
0110
0111 auto hyperPlane = Eigen::Hyperplane<ActsScalar, 3>::Through(
0112 vertices[0], vertices[1], vertices[2]);
0113 for (std::size_t ip = 3; ip < vertices.size(); ++ip) {
0114 if (hyperPlane.absDistance(vertices[ip]) > tolerance) {
0115 return false;
0116 }
0117 }
0118 return true;
0119 }