Tatooine
vertex_property_sampler.h
Go to the documentation of this file.
1#ifndef TATOOINE_DETAIL_LINE_VERTEX_PROPERTY_SAMPLER_H
2#define TATOOINE_DETAIL_LINE_VERTEX_PROPERTY_SAMPLER_H
3//==============================================================================
4#include <tatooine/line.h>
5#include <tatooine/nan.h>
6//==============================================================================
8//==============================================================================
9template <floating_point Real, std::size_t NumDimensions, typename Property,
10 template <typename> typename InterpolationKernel>
14 using property_type = Property;
17
18 private:
22
23 public:
25 : m_line{line},
26 m_property{property},
27 m_parameterization{m_line.parameterization()} {}
28
29 auto operator()(Real t) const {
30 auto range = std::pair{m_line.vertices().front(), m_line.vertices().back()};
31 while (range.second.index() - range.first.index() > 1) {
32 auto const center =
33 handle_type{(range.first.index() + range.second.index()) / 2};
34 if (t < m_parameterization[center]) {
35 range.second = center;
36 } else {
37 range.first = center;
38 }
39 }
40 auto const lt = m_parameterization[range.first];
41 auto const rt = m_parameterization[range.second];
42 t = (t - lt) / (rt - lt);
43
44 auto const interpolant = InterpolationKernel{m_property[range.first], m_property[range.second]};
45 return interpolant(t);
46 }
47};
48//==============================================================================
49template <floating_point Real, std::size_t NumDimensions, typename Property>
50struct vertex_property_sampler<Real, NumDimensions, Property,
51 interpolation::cubic> {
52 using real_type = Real;
58 using property_type = Property;
59 using value_type = typename property_type::value_type;
60
61 private:
65 std::vector<interpolation::cubic<value_type>> m_interpolants;
66
67 public:
69 : m_line{line},
70 m_property{property},
71 m_parameterization{m_line.parameterization()} {
72 if (m_line.vertices().size() < 2) {
73 return;
74 }
75 auto const stencil_size =
76 min(std::size_t(3), m_line.vertices().size());
77 auto const half = stencil_size / 2;
78 auto derivatives = std::vector<value_type>{};
79
80 auto const derivative = [&](handle_type const v) -> value_type {
81 auto lv = half > v.index() ? handle_type{0} : v - half;
82 auto const rv = lv.index() + stencil_size - 1 >= m_line.vertices().size()
83 ? handle_type{m_line.vertices().size() - 1}
84 : lv + stencil_size - 1;
85 auto const rpotential = stencil_size - (rv.index() - lv.index() + 1);
86 lv = rpotential > lv.index() ? handle_type{0} : lv - rpotential;
87
88 auto ts = std::vector<Real>(stencil_size);
89 auto i = std::size_t{};
90 for (auto vi = lv; vi <= rv; ++vi, ++i) {
92 }
93 auto coeffs = finite_differences_coefficients(1, ts);
94 auto derivative = value_type{};
95 i = 0;
96 for (auto vi = lv; vi <= rv; ++vi, ++i) {
97 derivative += m_property[vi] *
98 static_cast<tatooine::value_type<value_type>>(coeffs[i]);
99 }
100 return derivative;
101 };
102 auto dfdt0 = derivative(handle_type{0});
103 for (std::size_t i = 0; i < m_line.vertices().size() - 1; ++i) {
104 auto const dfdt1 = derivative(handle_type{i + 1});
105 auto const dy = m_parameterization[handle_type{i + 1}] -
107 m_interpolants.emplace_back(
109 value_type(dfdt0 * dy), value_type(dfdt1 * dy));
110 dfdt0 = dfdt1;
111 }
112 }
113 //----------------------------------------------------------------------------
114 auto operator()(Real t) const -> value_type{
115 if (m_line.vertices().size() < 2) {
116 if constexpr (tensor_rank<value_type> == 0) {
117 return nan<value_type>();
118 } else {
119 return value_type::fill(nan<tatooine::value_type<value_type>>());
120 }
121 }
122 auto range = std::pair{m_line.vertices().front(), m_line.vertices().back()};
123 while (range.second.index() - range.first.index() > 1) {
124 auto const center =
125 handle_type{(range.first.index() + range.second.index()) / 2};
126 if (t < m_parameterization[center]) {
127 range.second = center;
128 } else {
129 range.first = center;
130 }
131 }
132 auto const lt = m_parameterization[range.first];
133 auto const rt = m_parameterization[range.second];
134 t = (t - lt) / (rt - lt);
135
136 return m_interpolants[range.first.index()](t);
137 }
138};
139//==============================================================================
140} // namespace tatooine::detail::line
141//==============================================================================
142#endif
Definition: concepts.h:84
auto finite_differences_coefficients(std::size_t const derivative_order, floating_point auto const ... xs)
See What is this? for an explanation.
Definition: finite_differences_coefficients.h:13
Definition: merge.h:8
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto nan(const char *arg="")
Definition: nan.h:26
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
std::vector< interpolation::cubic< value_type > > m_interpolants
Definition: vertex_property_sampler.h:65
vertex_property_sampler(line_type const &line, property_type const &property)
Definition: vertex_property_sampler.h:68
auto operator()(Real t) const -> value_type
Definition: vertex_property_sampler.h:114
typename line_type::parameterization_property_type parameterization_property_type
Definition: vertex_property_sampler.h:57
typename line_type::tangent_property_type tangent_property_type
Definition: vertex_property_sampler.h:55
parameterization_property_type const & m_parameterization
Definition: vertex_property_sampler.h:64
typename property_type::value_type value_type
Definition: vertex_property_sampler.h:59
typename line_type::vertex_handle handle_type
Definition: vertex_property_sampler.h:54
Definition: vertex_property_sampler.h:11
Property property_type
Definition: vertex_property_sampler.h:14
line_type const & m_line
Definition: vertex_property_sampler.h:19
typename line_type::vertex_handle handle_type
Definition: vertex_property_sampler.h:13
auto operator()(Real t) const
Definition: vertex_property_sampler.h:29
typename line_type::parameterization_property_type parameterization_property_type
Definition: vertex_property_sampler.h:16
vertex_property_sampler(line_type const &line, property_type const &property)
Definition: vertex_property_sampler.h:24
property_type const & m_property
Definition: vertex_property_sampler.h:20
parameterization_property_type const & m_parameterization
Definition: vertex_property_sampler.h:21
Definition: line.h:46
Definition: line.h:35
auto vertices() const
Definition: line.h:250
typed_vertex_property_type< Real > parameterization_property_type
Definition: line.h:61
typed_vertex_property_type< vec< Real, NumDimensions > > tangent_property_type
Definition: line.h:63