|
|
|||
File indexing completed on 2025-12-02 09:19: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 0013 #include <cmath> 0014 #include <limits> 0015 #include <utility> 0016 0017 namespace Acts { 0018 0019 /// Construct a normalized direction vector from phi angle and pseudorapidity. 0020 /// 0021 /// @param phi is the direction angle in the x-y plane. 0022 /// @param eta is the pseudorapidity towards the z-axis. 0023 /// @return A normalized 3D direction vector constructed from phi and eta 0024 /// 0025 /// @note The input arguments intentionally use the same template type so that 0026 /// a compile error occurs if inconsistent input types are used. Avoids 0027 /// unexpected implicit type conversions and forces the user to 0028 /// explicitly cast mismatched input types. 0029 template <typename T> 0030 inline Eigen::Matrix<T, 3, 1> makeDirectionFromPhiEta(T phi, T eta) { 0031 const auto coshEtaInv = 1 / std::cosh(eta); 0032 return { 0033 std::cos(phi) * coshEtaInv, 0034 std::sin(phi) * coshEtaInv, 0035 std::tanh(eta), 0036 }; 0037 } 0038 0039 /// Construct a normalized direction vector from phi and theta angle. 0040 /// 0041 /// @param phi is the direction angle in radian in the x-y plane. 0042 /// @param theta is the polar angle in radian towards the z-axis. 0043 /// @return A normalized 3D direction vector constructed from phi and theta 0044 /// 0045 /// @note The input arguments intentionally use the same template type so that 0046 /// a compile error occurs if inconsistent input types are used. Avoids 0047 /// unexpected implicit type conversions and forces the user to 0048 /// explicitly cast mismatched input types. 0049 template <typename T> 0050 inline Eigen::Matrix<T, 3, 1> makeDirectionFromPhiTheta(T phi, T theta) { 0051 const T sinTheta{std::sin(theta)}; 0052 return { 0053 std::cos(phi) * sinTheta, 0054 std::sin(phi) * sinTheta, 0055 std::cos(theta), 0056 }; 0057 } 0058 /// @brief Construct a normalized direction vector from the tangents of the 0059 /// x-axis to the z-axis and of the y-axis to the z-axis 0060 /// 0061 /// @param tanAlpha Tangent of the x-axis to the z-axis 0062 /// @param tanBeta Tangent of the y-axis to the z-axis 0063 /// @return A normalized 3D direction vector constructed from the axis tangents 0064 template <typename T> 0065 inline Eigen::Matrix<T, 3, 1> makeDirectionFromAxisTangents(T tanAlpha, 0066 T tanBeta) { 0067 return Eigen::Matrix<T, 3, 1>{tanAlpha, tanBeta, 1}.normalized(); 0068 } 0069 0070 /// Construct a phi and theta angle from a direction vector. 0071 /// 0072 /// @param unitDir 3D vector indicating a direction 0073 /// @return A 2D vector containing phi and theta angles [phi, theta] 0074 /// 0075 template <typename T> 0076 inline Eigen::Matrix<T, 2, 1> makePhiThetaFromDirection( 0077 const Eigen::Matrix<T, 3, 1>& unitDir) { 0078 T phi = std::atan2(unitDir[1], unitDir[0]); 0079 T theta = std::acos(unitDir[2]); 0080 return { 0081 phi, 0082 theta, 0083 }; 0084 } 0085 0086 /// Construct the first curvilinear unit vector `U` for the given direction. 0087 /// 0088 /// @param direction is the input direction vector 0089 /// @returns a normalized vector in the x-y plane orthogonal to the direction. 0090 /// 0091 /// The special case of the direction vector pointing along the z-axis is 0092 /// handled by forcing the unit vector to along the x-axis. 0093 template <typename InputVector> 0094 inline auto createCurvilinearUnitU( 0095 const Eigen::MatrixBase<InputVector>& direction) { 0096 EIGEN_STATIC_ASSERT_FIXED_SIZE(InputVector); 0097 EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector); 0098 static_assert(3 <= InputVector::RowsAtCompileTime, 0099 "Direction vector must be at least three-dimensional."); 0100 0101 using OutputVector = typename InputVector::PlainObject; 0102 using OutputScalar = typename InputVector::Scalar; 0103 0104 OutputVector unitU = OutputVector::Zero(); 0105 // explicit version of U = Z x T 0106 unitU[0] = -direction[1]; 0107 unitU[1] = direction[0]; 0108 const auto scale = unitU.template head<2>().norm(); 0109 // if the absolute scale is tiny, the initial direction vector is aligned with 0110 // the z-axis. the ZxT product is ill-defined since any vector in the x-y 0111 // plane would be orthogonal to the direction. fix the U unit vector along the 0112 // x-axis to avoid this numerical instability. 0113 if (scale < (16 * std::numeric_limits<OutputScalar>::epsilon())) { 0114 unitU[0] = 1; 0115 unitU[1] = 0; 0116 } else { 0117 unitU.template head<2>() /= scale; 0118 } 0119 return unitU; 0120 } 0121 0122 /// Construct the curvilinear unit vectors `U` and `V` for the given direction. 0123 /// 0124 /// @param direction is the input direction vector 0125 /// @returns normalized unit vectors `U` and `V` orthogonal to the direction. 0126 /// 0127 /// With `T` the normalized input direction, the three vectors `U`, `V`, and 0128 /// `T` form an orthonormal basis set, i.e. they satisfy 0129 /// 0130 /// U x V = T 0131 /// V x T = U 0132 /// T x U = V 0133 /// 0134 /// with the additional condition that `U` is located in the global x-y plane. 0135 template <typename InputVector> 0136 inline auto createCurvilinearUnitVectors( 0137 const Eigen::MatrixBase<InputVector>& direction) { 0138 EIGEN_STATIC_ASSERT_FIXED_SIZE(InputVector); 0139 EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector); 0140 static_assert(3 <= InputVector::RowsAtCompileTime, 0141 "Direction vector must be at least three-dimensional."); 0142 0143 using OutputVector = typename InputVector::PlainObject; 0144 0145 std::pair<OutputVector, OutputVector> unitVectors; 0146 unitVectors.first = createCurvilinearUnitU(direction); 0147 unitVectors.second = direction.cross(unitVectors.first); 0148 unitVectors.second.normalize(); 0149 return unitVectors; 0150 } 0151 0152 } // 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 |
|