113 explicit Spline(
const std::vector<iPoint2D>& control_points) {
114 assert(control_points.size() >= 2 &&
115 "Need at least two points to interpolate between");
118 assert(control_points.front().x == 0);
119 assert(control_points.back().x == 65535);
121 assert(std::adjacent_find(
122 control_points.cbegin(), control_points.cend(),
124 return std::greater_equal<>()(lhs.x, rhs.x);
125 }) == control_points.cend() &&
126 "The X coordinates must all be strictly increasing");
129 if constexpr (!std::is_floating_point_v<value_type>) {
131 std::for_each(control_points.cbegin(), control_points.cend(),
133 assert(p.y >= std::numeric_limits<value_type>::min());
134 assert(p.y <= std::numeric_limits<value_type>::max());
145 xCp[i] = control_points[i].x;
146 segments[i].a = control_points[i].y;
155 std::vector<value_type> curve(65536);
160 for (
int x =
xCp[i];
x <=
xCp[i + 1];
x++) {
161 double diff =
x -
xCp[i];
162 double diff_2 = diff * diff;
163 double diff_3 = diff * diff * diff;
165 double interpolated =
166 s.a + (
s.b * diff) + (
s.c * diff_2) + (
s.d * diff_3);
168 if constexpr (!std::is_floating_point_v<value_type>) {
169 interpolated = std::max(
170 interpolated,
double(std::numeric_limits<value_type>::min()));
171 interpolated = std::min(
172 interpolated,
double(std::numeric_limits<value_type>::max()));