File indexing completed on 2025-07-15 08:12:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012
0013 #include <algorithm>
0014
0015 #include <unsupported/Eigen/Splines>
0016
0017 namespace Acts::Interpolation3D {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 template <typename trajectory_type>
0035 trajectory_type spline(const trajectory_type& inputsRaw, std::size_t nPoints,
0036 bool keepOriginalHits = false) {
0037 trajectory_type output;
0038 if (inputsRaw.empty()) {
0039 return output;
0040 }
0041
0042 using InputVectorType = typename trajectory_type::value_type;
0043
0044 std::vector<Vector3> inputs;
0045
0046 if constexpr (std::is_same_v<trajectory_type, std::vector<Vector3>>) {
0047 inputs = inputsRaw;
0048 } else {
0049 inputs.reserve(inputsRaw.size());
0050 for (const auto& input : inputsRaw) {
0051 inputs.push_back(Vector3(input[0], input[1], input[2]));
0052 }
0053 }
0054
0055
0056
0057 if (inputsRaw.size() < 3 || nPoints <= inputsRaw.size()) {
0058 return inputsRaw;
0059 } else {
0060 Eigen::MatrixXd points(3, inputs.size());
0061 for (std::size_t i = 0; i < inputs.size(); ++i) {
0062 points.col(i) = inputs[i].transpose();
0063 }
0064
0065
0066
0067 Eigen::Spline<double, 3> spline3D =
0068 Eigen::SplineFitting<Eigen::Spline<double, 3>>::Interpolate(points, 2);
0069
0070
0071
0072 double step = 1. / (nPoints - 1);
0073 for (std::size_t i = 0; i < nPoints; ++i) {
0074 double t = i * step;
0075 InputVectorType point;
0076 point[0] = spline3D(t)[0];
0077 point[1] = spline3D(t)[1];
0078 point[2] = spline3D(t)[2];
0079 output.push_back(point);
0080 }
0081 }
0082
0083
0084 if (keepOriginalHits) {
0085 output.insert(output.begin(), inputsRaw.begin() + 1, inputsRaw.end() - 1);
0086
0087 std::ranges::sort(output, [&inputs](const auto& a, const auto& b) {
0088 const auto ifront = inputs.front();
0089 double da2 = (a[0] - ifront[0]) * (a[0] - ifront[0]) +
0090 (a[1] - ifront[1]) * (a[1] - ifront[1]) +
0091 (a[2] - ifront[2]) * (a[2] - ifront[2]);
0092 double db2 = (b[0] - ifront[0]) * (b[0] - ifront[0]) +
0093 (b[1] - ifront[1]) * (b[1] - ifront[1]) +
0094 (b[2] - ifront[2]) * (b[2] - ifront[2]);
0095 return da2 < db2;
0096 });
0097 }
0098
0099 return output;
0100 }
0101
0102 }