cgv
Loading...
Searching...
No Matches
piecewise_nearest_interpolator.h
1#pragma once
2
3#include "interpolator.h"
4
5namespace cgv {
6namespace math {
7
8template<typename T>
10public:
11 T interpolate(control_point_container<T> control_points, float t) const {
12 size_t count = control_points.size();
13
14 if(count == 0)
15 return (T)0;
16
17 if(count == 1)
18 return control_points[0].second;
19
20 t = cgv::math::clamp(t, control_points.min().first, control_points.max().first);
21
22 if(t > control_points[0].first) {
23 size_t idx = 0;
24
25 for(size_t i = 1; i < count; ++i) {
26 if(control_points[idx].first <= t && control_points[i].first > t)
27 break;
28 idx = i;
29 }
30
31 if(idx < count - 1) {
32 std::pair<float, T> n0 = control_points[idx];
33 std::pair<float, T> n1 = control_points[idx + 1];
34
35 float t0 = n0.first;
36 float t1 = n1.first;
37
38 return (t - t0) < (t1 - t) ? n0.second : n1.second;
39 } else {
40 return control_points[idx].second;
41 }
42 } else {
43 return control_points[0].second;
44 }
45 }
46
47 std::vector<T> interpolate(control_point_container<T> control_points, size_t n) const {
48 size_t count = control_points.size();
49
50 std::vector<T> data(n, (T)0);
51
52 if(n == 0 || count == 0)
53 return data;
54
55 if(count == 1) {
56 std::fill(data.begin(), data.end(), control_points[0].second);
57 return data;
58 }
59
60 size_t l = 0;
61 size_t r = 1;
62
63 if(control_points.min().first > 0.0f)
64 r = 0;
65
66 float step = 1.0f / static_cast<float>(n - 1);
67
68 for(size_t i = 0; i < n; ++i) {
69 float t = static_cast<float>(i) * step;
70
71 while(t > control_points[r].first && l < count - 1) {
72 l = r;
73 r = std::min(l + 1, count - 1);
74 }
75
76 if(l == r) {
77 data[i] = (T)(control_points[r].second);
78 } else {
79 std::pair<float, T> n0 = control_points[l];
80 std::pair<float, T> n1 = control_points[r];
81
82 float t0 = n0.first;
83 float t1 = n1.first;
84
85 data[i] = (t - t0) < (t1 - t) ? n0.second : n1.second;
86 }
87 }
88
89 return data;
90 }
91};
92
93}
94}
the cgv namespace
Definition print.h:11