Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:02:27

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/ConvexPolygonBounds.hpp"
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0013 
0014 #include <ostream>
0015 #include <stdexcept>
0016 
0017 namespace Acts {
0018 
0019 std::ostream& ConvexPolygonBoundsBase::toStream(std::ostream& sl) const {
0020   std::vector<Vector2> vtxs = vertices();
0021   sl << "Acts::ConvexPolygonBounds<" << vtxs.size() << ">: vertices: [x, y]\n";
0022   for (std::size_t i = 0; i < vtxs.size(); i++) {
0023     const auto& vtx = vtxs[i];
0024     if (i > 0) {
0025       sl << ",";
0026       sl << "\n";
0027     }
0028     sl << "[" << vtx.x() << ", " << vtx.y() << "]";
0029   }
0030   return sl;
0031 }
0032 
0033 std::vector<double> ConvexPolygonBoundsBase::values() const {
0034   std::vector<double> values;
0035   for (const auto& vtx : vertices()) {
0036     values.push_back(vtx.x());
0037     values.push_back(vtx.y());
0038   }
0039   return values;
0040 }
0041 
0042 void ConvexPolygonBoundsBase::calculateCenter(
0043     std::span<const Vector2> vertices) {
0044   Vector2 sum = Vector2::Zero();
0045   for (const auto& vertex : vertices) {
0046     sum += vertex;
0047   }
0048   m_center = sum / static_cast<double>(vertices.size());
0049 }
0050 
0051 Vector2 ConvexPolygonBoundsBase::center() const {
0052   return m_center;
0053 }
0054 
0055 const RectangleBounds& ConvexPolygonBoundsBase::boundingBox() const {
0056   return m_boundingBox;
0057 }
0058 
0059 void ConvexPolygonBoundsBase::makeBoundingBox(
0060     std::span<const Vector2> vertices) {
0061   Vector2 vmax, vmin;
0062   vmax = vertices[0];
0063   vmin = vertices[0];
0064 
0065   for (std::size_t i = 1; i < vertices.size(); i++) {
0066     vmax = vmax.cwiseMax(vertices[i]);
0067     vmin = vmin.cwiseMin(vertices[i]);
0068   }
0069 
0070   m_boundingBox = {vmin, vmax};
0071 }
0072 
0073 void ConvexPolygonBoundsBase::checkConsistency(
0074     std::span<const Vector2> vertices) noexcept(false) {
0075   const std::size_t N = vertices.size();
0076   for (std::size_t i = 0; i < N; i++) {
0077     std::size_t j = (i + 1) % N;
0078     const Vector2& a = vertices[i];
0079     const Vector2& b = vertices[j];
0080 
0081     const Vector2 ab = b - a;
0082     const Vector2 normal = Vector2(ab.y(), -ab.x()).normalized();
0083 
0084     bool first = true;
0085     bool ref = false;
0086     // loop over all other vertices
0087     for (std::size_t k = 0; k < N; k++) {
0088       if (k == i || k == j) {
0089         continue;
0090       }
0091 
0092       const Vector2& c = vertices[k];
0093       double dot = normal.dot(c - a);
0094 
0095       if (first) {
0096         ref = std::signbit(dot);
0097         first = false;
0098         continue;
0099       }
0100 
0101       if (std::signbit(dot) != ref) {
0102         throw std::logic_error(
0103             "ConvexPolygon: Given vertices do not form convex hull");
0104       }
0105     }
0106   }
0107 }
0108 
0109 ConvexPolygonBounds<PolygonDynamic>::ConvexPolygonBounds(
0110     std::span<const Vector2> vertices)
0111     : m_vertices(vertices.begin(), vertices.end()) {
0112   if (vertices.size() < 3) {
0113     throw std::invalid_argument(
0114         "ConvexPolygonBounds: At least 3 vertices are required.");
0115   }
0116   checkConsistency(vertices);
0117   calculateCenter(vertices);
0118   makeBoundingBox(vertices);
0119 }
0120 
0121 ConvexPolygonBounds<PolygonDynamic>::ConvexPolygonBounds(
0122     const std::vector<Vector2>& vertices)
0123     : ConvexPolygonBounds{std::span<const Vector2>{vertices}} {}
0124 
0125 bool ConvexPolygonBounds<PolygonDynamic>::inside(
0126     const Vector2& lposition) const {
0127   return detail::VerticesHelper::isInsidePolygon(lposition, m_vertices);
0128 }
0129 
0130 Vector2 ConvexPolygonBounds<PolygonDynamic>::closestPoint(
0131     const Vector2& lposition, const SquareMatrix2& metric) const {
0132   return detail::VerticesHelper::computeClosestPointOnPolygon(
0133       lposition, std::span<const Vector2>(m_vertices.data(), m_vertices.size()),
0134       metric);
0135 }
0136 
0137 std::vector<Vector2> ConvexPolygonBounds<PolygonDynamic>::vertices(
0138     unsigned int /*lseg*/) const {
0139   return {m_vertices.begin(), m_vertices.end()};
0140 }
0141 
0142 }  // namespace Acts