Warning, file /include/Acts/Utilities/UnitVectors.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
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
0020
0021
0022
0023
0024
0025
0026
0027
0028
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
0040
0041
0042
0043
0044
0045
0046
0047
0048
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
0059
0060
0061
0062
0063
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
0071
0072
0073
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
0087
0088
0089
0090
0091
0092
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
0106 unitU[0] = -direction[1];
0107 unitU[1] = direction[0];
0108 const auto scale = unitU.template head<2>().norm();
0109
0110
0111
0112
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
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
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 }