Warning, file /acts/Core/src/Geometry/CuboidVolumeBounds.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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/LineSurface.hpp"
0013 #include "Acts/Surfaces/PlaneSurface.hpp"
0014 #include "Acts/Surfaces/RectangleBounds.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Utilities/BoundingBox.hpp"
0017
0018 #include <algorithm>
0019 #include <array>
0020 #include <stdexcept>
0021 #include <utility>
0022
0023 namespace Acts {
0024
0025 CuboidVolumeBounds::CuboidVolumeBounds(double halex, double haley, double halez)
0026 : VolumeBounds(), m_values({halex, haley, halez}) {
0027 checkConsistency();
0028 buildSurfaceBounds();
0029 }
0030
0031 CuboidVolumeBounds::CuboidVolumeBounds(const std::array<double, eSize>& values)
0032 : m_values(values) {
0033 checkConsistency();
0034 buildSurfaceBounds();
0035 }
0036
0037 CuboidVolumeBounds::CuboidVolumeBounds(
0038 std::initializer_list<std::pair<BoundValues, double>> keyValues)
0039 : m_values({-1, -1, -1}) {
0040 for (const auto& [key, value] : keyValues) {
0041 m_values[key] = value;
0042 }
0043
0044 if (std::any_of(m_values.begin(), m_values.end(),
0045 [](const auto& val) { return val == -1; })) {
0046 throw std::logic_error("Missing bound values");
0047 }
0048 checkConsistency();
0049 buildSurfaceBounds();
0050 }
0051
0052 std::vector<double> CuboidVolumeBounds::values() const {
0053 return {m_values.begin(), m_values.end()};
0054 }
0055
0056 std::vector<Acts::OrientedSurface> Acts::CuboidVolumeBounds::orientedSurfaces(
0057 const Transform3& transform) const {
0058 std::vector<OrientedSurface> oSurfaces;
0059 oSurfaces.reserve(6);
0060
0061
0062 auto sf = Surface::makeShared<PlaneSurface>(
0063 transform * Translation3(0., 0., -get(eHalfLengthZ)), m_xyBounds);
0064 oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0065
0066 sf = Surface::makeShared<PlaneSurface>(
0067 transform * Translation3(0., 0., get(eHalfLengthZ)), m_xyBounds);
0068 oSurfaces.push_back(
0069 OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0070
0071
0072 sf = Surface::makeShared<PlaneSurface>(
0073 transform * Translation3(-get(eHalfLengthX), 0., 0.) * s_planeYZ,
0074 m_yzBounds);
0075 oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0076
0077 sf = Surface::makeShared<PlaneSurface>(
0078 transform * Translation3(get(eHalfLengthX), 0., 0.) * s_planeYZ,
0079 m_yzBounds);
0080 oSurfaces.push_back(
0081 OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0082
0083
0084 sf = Surface::makeShared<PlaneSurface>(
0085 transform * Translation3(0., -get(eHalfLengthY), 0.) * s_planeZX,
0086 m_zxBounds);
0087 oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()});
0088
0089 sf = Surface::makeShared<PlaneSurface>(
0090 transform * Translation3(0., get(eHalfLengthY), 0.) * s_planeZX,
0091 m_zxBounds);
0092 oSurfaces.push_back(
0093 OrientedSurface{std::move(sf), Direction::OppositeNormal()});
0094
0095 return oSurfaces;
0096 }
0097
0098 std::ostream& CuboidVolumeBounds::toStream(std::ostream& os) const {
0099 os << std::setiosflags(std::ios::fixed);
0100 os << std::setprecision(5);
0101 os << "Acts::CuboidVolumeBounds: (halfLengthX, halfLengthY, halfLengthZ) = ";
0102 os << "(" << get(eHalfLengthX) << ", " << get(eHalfLengthY) << ", "
0103 << get(eHalfLengthZ) << ")";
0104 return os;
0105 }
0106
0107 Volume::BoundingBox CuboidVolumeBounds::boundingBox(
0108 const Transform3* trf, const Vector3& envelope,
0109 const Volume* entity) const {
0110 Vector3 vmin(-get(eHalfLengthX), -get(eHalfLengthY), -get(eHalfLengthZ));
0111 Vector3 vmax(get(eHalfLengthX), get(eHalfLengthY), get(eHalfLengthZ));
0112
0113 Volume::BoundingBox box(entity, vmin - envelope, vmax + envelope);
0114 return trf == nullptr ? box : box.transformed(*trf);
0115 }
0116
0117 void CuboidVolumeBounds::buildSurfaceBounds() {
0118 m_xyBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthX),
0119 get(eHalfLengthY));
0120 m_yzBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthY),
0121 get(eHalfLengthZ));
0122 m_zxBounds = std::make_shared<const RectangleBounds>(get(eHalfLengthZ),
0123 get(eHalfLengthX));
0124 }
0125
0126 double CuboidVolumeBounds::referenceBorder(AxisDirection aDir) const {
0127 if (aDir <= AxisDirection::AxisZ) {
0128 return m_values[toUnderlying(aDir)];
0129 }
0130 if (aDir == AxisDirection::AxisR) {
0131 return std::sqrt(m_values[toUnderlying(AxisDirection::AxisX)] *
0132 m_values[toUnderlying(AxisDirection::AxisX)] +
0133 m_values[toUnderlying(AxisDirection::AxisY)] *
0134 m_values[toUnderlying(AxisDirection::AxisY)]);
0135 }
0136 return 0.0;
0137 }
0138
0139 bool CuboidVolumeBounds::inside(const Vector3& pos, double tol) const {
0140 return (std::abs(pos.x()) <= get(eHalfLengthX) + tol &&
0141 std::abs(pos.y()) <= get(eHalfLengthY) + tol &&
0142 std::abs(pos.z()) <= get(eHalfLengthZ) + tol);
0143 }
0144
0145 void CuboidVolumeBounds::checkConsistency() noexcept(false) {
0146 if (get(eHalfLengthX) <= 0 || get(eHalfLengthY) <= 0 ||
0147 get(eHalfLengthZ) <= 0.) {
0148 throw std::invalid_argument(
0149 "CuboidVolumeBounds: invalid input, zero or negative.");
0150 }
0151 }
0152
0153 void CuboidVolumeBounds::set(BoundValues bValue, double value) {
0154 set({{bValue, value}});
0155 }
0156
0157 void CuboidVolumeBounds::set(
0158 std::initializer_list<std::pair<BoundValues, double>> keyValues) {
0159 std::array<double, eSize> previous = m_values;
0160 for (const auto& [key, value] : keyValues) {
0161 m_values[key] = value;
0162 }
0163 try {
0164 checkConsistency();
0165 buildSurfaceBounds();
0166 } catch (std::invalid_argument& e) {
0167 m_values = previous;
0168 throw e;
0169 }
0170 }
0171
0172 CuboidVolumeBounds::BoundValues CuboidVolumeBounds::boundsFromAxisDirection(
0173 AxisDirection direction) {
0174 using enum AxisDirection;
0175 switch (direction) {
0176 case AxisX:
0177 return BoundValues::eHalfLengthX;
0178 case AxisY:
0179 return BoundValues::eHalfLengthY;
0180 case AxisZ:
0181 return BoundValues::eHalfLengthZ;
0182 default:
0183 throw std::invalid_argument("Invalid axis direction");
0184 }
0185 }
0186
0187 std::tuple<CuboidVolumeBounds::Face, CuboidVolumeBounds::Face,
0188 std::array<CuboidVolumeBounds::Face, 4>>
0189 CuboidVolumeBounds::facesFromAxisDirection(AxisDirection direction) {
0190 using enum AxisDirection;
0191 using enum CuboidVolumeBounds::Face;
0192 if (direction == AxisX) {
0193 return {NegativeXFace,
0194 PositiveXFace,
0195 {NegativeZFace, PositiveZFace, NegativeYFace, PositiveYFace}};
0196 } else if (direction == AxisY) {
0197 return {NegativeYFace,
0198 PositiveYFace,
0199 {NegativeZFace, PositiveZFace, NegativeXFace, PositiveXFace}};
0200 } else if (direction == AxisZ) {
0201 return {NegativeZFace,
0202 PositiveZFace,
0203 {NegativeXFace, PositiveXFace, NegativeYFace, PositiveYFace}};
0204 } else {
0205 throw std::invalid_argument("Invalid axis direction");
0206 }
0207 }
0208
0209 }
0210
0211
0212 std::ostream& operator<<(std::ostream& os,
0213 Acts::CuboidVolumeBounds::Face face) {
0214 using enum Acts::CuboidVolumeBounds::Face;
0215 switch (face) {
0216 case NegativeXFace:
0217 return os << "NegativeXFace";
0218 case PositiveXFace:
0219 return os << "PositiveXFace";
0220 case NegativeYFace:
0221 return os << "NegativeYFace";
0222 case PositiveYFace:
0223 return os << "PositiveYFace";
0224 case NegativeZFace:
0225 return os << "NegativeZFace";
0226 case PositiveZFace:
0227 return os << "PositiveZFace";
0228 default:
0229 return os << "UnknownFace";
0230 }
0231 }