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