File indexing completed on 2025-01-18 09:27:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <array>
0012
0013 namespace Acts::detail {
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 template <typename Point1, typename Point2, typename Point3, typename Value>
0035 struct can_interpolate {
0036 template <typename C>
0037 static auto value_type_test(C* c)
0038 -> decltype(static_cast<C>(std::declval<double>() * std::declval<C>() +
0039 std::declval<double>() * std::declval<C>()),
0040 std::true_type());
0041 template <typename C>
0042 static std::false_type value_type_test(...);
0043
0044 template <typename C>
0045 static auto point_type_test(C* c)
0046 -> decltype(static_cast<double>(std::declval<C>()[0]), std::true_type());
0047 template <typename C>
0048 static std::false_type point_type_test(...);
0049
0050 static const bool value =
0051 std::is_same<std::true_type,
0052 decltype(value_type_test<Value>(nullptr))>::value &&
0053 std::is_same<std::true_type,
0054 decltype(point_type_test<Point1>(nullptr))>::value &&
0055 std::is_same<std::true_type,
0056 decltype(point_type_test<Point2>(nullptr))>::value &&
0057 std::is_same<std::true_type,
0058 decltype(point_type_test<Point3>(nullptr))>::value;
0059 };
0060
0061
0062
0063
0064 template <std::size_t N>
0065 struct get_dimension {
0066
0067 static constexpr std::size_t value = get_dimension<(N >> 1)>::value + 1u;
0068 };
0069
0070
0071 template <>
0072 struct get_dimension<2u> {
0073 static constexpr std::size_t value = 1u;
0074 };
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 template <typename T, class Point1, class Point2, class Point3, std::size_t D,
0096 std::size_t N>
0097 struct interpolate_impl;
0098
0099
0100
0101 template <typename T, class Point1, class Point2, class Point3, std::size_t D,
0102 std::size_t N>
0103 struct interpolate_impl {
0104 static T run(const Point1& pos, const Point2& lowerLeft,
0105 const Point3& upperRight, const std::array<T, N>& fields) {
0106
0107 const double f = (pos[D] - lowerLeft[D]) / (upperRight[D] - lowerLeft[D]);
0108
0109 std::array<T, (N >> 1)> newFields{};
0110 for (std::size_t i = 0; i < N / 2; ++i) {
0111 newFields.at(i) = (1 - f) * fields.at(2 * i) + f * fields.at(2 * i + 1);
0112 }
0113
0114 return interpolate_impl<T, Point1, Point2, Point3, D - 1, (N >> 1)>::run(
0115 pos, lowerLeft, upperRight, newFields);
0116 }
0117 };
0118
0119
0120 template <typename T, class Point1, class Point2, class Point3, std::size_t D>
0121 struct interpolate_impl<T, Point1, Point2, Point3, D, 2u> {
0122 static T run(const Point1& pos, const Point2& lowerLeft,
0123 const Point3& upperRight, const std::array<T, 2u>& fields) {
0124
0125 const double f = (pos[D] - lowerLeft[D]) / (upperRight[D] - lowerLeft[D]);
0126
0127 return (1 - f) * fields.at(0) + f * fields.at(1);
0128 }
0129 };
0130
0131 }