File indexing completed on 2026-07-26 08:19:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/PointSurface.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Tolerance.hpp"
0013 #include "Acts/Geometry/GeometryObject.hpp"
0014 #include "Acts/Surfaces/InfiniteBounds.hpp"
0015 #include "Acts/Surfaces/PointBounds.hpp"
0016 #include "Acts/Surfaces/SurfaceBounds.hpp"
0017 #include "Acts/Surfaces/SurfaceError.hpp"
0018 #include "Acts/Utilities/Intersection.hpp"
0019 #include "Acts/Utilities/VectorHelpers.hpp"
0020 #include "Acts/Utilities/detail/OstreamStateGuard.hpp"
0021
0022 #include <cmath>
0023 #include <iomanip>
0024 #include <iostream>
0025 #include <limits>
0026 #include <utility>
0027 #include <vector>
0028
0029 namespace Acts {
0030
0031 namespace {
0032
0033
0034
0035 RotationMatrix3 pointReferenceFrame(const Vector3& direction) {
0036 const Vector3 T = direction.normalized();
0037 const bool standard =
0038 std::abs(T.dot(Vector3::UnitZ())) < s_curvilinearProjTolerance;
0039 Vector3 U = (standard ? Vector3::UnitZ() : Vector3::UnitX()).cross(T);
0040 U.normalize();
0041 const Vector3 V = T.cross(U);
0042
0043 RotationMatrix3 rframe;
0044 rframe << U, V, T;
0045 return rframe;
0046 }
0047 }
0048
0049 PointSurface::PointSurface(const Vector3& center)
0050 : Surface(Transform3(Translation3(center))), m_bounds(nullptr) {}
0051
0052 PointSurface::PointSurface(const Vector3& center, double maxDistance)
0053 : Surface(Transform3(Translation3(center))),
0054 m_bounds(std::make_shared<const PointBounds>(maxDistance)) {}
0055
0056 PointSurface::PointSurface(const Transform3& transform,
0057 std::shared_ptr<const PointBounds> pbounds)
0058 : Surface(transform), m_bounds(std::move(pbounds)) {}
0059
0060 PointSurface::PointSurface(const GeometryContext& gctx,
0061 const PointSurface& other, const Transform3& shift)
0062 : GeometryObject{}, Surface(gctx, other, shift), m_bounds(other.m_bounds) {}
0063
0064 Vector3 PointSurface::normal(const GeometryContext& ,
0065 const Vector3& ,
0066 const Vector3& direction) const {
0067 return direction.normalized();
0068 }
0069
0070 Vector3 PointSurface::referencePosition(const GeometryContext& gctx,
0071 AxisDirection ) const {
0072 return center(gctx);
0073 }
0074
0075 RotationMatrix3 PointSurface::referenceFrame(const GeometryContext& ,
0076 const Vector3& ,
0077 const Vector3& direction) const {
0078 return pointReferenceFrame(direction);
0079 }
0080
0081 Vector3 PointSurface::localToGlobal(const GeometryContext& gctx,
0082 const Vector2& lposition,
0083 const Vector3& direction) const {
0084 const RotationMatrix3 rframe = pointReferenceFrame(direction);
0085 return center(gctx) + lposition[0] * rframe.col(0) +
0086 lposition[1] * rframe.col(1);
0087 }
0088
0089 Result<Vector2> PointSurface::globalToLocal(const GeometryContext& gctx,
0090 const Vector3& position,
0091 const Vector3& direction,
0092 double tolerance) const {
0093
0094 const Vector3 localPosition =
0095 referenceFrame(gctx, position, direction).inverse() *
0096 (position - center(gctx));
0097
0098
0099
0100
0101 if (std::abs(localPosition.z()) > std::abs(tolerance)) {
0102 return Result<Vector2>::failure(SurfaceError::GlobalPositionNotOnSurface);
0103 }
0104
0105 return Result<Vector2>::success(localPosition.head<2>());
0106 }
0107
0108 MultiIntersection3D PointSurface::intersect(
0109 const GeometryContext& gctx, const Vector3& position,
0110 const Vector3& direction, const BoundaryTolerance& boundaryTolerance,
0111 double tolerance) const {
0112
0113 const Vector3 pc = center(gctx);
0114
0115
0116
0117
0118 const double u = (pc - position).dot(direction);
0119
0120 IntersectionStatus status = std::abs(u) > std::abs(tolerance)
0121 ? IntersectionStatus::reachable
0122 : IntersectionStatus::onSurface;
0123 const Vector3 result = position + u * direction;
0124
0125
0126
0127 if (m_bounds != nullptr && !boundaryTolerance.isInfinite()) {
0128 const RotationMatrix3 rframe = pointReferenceFrame(direction);
0129 const Vector3 vecLocal = result - pc;
0130 const Vector2 local(vecLocal.dot(rframe.col(0)),
0131 vecLocal.dot(rframe.col(1)));
0132 if (!m_bounds->inside(local, boundaryTolerance)) {
0133 status = IntersectionStatus::unreachable;
0134 }
0135 }
0136
0137 return MultiIntersection3D(Intersection3D(result, u, status));
0138 }
0139
0140 BoundToFreeMatrix PointSurface::boundToFreeJacobian(
0141 const GeometryContext& gctx, const Vector3& position,
0142 const Vector3& direction) const {
0143 assert(isOnSurface(gctx, position, direction, BoundaryTolerance::Infinite()));
0144
0145 const RotationMatrix3 rframe = referenceFrame(gctx, position, direction);
0146 const Vector3 U = rframe.col(0);
0147 const Vector3 V = rframe.col(1);
0148 const Vector3 T = rframe.col(2);
0149
0150
0151 const Vector2 local = *globalToLocal(gctx, position, direction,
0152 std::numeric_limits<double>::max());
0153 const double loc0 = local.x();
0154 const double loc1 = local.y();
0155
0156
0157
0158
0159 BoundToFreeMatrix jacToGlobal =
0160 Surface::boundToFreeJacobian(gctx, position, direction);
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 const double cosTheta = direction.z();
0177 const double sinTheta = VectorHelpers::perp(direction);
0178
0179 jacToGlobal.block<3, 1>(eFreePos0, eBoundPhi) =
0180 loc0 * (cosTheta * V - sinTheta * T) - loc1 * cosTheta * U;
0181 jacToGlobal.block<3, 1>(eFreePos0, eBoundTheta) = loc1 * T;
0182
0183 return jacToGlobal;
0184 }
0185
0186 FreeToPathMatrix PointSurface::freeToPathDerivative(
0187 const GeometryContext& gctx, const Vector3& position,
0188 const Vector3& direction) const {
0189 assert(isOnSurface(gctx, position, direction, BoundaryTolerance::Infinite()));
0190
0191
0192
0193 FreeToPathMatrix freeToPath = FreeToPathMatrix::Zero();
0194
0195 freeToPath.segment<3>(eFreePos0) = -direction.transpose();
0196
0197
0198 freeToPath.segment<3>(eFreeDir0) = (center(gctx) - position).transpose();
0199
0200 return freeToPath;
0201 }
0202
0203 AlignmentToPathMatrix PointSurface::alignmentToPathDerivative(
0204 const GeometryContext& gctx, const Vector3& position,
0205 const Vector3& direction) const {
0206 static_cast<void>(gctx);
0207 static_cast<void>(position);
0208
0209 assert(isOnSurface(gctx, position, direction, BoundaryTolerance::Infinite()));
0210
0211
0212
0213 AlignmentToPathMatrix alignToPath = AlignmentToPathMatrix::Zero();
0214 alignToPath.segment<3>(eAlignmentCenter0) = direction.transpose();
0215
0216 return alignToPath;
0217 }
0218
0219 Matrix<2, 3> PointSurface::localCartesianToBoundLocalDerivative(
0220 const GeometryContext& , const Vector3& ) const {
0221
0222
0223
0224
0225 Matrix<2, 3> loc3DToLocBound = Matrix<2, 3>::Zero();
0226 loc3DToLocBound << 1, 0, 0, 0, 1, 0;
0227 return loc3DToLocBound;
0228 }
0229
0230 double PointSurface::pathCorrection(const GeometryContext& ,
0231 const Vector3& ,
0232 const Vector3& ) const {
0233 return 1.;
0234 }
0235
0236 const SurfaceBounds& PointSurface::bounds() const {
0237 if (m_bounds != nullptr) {
0238 return *m_bounds;
0239 }
0240 return s_noBounds;
0241 }
0242
0243 const std::shared_ptr<const PointBounds>& PointSurface::boundsPtr() const {
0244 return m_bounds;
0245 }
0246
0247 void PointSurface::assignSurfaceBounds(
0248 std::shared_ptr<const PointBounds> newBounds) {
0249 m_bounds = std::move(newBounds);
0250 }
0251
0252 std::string PointSurface::name() const {
0253 return "Acts::PointSurface";
0254 }
0255
0256 Polyhedron PointSurface::polyhedronRepresentation(
0257 const GeometryContext& gctx, unsigned int ) const {
0258
0259
0260 std::vector<Vector3> vertices;
0261 std::vector<Polyhedron::FaceType> faces;
0262 std::vector<Polyhedron::FaceType> triangularMesh;
0263
0264 const Transform3& ctransform = localToGlobalTransform(gctx);
0265 const double d = 1.;
0266 vertices.push_back(ctransform * Vector3(-d, 0., 0.));
0267 vertices.push_back(ctransform * Vector3(d, 0., 0.));
0268 vertices.push_back(ctransform * Vector3(0., -d, 0.));
0269 vertices.push_back(ctransform * Vector3(0., d, 0.));
0270 faces.push_back({0, 1});
0271 faces.push_back({2, 3});
0272 triangularMesh.push_back({0, 1, 2});
0273
0274 return Polyhedron(vertices, faces, triangularMesh);
0275 }
0276
0277 std::ostream& PointSurface::toStreamImpl(const GeometryContext& gctx,
0278 std::ostream& sl) const {
0279 detail::OstreamStateGuard guard{sl};
0280 sl << std::fixed << std::setprecision(7);
0281 sl << "Acts::PointSurface:" << std::endl;
0282 const Vector3& sfCenter = center(gctx);
0283 sl << " Center position (x, y, z) = (" << sfCenter.x() << ", "
0284 << sfCenter.y() << ", " << sfCenter.z() << ")";
0285 return sl;
0286 }
0287
0288 }