File indexing completed on 2025-01-18 09:11:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/ConeBounds.hpp"
0010
0011 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0012 #include "Acts/Surfaces/detail/BoundaryCheckHelper.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,
0076 const BoundaryTolerance& boundaryTolerance) const {
0077 auto rphiHalf = r(lposition[1]) * get(eHalfPhiSector);
0078 return detail::insideAlignedBox(
0079 Vector2(-rphiHalf, get(eMinZ)), Vector2(rphiHalf, get(eMaxZ)),
0080 boundaryTolerance, shifted(lposition), std::nullopt);
0081 }
0082
0083 std::ostream& ConeBounds::toStream(std::ostream& sl) const {
0084 sl << std::setiosflags(std::ios::fixed);
0085 sl << std::setprecision(7);
0086 sl << "Acts::ConeBounds: (tanAlpha, minZ, maxZ, halfPhiSector, averagePhi) "
0087 "= ";
0088 sl << "(" << m_tanAlpha << ", " << get(eMinZ) << ", " << get(eMaxZ) << ", "
0089 << get(eHalfPhiSector) << ", " << get(eAveragePhi) << ")";
0090 sl << std::setprecision(-1);
0091 return sl;
0092 }
0093
0094 }