Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:30

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0010 
0011 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0012 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0013 #include "Acts/Surfaces/detail/BoundaryCheckHelper.hpp"
0014 
0015 #include <iomanip>
0016 #include <iostream>
0017 
0018 namespace Acts {
0019 
0020 TrapezoidBounds::TrapezoidBounds(double halfXnegY, double halfXposY,
0021                                  double halfY, double rotAngle) noexcept(false)
0022     : m_values({halfXnegY, halfXposY, halfY, rotAngle}),
0023       m_boundingBox(std::max(halfXnegY, halfXposY), halfY) {
0024   rotateBoundingBox();
0025   checkConsistency();
0026 }
0027 
0028 TrapezoidBounds::TrapezoidBounds(
0029     const std::array<double, eSize>& values) noexcept(false)
0030     : m_values(values),
0031       m_boundingBox(
0032           std::max(values[eHalfLengthXnegY], values[eHalfLengthXposY]),
0033           values[eHalfLengthY]) {
0034   rotateBoundingBox();
0035   checkConsistency();
0036 }
0037 
0038 std::vector<double> TrapezoidBounds::values() const {
0039   return {m_values.begin(), m_values.end()};
0040 }
0041 
0042 bool TrapezoidBounds::inside(const Vector2& lposition,
0043                              const BoundaryTolerance& boundaryTolerance) const {
0044   if (boundaryTolerance.isInfinite()) {
0045     return true;
0046   }
0047 
0048   const double hlXnY = get(TrapezoidBounds::eHalfLengthXnegY);
0049   const double hlXpY = get(TrapezoidBounds::eHalfLengthXposY);
0050   const double hlY = get(TrapezoidBounds::eHalfLengthY);
0051   const double rotAngle = get(TrapezoidBounds::eRotationAngle);
0052 
0053   const Vector2 extPosition = Eigen::Rotation2Dd(rotAngle) * lposition;
0054   const double x = extPosition[0];
0055   const double y = extPosition[1];
0056 
0057   if (auto absoluteBound = boundaryTolerance.asAbsoluteBoundOpt(true);
0058       absoluteBound.has_value()) {
0059     double tolX = absoluteBound->tolerance0;
0060     double tolY = absoluteBound->tolerance1;
0061 
0062     if (std::abs(y) - hlY > tolY) {
0063       // outside y range
0064       return false;
0065     }
0066 
0067     if (std::abs(x) - std::max(hlXnY, hlXpY) > tolX) {
0068       // outside x range
0069       return false;
0070     }
0071 
0072     if (std::abs(x) - std::min(hlXnY, hlXpY) <= tolX) {
0073       // inside x range
0074       return true;
0075     }
0076   }
0077 
0078   // at this stage, the point can only be in the triangles
0079   // run slow-ish polygon check
0080   Vector2 vertices[] = {
0081       {-hlXnY, -hlY}, {hlXnY, -hlY}, {hlXpY, hlY}, {-hlXpY, hlY}};
0082   return detail::insidePolygon(vertices, boundaryTolerance, extPosition,
0083                                std::nullopt);
0084 }
0085 
0086 std::vector<Vector2> TrapezoidBounds::vertices(
0087     unsigned int /*ignoredSegments*/) const {
0088   const double hlXnY = get(TrapezoidBounds::eHalfLengthXnegY);
0089   const double hlXpY = get(TrapezoidBounds::eHalfLengthXposY);
0090   const double hlY = get(TrapezoidBounds::eHalfLengthY);
0091   const double rotAngle = get(TrapezoidBounds::eRotationAngle);
0092 
0093   std::vector<Vector2> vertices = {
0094       {-hlXnY, -hlY}, {hlXnY, -hlY}, {hlXpY, hlY}, {-hlXpY, hlY}};
0095   for (auto& v : vertices) {
0096     v = Eigen::Rotation2Dd(-rotAngle) * v;
0097   }
0098   return vertices;
0099 }
0100 
0101 const RectangleBounds& TrapezoidBounds::boundingBox() const {
0102   return m_boundingBox;
0103 }
0104 
0105 std::ostream& TrapezoidBounds::toStream(std::ostream& sl) const {
0106   sl << std::setiosflags(std::ios::fixed);
0107   sl << std::setprecision(7);
0108   sl << "Acts::TrapezoidBounds:  (halfXnegY, halfXposY, halfY, rotAngle) = "
0109      << "(" << get(eHalfLengthXnegY) << ", " << get(eHalfLengthXposY) << ", "
0110      << get(eHalfLengthY) << ", " << get(eRotationAngle) << ")";
0111   sl << std::setprecision(-1);
0112   return sl;
0113 }
0114 
0115 void TrapezoidBounds::rotateBoundingBox() noexcept(false) {
0116   const double rotAngle = get(eRotationAngle);
0117 
0118   if (rotAngle != 0.) {
0119     m_boundingBox = ConvexPolygonBounds<4>(vertices()).boundingBox();
0120   }
0121 }
0122 
0123 void TrapezoidBounds::checkConsistency() noexcept(false) {
0124   if (get(eHalfLengthXnegY) <= 0. || get(eHalfLengthXposY) <= 0.) {
0125     throw std::invalid_argument("TrapezoidBounds: invalid local x setup");
0126   }
0127   if (get(eHalfLengthY) <= 0.) {
0128     throw std::invalid_argument("TrapezoidBounds: invalid local y setup");
0129   }
0130 }
0131 
0132 }  // namespace Acts