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