File indexing completed on 2025-01-18 09:11:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0010
0011 #include "Acts/Definitions/Direction.hpp"
0012 #include "Acts/Surfaces/PlaneSurface.hpp"
0013 #include "Acts/Surfaces/RectangleBounds.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/BoundingBox.hpp"
0016
0017 #include <utility>
0018
0019 namespace Acts {
0020
0021 CuboidVolumeBounds::CuboidVolumeBounds(double halex, double haley, double halez)
0022 : VolumeBounds(), m_values({halex, haley, halez}) {
0023 checkConsistency();
0024 buildSurfaceBounds();
0025 }
0026
0027 CuboidVolumeBounds::CuboidVolumeBounds(const std::array<double, eSize>& values)
0028 : m_values(values) {
0029 checkConsistency();
0030 buildSurfaceBounds();
0031 }
0032
0033 std::vector<double> CuboidVolumeBounds::values() const {
0034 return {m_values.begin(), m_values.end()};
0035 }
0036
0037 std::vector<Acts::OrientedSurface> Acts::CuboidVolumeBounds::orientedSurfaces(
0038 const Transform3& transform) const {
0039 std::vector<OrientedSurface> oSurfaces;
0040 oSurfaces.reserve(6);
0041
0042
0043 auto sf = Surface::makeShared<PlaneSurface>(
0044 transform * Translation3(0., 0., -get(eHalfLengthZ)), m_xyBounds);
0045 oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0046
0047 sf = Surface::makeShared<PlaneSurface>(
0048 transform * Translation3(0., 0., get(eHalfLengthZ)), m_xyBounds);
0049 oSurfaces.push_back(
0050 OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0051
0052
0053 sf = Surface::makeShared<PlaneSurface>(
0054 transform * Translation3(-get(eHalfLengthX), 0., 0.) * s_planeYZ,
0055 m_yzBounds);
0056 oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0057
0058 sf = Surface::makeShared<PlaneSurface>(
0059 transform * Translation3(get(eHalfLengthX), 0., 0.) * s_planeYZ,
0060 m_yzBounds);
0061 oSurfaces.push_back(
0062 OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0063
0064
0065 sf = Surface::makeShared<PlaneSurface>(
0066 transform * Translation3(0., -get(eHalfLengthY), 0.) * s_planeZX,
0067 m_zxBounds);
0068 oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0069
0070 sf = Surface::makeShared<PlaneSurface>(
0071 transform * Translation3(0., get(eHalfLengthY), 0.) * s_planeZX,
0072 m_zxBounds);
0073 oSurfaces.push_back(
0074 OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0075
0076 return oSurfaces;
0077 }
0078
0079 std::ostream& CuboidVolumeBounds::toStream(std::ostream& os) const {
0080 os << std::setiosflags(std::ios::fixed);
0081 os << std::setprecision(5);
0082 os << "Acts::CuboidVolumeBounds: (halfLengthX, halfLengthY, halfLengthZ) = ";
0083 os << "(" << get(eHalfLengthX) << ", " << get(eHalfLengthY) << ", "
0084 << get(eHalfLengthZ) << ")";
0085 return os;
0086 }
0087
0088 Volume::BoundingBox CuboidVolumeBounds::boundingBox(
0089 const Transform3* trf, const Vector3& envelope,
0090 const Volume* entity) const {
0091 Vector3 vmin(-get(eHalfLengthX), -get(eHalfLengthY), -get(eHalfLengthZ));
0092 Vector3 vmax(get(eHalfLengthX), get(eHalfLengthY), get(eHalfLengthZ));
0093
0094 Volume::BoundingBox box(entity, vmin - envelope, vmax + envelope);
0095 return trf == nullptr ? box : box.transformed(*trf);
0096 }
0097
0098 void CuboidVolumeBounds::buildSurfaceBounds() {
0099 m_xyBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthX),
0100 get(eHalfLengthY));
0101 m_yzBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthY),
0102 get(eHalfLengthZ));
0103 m_zxBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthZ),
0104 get(eHalfLengthX));
0105 }
0106
0107 double CuboidVolumeBounds::referenceBorder(AxisDirection aDir) const {
0108 if (aDir <= AxisDirection::AxisZ) {
0109 return m_values[toUnderlying(aDir)];
0110 }
0111 if (aDir == AxisDirection::AxisR) {
0112 return std::sqrt(m_values[toUnderlying(AxisDirection::AxisX)] *
0113 m_values[toUnderlying(AxisDirection::AxisX)] +
0114 m_values[toUnderlying(AxisDirection::AxisY)] *
0115 m_values[toUnderlying(AxisDirection::AxisY)]);
0116 }
0117 return 0.0;
0118 }
0119
0120 bool CuboidVolumeBounds::inside(const Vector3& pos, double tol) const {
0121 return (std::abs(pos.x()) <= get(eHalfLengthX) + tol &&
0122 std::abs(pos.y()) <= get(eHalfLengthY) + tol &&
0123 std::abs(pos.z()) <= get(eHalfLengthZ) + tol);
0124 }
0125
0126 void CuboidVolumeBounds::checkConsistency() noexcept(false) {
0127 if (get(eHalfLengthX) <= 0 || get(eHalfLengthY) <= 0 ||
0128 get(eHalfLengthZ) <= 0.) {
0129 throw std::invalid_argument(
0130 "CuboidVolumeBounds: invalid input, zero or negative.");
0131 }
0132 }
0133
0134 void CuboidVolumeBounds::set(BoundValues bValue, double value) {
0135 set({{bValue, value}});
0136 }
0137
0138 void CuboidVolumeBounds::set(
0139 std::initializer_list<std::pair<BoundValues, double>> keyValues) {
0140 std::array<double, eSize> previous = m_values;
0141 for (const auto& [key, value] : keyValues) {
0142 m_values[key] = value;
0143 }
0144 try {
0145 checkConsistency();
0146 buildSurfaceBounds();
0147 } catch (std::invalid_argument& e) {
0148 m_values = previous;
0149 throw e;
0150 }
0151 }
0152
0153 }