File indexing completed on 2025-09-17 08:02:27
0001
0002
0003
0004
0005
0006
0007
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
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 ) const {
0139 return {m_vertices.begin(), m_vertices.end()};
0140 }
0141
0142 }