|
|
|||
File indexing completed on 2026-11-07 09:23:07
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 #pragma once 0010 0011 #include "Acts/Definitions/Algebra.hpp" 0012 #include "Acts/Definitions/Alignment.hpp" 0013 #include "Acts/Definitions/Tolerance.hpp" 0014 #include "Acts/Geometry/GeometryContext.hpp" 0015 #include "Acts/Geometry/Polyhedron.hpp" 0016 #include "Acts/Surfaces/BoundaryTolerance.hpp" 0017 #include "Acts/Surfaces/CylinderBounds.hpp" 0018 #include "Acts/Surfaces/RegularSurface.hpp" 0019 #include "Acts/Surfaces/Surface.hpp" 0020 #include "Acts/Surfaces/SurfaceConcept.hpp" 0021 #include "Acts/Utilities/AxisDefinitions.hpp" 0022 #include "Acts/Utilities/Logger.hpp" 0023 #include "Acts/Utilities/Result.hpp" 0024 #include "Acts/Utilities/detail/RealQuadraticEquation.hpp" 0025 0026 #include <memory> 0027 #include <numbers> 0028 #include <string> 0029 0030 namespace Acts { 0031 0032 /// @class CylinderSurface 0033 /// 0034 /// Class for a CylinderSurface in the TrackingGeometry. 0035 /// It inherits from Surface. 0036 /// 0037 /// The cylinder surface has a special role in the TrackingGeometry, 0038 /// since it builds the surfaces of all TrackingVolumes at container level 0039 /// for a cylindrical tracking geometry. 0040 /// 0041 /// @image html CylinderSurface.png 0042 0043 class CylinderSurface : public RegularSurface { 0044 friend class Surface; 0045 0046 protected: 0047 /// Constructor from Transform3 and CylinderBounds 0048 /// 0049 /// @param transform The transform to position the surface 0050 /// @param radius The radius of the cylinder 0051 /// @param halfz The half length in z 0052 /// @param halfphi The half opening angle 0053 /// @param avphi The phi value from which the opening angle spans (both sides) 0054 CylinderSurface(const Transform3& transform, double radius, double halfz, 0055 double halfphi = std::numbers::pi, double avphi = 0.); 0056 0057 /// Constructor from Transform3 and CylinderBounds arguments 0058 /// 0059 /// @param transform The transform to position the surface 0060 /// @param cbounds is a shared pointer to a cylindeer bounds object, 0061 /// it must exist (assert test) 0062 CylinderSurface(const Transform3& transform, 0063 std::shared_ptr<const CylinderBounds> cbounds); 0064 0065 /// Constructor from SurfacePlacementBase: Element proxy 0066 /// 0067 /// @param cbounds are the provided cylinder bounds (shared) 0068 /// @param placement Reference to the surface placement 0069 /// @note The Surface does not take any ownership over the 0070 /// `SurfacePlacementBase` it is expected that the user 0071 /// ensures the life-time of the `SurfacePlacementBase` 0072 /// and that the `Surface` is actually owned by 0073 /// the `SurfacePlacementBase` instance 0074 CylinderSurface(std::shared_ptr<const CylinderBounds> cbounds, 0075 const SurfacePlacementBase& placement); 0076 0077 /// Copy constructor 0078 /// 0079 /// @param other is the source cylinder for the copy 0080 CylinderSurface(const CylinderSurface& other); 0081 0082 /// Copy constructor - with shift 0083 /// 0084 /// @param gctx The current geometry context object, e.g. alignment 0085 /// @param other is the source cone surface 0086 /// @param shift is the additional transform applied after copying 0087 CylinderSurface(const GeometryContext& gctx, const CylinderSurface& other, 0088 const Transform3& shift); 0089 0090 public: 0091 ~CylinderSurface() override = default; 0092 0093 /// Assignment operator 0094 /// 0095 /// @param other is the source cylinder for the copy 0096 /// @return Reference to this CylinderSurface after assignment 0097 /// @deprecated Surface copy-assignment will be removed; copy via 0098 /// `Surface::makeShared<CylinderSurface>(other)` instead. 0099 [[deprecated( 0100 "Surface copy-assignment is deprecated and will be removed; copy via " 0101 "Surface::makeShared<CylinderSurface>(other) instead.")]] 0102 CylinderSurface& operator=(const CylinderSurface& other); 0103 0104 /// The binning position method - is overloaded for r-type binning 0105 /// 0106 /// @param gctx The current geometry context object, e.g. alignment 0107 /// @param aDir is the axis Direction of global binning to be done 0108 /// 0109 /// @return is the global position to be used for binning 0110 Vector3 referencePosition(const GeometryContext& gctx, 0111 AxisDirection aDir) const final; 0112 0113 /// Return the measurement frame - this is needed for alignment, in particular 0114 /// The measurement frame of a cylinder is the tangential plane at a given 0115 /// position 0116 /// 0117 /// @param gctx The current geometry context object, e.g. alignment 0118 /// @param position is the position where the measurement frame is defined 0119 /// @param direction is the momentum direction vector (ignored) 0120 /// @return rotation matrix that defines the measurement frame 0121 RotationMatrix3 referenceFrame(const GeometryContext& gctx, 0122 const Vector3& position, 0123 const Vector3& direction) const final; 0124 0125 /// Return the surface type 0126 /// @return Surface type identifier 0127 SurfaceType type() const override; 0128 0129 /// Return method for surface normal information 0130 /// @note for a Cylinder a local position is always required for the normal 0131 /// vector 0132 /// 0133 /// @param gctx The current geometry context object, e.g. alignment 0134 /// @param lposition is the local position for which the normal vector is 0135 /// requested 0136 /// 0137 /// @return normal vector at the local position by value 0138 Vector3 normal(const GeometryContext& gctx, 0139 const Vector2& lposition) const final; 0140 0141 /// Return method for surface normal information 0142 /// @note for a Cylinder a local position is always required for the normal 0143 /// vector 0144 /// 0145 /// @param gctx The current geometry context object, e.g. alignment 0146 /// @param position is the global position for which the normal vector is 0147 /// requested 0148 /// 0149 /// @return normal vector at the global position by value 0150 Vector3 normal(const GeometryContext& gctx, 0151 const Vector3& position) const final; 0152 0153 // Use overloads from `RegularSurface` 0154 using RegularSurface::globalToLocal; 0155 using RegularSurface::localToGlobal; 0156 using RegularSurface::normal; 0157 0158 /// Return method for the rotational symmetry axis 0159 /// 0160 /// @param gctx The current geometry context object, e.g. alignment 0161 /// 0162 /// @return the z-Axis of transform 0163 virtual Vector3 rotSymmetryAxis(const GeometryContext& gctx) const; 0164 0165 /// This method returns the CylinderBounds by reference 0166 /// @return Reference to the cylinder bounds 0167 const CylinderBounds& bounds() const final; 0168 0169 /// This method returns the shared_ptr to the CylinderBounds 0170 /// @return Shared pointer to the cylinder bounds 0171 const std::shared_ptr<const CylinderBounds>& boundsPtr() const; 0172 0173 /// Overwrite the existing surface bounds with new ones 0174 /// @param newBounds: Pointer to the new bounds 0175 void assignSurfaceBounds(std::shared_ptr<const CylinderBounds> newBounds); 0176 0177 /// Local to global transformation 0178 /// 0179 /// @param gctx The current geometry context object, e.g. alignment 0180 /// @param lposition is the local position to be transformed 0181 /// 0182 /// @return The global position by value 0183 Vector3 localToGlobal(const GeometryContext& gctx, 0184 const Vector2& lposition) const final; 0185 0186 /// Global to local transformation 0187 /// 0188 /// @param gctx The current geometry context object, e.g. alignment 0189 /// @param position is the global position to be transformed 0190 /// @param tolerance optional tolerance within which a point is considered 0191 /// valid on surface 0192 /// 0193 /// @return a Result<Vector2> which can be !ok() if the operation fails 0194 Result<Vector2> globalToLocal( 0195 const GeometryContext& gctx, const Vector3& position, 0196 double tolerance = s_onSurfaceTolerance) const final; 0197 0198 /// Straight line intersection schema from position/direction 0199 /// 0200 /// @param gctx The current geometry context object, e.g. alignment 0201 /// @param position The position to start from 0202 /// @param direction The direction at start 0203 /// @param boundaryTolerance the Boundary Check Tolerance 0204 /// @param tolerance the tolerance used for the intersection 0205 /// 0206 /// If possible returns both solutions for the cylinder 0207 /// 0208 /// @return SurfaceIntersection object (contains intersection & surface) 0209 MultiIntersection3D intersect( 0210 const GeometryContext& gctx, const Vector3& position, 0211 const Vector3& direction, 0212 const BoundaryTolerance& boundaryTolerance = 0213 BoundaryTolerance::Infinite(), 0214 double tolerance = s_onSurfaceTolerance) const final; 0215 0216 /// Path correction due to incident of the track 0217 /// 0218 /// @param gctx The current geometry context object, e.g. alignment 0219 /// @param position is the global position as a starting point 0220 /// @param direction is the global momentum direction at the starting point 0221 /// 0222 /// @return is the correction factor due to incident 0223 double pathCorrection(const GeometryContext& gctx, const Vector3& position, 0224 const Vector3& direction) const final; 0225 0226 /// Return method for properly formatted output string 0227 /// @return String representation of the class name 0228 std::string name() const override; 0229 0230 /// Return a Polyhedron for a cylinder 0231 /// 0232 /// This method represents the cylinder as a polyhedron with a given number 0233 /// of segments to represent a quarter of a full circle. The polyedron will 0234 /// consist of the vertices of the cylinder on both sides, and faces between 0235 /// them, both as rectangular faces and as triangular faces. 0236 /// 0237 /// @param gctx The current geometry context object, e.g. alignment 0238 /// @param quarterSegments The number of segments to approximate a quarter of the 0239 /// full circle; it's chosen to be 1, only the extrema points (-pi, -0.5pi, 0240 /// 0., 0.5pi) are inserted to capture the correct extent in the x-y plane 0241 /// 0242 /// @return A list of vertices and a face/facett description of it 0243 Polyhedron polyhedronRepresentation( 0244 const GeometryContext& gctx, 0245 unsigned int quarterSegments = 2u) const override; 0246 0247 /// Calculate the derivative of path length at the geometry constraint or 0248 /// point-of-closest-approach w.r.t. alignment parameters of the surface (i.e. 0249 /// local frame origin in global 3D Cartesian coordinates and its rotation 0250 /// represented with extrinsic Euler angles) 0251 /// 0252 /// @param gctx The current geometry context object, e.g. alignment 0253 /// @param position global 3D position 0254 /// @param direction global 3D momentum direction 0255 /// 0256 /// @return Derivative of path length w.r.t. the alignment parameters 0257 AlignmentToPathMatrix alignmentToPathDerivative( 0258 const GeometryContext& gctx, const Vector3& position, 0259 const Vector3& direction) const final; 0260 0261 /// Calculate the derivative of bound track parameters local position w.r.t. 0262 /// position in local 3D Cartesian coordinates 0263 /// 0264 /// @param gctx The current geometry context object, e.g. alignment 0265 /// @param position The position of the parameters in global 0266 /// 0267 /// @return Derivative of bound local position w.r.t. position in local 3D 0268 /// cartesian coordinates 0269 Matrix<2, 3> localCartesianToBoundLocalDerivative( 0270 const GeometryContext& gctx, const Vector3& position) const final; 0271 0272 /// Merge two cylinder surfaces into a single one. 0273 /// @image html Cylinder_Merging.svg 0274 /// @note The surfaces need to be *compatible*, i.e. have cylinder bounds 0275 /// that align, and have the same radius 0276 /// @param other The other cylinder surface to merge with 0277 /// @param direction The axis direction: either @c AxisZ or @c AxisRPhi 0278 /// @param externalRotation If true, any phi rotation is done in the transform 0279 /// @param logger The logger to use 0280 /// @return The merged cylinder surface and a boolean indicating if surfaces are reversed 0281 /// @note The returned boolean is `false` if `this` is *left* or 0282 /// *counter-clockwise* of @p other, and `true` if not. 0283 std::pair<std::shared_ptr<CylinderSurface>, bool> mergedWith( 0284 const CylinderSurface& other, AxisDirection direction, 0285 bool externalRotation, const Logger& logger = getDummyLogger()) const; 0286 0287 /// @copydoc Surface::assignSurfaceMaterial 0288 void assignSurfaceMaterial( 0289 std::shared_ptr<const ISurfaceMaterial> material) override; 0290 0291 protected: 0292 std::shared_ptr<const CylinderBounds> m_bounds; //!< bounds (shared) 0293 0294 /// @copydoc Surface::localAxes 0295 std::array<AxisDirection, 2> localAxes() const override { 0296 return {AxisDirection::AxisRPhi, AxisDirection::AxisZ}; 0297 } 0298 0299 /// @copydoc Surface::transformSurfaceLocalToMaterialLocal 0300 Vector2 transformSurfaceLocalToMaterialLocal( 0301 const Vector2& surfaceLocal) const override; 0302 0303 private: 0304 bool m_scaleMaterialAxis = false; 0305 0306 /// Implementation of the intersection solver 0307 /// 0308 /// <b>mathematical motivation:</b> 0309 /// 0310 /// The cylinder is given by : 0311 /// - cylinder center: ccenter (C) 0312 /// - the direction of the cylinder axis: cdirection (DZ) 0313 /// - the radius r 0314 /// The line is given by : 0315 /// - a reference position : lposition (L0) 0316 /// - the line direction: ldirection (DL) 0317 /// the parametric form for the line is then : L(t) = L0 + t * DL 0318 /// 0319 /// Any point P on infinite cylinder if : 0320 /// ((P - C) x DZ)^2 = r^2 * DZ^2 0321 /// We know that DZ is a unit vector: 0322 /// DZ^2 == 1 0323 /// When expanded with the line equation, this is : 0324 /// ((L0 - C) x DZ + t * (DL x DZ))^2 = r^2 * DZ^2 0325 /// which is a quadratic equation in the form (X + t * Y)^2 = d, where : 0326 /// X = (L0 - C) x DZ 0327 /// Y = DL x DZ 0328 /// d = r^2 * (DZ)^2 0329 /// Now, expand the equation : 0330 /// t^2 * (Y . Y) + t * (2 * (X . Y)) + (X . X) - d = 0 0331 /// => second order equation in the form : a*t^2 + b*t + c = 0 where 0332 /// a = (Y . Y) 0333 /// b = 2 * (X . Y) 0334 /// c = (X . X) - d 0335 /// finally solve the second order equation : a*t^2 + b*t + c = 0 0336 /// reinsertion into the line equation. 0337 /// 0338 /// @return the quadratic equation 0339 detail::RealQuadraticEquation intersectionSolver( 0340 const Transform3& transform, const Vector3& position, 0341 const Vector3& direction) const; 0342 }; 0343 0344 static_assert(RegularSurfaceConcept<CylinderSurface>, 0345 "CylinderSurface does not fulfill RegularSurfaceConcept"); 0346 0347 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|