File indexing completed on 2025-09-15 08:14:11
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/ConeBounds.hpp"
0010
0011 #include "Acts/Definitions/Tolerance.hpp"
0012 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0013 #include "Acts/Utilities/detail/periodic.hpp"
0014
0015 #include <cmath>
0016 #include <iomanip>
0017 #include <iostream>
0018 #include <limits>
0019 #include <optional>
0020
0021 namespace Acts {
0022
0023 ConeBounds::ConeBounds(double alpha, bool symm, double halfphi,
0024 double avphi) noexcept(false)
0025 : m_values({alpha, symm ? -std::numeric_limits<double>::infinity() : 0,
0026 std::numeric_limits<double>::infinity(), halfphi, avphi}),
0027 m_tanAlpha(std::tan(alpha)) {
0028 checkConsistency();
0029 }
0030
0031 ConeBounds::ConeBounds(double alpha, double minz, double maxz, double halfphi,
0032 double avphi) noexcept(false)
0033 : m_values({alpha, minz, maxz, halfphi, avphi}),
0034 m_tanAlpha(std::tan(alpha)) {
0035 checkConsistency();
0036 }
0037
0038 ConeBounds::ConeBounds(const std::array<double, eSize>& values) noexcept(false)
0039 : m_values(values), m_tanAlpha(std::tan(values[eAlpha])) {
0040 checkConsistency();
0041 }
0042
0043 std::vector<double> ConeBounds::values() const {
0044 return {m_values.begin(), m_values.end()};
0045 }
0046
0047 void ConeBounds::checkConsistency() noexcept(false) {
0048 if (get(eAlpha) < 0. || get(eAlpha) >= std::numbers::pi) {
0049 throw std::invalid_argument("ConeBounds: invalid open angle.");
0050 }
0051 if (get(eMinZ) > get(eMaxZ) ||
0052 std::abs(get(eMinZ) - get(eMaxZ)) < s_epsilon) {
0053 throw std::invalid_argument("ConeBounds: invalid z range setup.");
0054 }
0055 if (get(eHalfPhiSector) < 0. || std::abs(eHalfPhiSector) > std::numbers::pi) {
0056 throw std::invalid_argument("ConeBounds: invalid phi sector setup.");
0057 }
0058 if (get(eAveragePhi) != detail::radian_sym(get(eAveragePhi))) {
0059 throw std::invalid_argument("ConeBounds: invalid phi positioning.");
0060 }
0061 }
0062
0063 Vector2 ConeBounds::shifted(const Vector2& lposition) const {
0064 using detail::radian_sym;
0065
0066 auto x = r(lposition[1]);
0067 Vector2 shifted;
0068 shifted[1] = lposition[1];
0069 shifted[0] = std::isnormal(x)
0070 ? (x * radian_sym((lposition[0] / x) - get(eAveragePhi)))
0071 : lposition[0];
0072 return shifted;
0073 }
0074
0075 bool ConeBounds::inside(const Vector2& lposition) const {
0076 auto rphiHalf = r(lposition[1]) * get(eHalfPhiSector);
0077 return detail::VerticesHelper::isInsideRectangle(
0078 shifted(lposition), Vector2(-rphiHalf, get(eMinZ)),
0079 Vector2(rphiHalf, get(eMaxZ)));
0080 }
0081
0082 Vector2 ConeBounds::closestPoint(const Vector2& lposition,
0083 const SquareMatrix2& metric) const {
0084 auto rphiHalf = r(lposition[1]) * get(eHalfPhiSector);
0085 return detail::VerticesHelper::computeClosestPointOnAlignedBox(
0086 Vector2(-rphiHalf, get(eMinZ)), Vector2(rphiHalf, get(eMaxZ)),
0087 shifted(lposition), metric);
0088 }
0089
0090 Vector2 ConeBounds::center() const {
0091
0092 double zCentroid = 0.5 * (get(eMinZ) + get(eMaxZ));
0093
0094 double phiCentroid = get(eAveragePhi);
0095 return Vector2(phiCentroid, zCentroid);
0096 }
0097
0098 std::ostream& ConeBounds::toStream(std::ostream& sl) const {
0099 sl << std::setiosflags(std::ios::fixed);
0100 sl << std::setprecision(7);
0101 sl << "Acts::ConeBounds: (tanAlpha, minZ, maxZ, halfPhiSector, averagePhi) "
0102 "= ";
0103 sl << "(" << m_tanAlpha << ", " << get(eMinZ) << ", " << get(eMaxZ) << ", "
0104 << get(eHalfPhiSector) << ", " << get(eAveragePhi) << ")";
0105 sl << std::setprecision(-1);
0106 return sl;
0107 }
0108
0109 }