31template <
typename T>
struct point
50 T
min{ -std::numeric_limits<T>::infinity() };
51 T
max{ +std::numeric_limits<T>::infinity() };
72 template <
typename iter>
spline_base(iter i_begin, iter i_end)
74 for(iter
i{ i_begin };
i != i_end; ++
i)
points.push_back({ i->x, i->y, 0 });
75 if(
points.empty())
throw std::invalid_argument(
"empty set of interpolation points");
81 template <
typename iter>
88 for(iter
i{ i_begin };
i != i_end; ++
i)
90 T
x{ std::fmod(
i->x, period) };
91 if(
x < 0)
x += period;
97 for(iter
i{ i_begin };
i != i_end; ++
i)
102 if(
points.empty())
throw std::invalid_argument(
"empty set of interpolation points");
112 bool periodic_ =
false)
113 :
spline_base(I.begin(), I.end(), x_lim_, y_lim_, periodic_)
128 x = std::fmod(
x, period);
129 if(
x <
points.front().x)
x += period;
133 n0 = n0 > 0 ? n0 - 1 :
points.size() - 1;
134 n1 = n0 + 1 <
points.size() ? n0 + 1 : 0;
149 if(n0 > 0) n0 = std::min(n0 - 1,
points.size() - 2);
159 y =
P.y + (
x -
P.x) *
P.dy;
163 const T dx{ (
x -
points[n0].x) / h };
164 const T dx2{ dx * dx };
165 const T dx3{ dx2 * dx };
168 const T h00{ 2 * dx3 - 3 * dx2 + 1 };
169 const T h10{ dx3 - 2 * dx2 + dx };
170 const T h01{ -2 * dx3 + 3 * dx2 };
171 const T h11{ dx3 - dx2 };
175 y = std::max(y,
y_lim.min);
176 y = std::min(y,
y_lim.max);
220 template <
typename iter>
226 template <
typename iter>
228 bool periodic_ =
false)
240 bool periodic_ =
false)
270 std::vector<T> Delta;
275 if(Delta[
N - 1] * Delta[0] <= 0)
278 points[0].dy = (Delta[
N - 1] + Delta[0]) / 2;
280 if(Delta[
i - 1] * Delta[
i] <= 0)
283 points[
i].dy = (Delta[
i - 1] + Delta[
i]) / 2;
287 if(std::abs(Delta[
i]) < std::numeric_limits<T>::epsilon())
291 const T alpha{
points[
i].dy / Delta[
i] };
292 const T beta{
points[i_1].dy / Delta[
i] };
293 const T tau{ alpha * alpha + beta * beta };
296 points[
i].dy = 3 * alpha * Delta[
i] / std::sqrt(tau);
297 points[i_1].dy = 3 * beta * Delta[
i] / std::sqrt(tau);
304 std::vector<T> Delta;
305 Delta.reserve(
N - 1);
310 if(Delta[
i - 1] * Delta[
i] <= 0)
313 points[
i].dy = (Delta[
i - 1] + Delta[
i]) / 2;
314 if(
N >= 2)
points[
N - 1].dy = Delta[
N - 2];
316 if(std::abs(Delta[
i]) < std::numeric_limits<T>::epsilon())
320 const T alpha{
points[
i].dy / Delta[
i] };
321 const T beta{
points[
i + 1].dy / Delta[
i] };
322 const T tau{ alpha * alpha + beta * beta };
325 points[
i].dy = 3 * alpha * Delta[
i] / std::sqrt(tau);
326 points[
i + 1].dy = 3 * beta * Delta[
i] / std::sqrt(tau);
334 template <
typename iter>
340 template <
typename iter>
342 bool periodic_ =
false)
354 const limits<T> &y_lim_,
bool periodic_ =
false)
377 static T
G(
const T S1,
const T S2,
const T h1,
const T h2)
381 const T alpha{ (h1 + 2 * h2) / (3 * (h1 + h2)) };
382 return S1 * S2 / (alpha * S2 + (1 - alpha) * S1);
396 std::vector<T> h, Delta;
406 points[0].dy =
G(Delta[
N - 1], Delta[0], h[
N - 1], h[0]);
411 std::vector<T> h, Delta;
413 Delta.reserve(
N - 1);
421 if(
N >= 2)
points[
N - 1].dy = Delta[
N - 2];
427 template <
typename iter>
433 template <
typename iter>
435 bool periodic_ =
false)
447 const limits<T> &y_lim_,
bool periodic_ =
false)
479 :
N{ N_ },
is_banded{ is_banded_ },
A(is_banded_ ? 3 * N_ : N_ * N_, 0)
487 if(
i == j)
return A[
i +
N];
488 if(
i + 1 == j)
return A[
i];
489 if(
i == j + 1)
return A[
i + 2 *
N];
498 if(
i == j)
return A[
i +
N];
499 if(
i + 1 == j)
return A[
i];
500 if(
i == j + 1)
return A[
i + 2 *
N];
520 if(
A.size() < 1)
return false;
526 const T t1{
A(
i,
i) };
532 A(
i + 1,
i + 1) -=
A(
i + 1,
i) *
A(
i,
i + 1);
544 const T t1{
A(
i,
i) };
565 if(
n < 1 or
A.size() != b.size())
return;
571 if(
i > 0) b[
i] -=
A(
i,
i - 1) * b[
i - 1];
576 if(
i + 1 <
n) b[
i] -=
A(
i,
i + 1) * b[
i + 1];
613 std::vector<T> Delta_x, Delta_y;
633 A(
i,
i - 1) = Delta_x[
i - 1] / 6;
634 A(
i,
i) = (Delta_x[
i - 1] + Delta_x[
i]) / 3;
635 A(
i,
i + 1) = Delta_x[
i] / 6;
636 b[
i] = Delta_y[
i] / Delta_x[
i] - Delta_y[
i - 1] / Delta_x[
i - 1];
640 A(0, 0) = (Delta_x[
N - 1] + Delta_x[0]) / 3;
641 A(
N - 1,
N - 1) = (Delta_x[
N - 2] + Delta_x[
N - 1]) / 3;
642 b[0] = Delta_y[0] / Delta_x[0] - Delta_y[
N - 1] / Delta_x[
N - 1];
643 b[
N - 1] = Delta_y[
N - 1] / Delta_x[
N - 1] - Delta_y[
N - 2] / Delta_x[
N - 2];
646 A(0, 1) = Delta_x[0] / 6;
647 A(
N - 1,
N - 2) = Delta_x[
N - 2] / 6;
648 A(0,
N - 1) =
A(
N - 1, 0) = Delta_x[
N - 1] / 6;
652 A(0, 1) =
A(1, 0) = (Delta_x[0] + Delta_x[1]) / 6;
667 c_i = Delta_y[
i] / Delta_x[
i] - Delta_x[
i] / 6 * (b[
i + 1] - b[
i]);
668 points[
i].dy = -Delta_x[
i] * b[
i] / 2 + c_i;
671 points[
N - 1].dy = Delta_x[
N - 2] * b[
N - 1] / 2 + c_i;
678 template <
typename iter>
684 template <
typename iter>
686 bool periodic_ =
false)
698 bool periodic_ =
false)
758 std::vector<interpol::point<float> >
v;
769 v.push_back({ curve->m_anchors[i].x * box_width + curve->m_min_x,
770 curve->m_anchors[i].y * box_height + curve->m_min_y });
774 const int firstPointX =
v.front().x * (sample->
m_samplingRes - 1);
775 const int firstPointY =
v.front().y * (sample->
m_outputRes - 1);
777 const int lastPointY =
v.back().y * (sample->
m_outputRes - 1);
784 { curve->m_min_y, curve->m_max_y },
false);
785 for(
int i = 0;
i <
n; ++
i)
789 else if(
i > lastPointX)
793 int val =
static_cast<int>(std::round(s(
i *
res) * (sample->
m_outputRes - 1)));
794 if(val > maxY) val = maxY;
795 if(val < minY) val = minY;
803 { curve->m_min_y, curve->m_max_y },
false);
804 for(
int i = 0;
i <
n; ++
i)
808 else if(
i > lastPointX)
812 int val =
static_cast<int>(std::round(s(
i *
res) * (sample->
m_outputRes - 1)));
813 if(val > maxY) val = maxY;
814 if(val < minY) val = minY;
822 { curve->m_min_y, curve->m_max_y },
false);
823 for(
int i = 0;
i <
n; ++
i)
827 else if(
i > lastPointX)
832 if(val > maxY) val = maxY;
833 if(val < minY) val = minY;
854 std::vector<interpol::point<float> >
v;
865 v.push_back({ curve->m_anchors[i].x * box_width + curve->m_min_x,
866 curve->m_anchors[i].y * box_height + curve->m_min_y });
873 { curve->m_min_y, curve->m_max_y },
true);
880 { curve->m_min_y, curve->m_max_y },
true);
887 { curve->m_min_y, curve->m_max_y },
true);
Catmull_Rom_spline(const std::initializer_list< point< T > > &I, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
Catmull_Rom_spline(iter i_begin, iter i_end)
std::vector< base_point< T > > points
typename std::vector< base_point< T > >::size_type size_type
Catmull_Rom_spline(iter i_begin, iter i_end, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
Catmull_Rom_spline(const std::initializer_list< point< T > > &I)
static T G(const T S1, const T S2, const T h1, const T h2)
std::vector< base_point< T > > points
typename std::vector< base_point< T > >::size_type size_type
monotone_hermite_spline_variant(const std::initializer_list< point< T > > &I, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
monotone_hermite_spline_variant(iter i_begin, iter i_end, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
monotone_hermite_spline_variant(const std::initializer_list< point< T > > &I)
monotone_hermite_spline_variant(iter i_begin, iter i_end)
monotone_hermite_spline(const std::initializer_list< point< T > > &I, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
std::vector< base_point< T > > points
typename std::vector< base_point< T > >::size_type size_type
monotone_hermite_spline(const std::initializer_list< point< T > > &I)
monotone_hermite_spline(iter i_begin, iter i_end)
monotone_hermite_spline(iter i_begin, iter i_end, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
T & operator()(size_type i, size_type j)
typename std::vector< T >::size_type size_type
const T & operator()(size_type i, size_type j) const
matrix(size_type N_, bool is_banded_=false)
static bool LU_factor(matrix &A)
smooth_cubic_spline(const std::initializer_list< point< T > > &I, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
std::vector< base_point< T > > points
typename std::vector< base_point< T > >::size_type size_type
smooth_cubic_spline(const std::initializer_list< point< T > > &I)
smooth_cubic_spline(iter i_begin, iter i_end)
static void LU_solve(const matrix &A, vector &b)
static bool gauss_solve(matrix &A, vector &b)
smooth_cubic_spline(iter i_begin, iter i_end, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
std::vector< base_point< T > > points
typename std::vector< base_point< T > >::size_type size_type
spline_base(iter i_begin, iter i_end)
spline_base(const std::initializer_list< point< T > > &I, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
spline_base(const std::initializer_list< point< T > > &I)
spline_base(iter i_begin, iter i_end, const limits< T > &x_lim_, const limits< T > &y_lim_, bool periodic_=false)
_lib_location_type_t type
float *const restrict const size_t k
constexpr limits< T > infinity()
float interpolate_val_V2_periodic(int n, CurveAnchorPoint Points[], float x, unsigned int type, float period)
int CurveDataSampleV2Periodic(CurveData *curve, CurveSample *sample)
int CurveDataSampleV2(CurveData *curve, CurveSample *sample)
float interpolate_val_V2(int n, CurveAnchorPoint Points[], float x, unsigned int type)
unsigned char m_numAnchors
unsigned int m_spline_type
unsigned int m_samplingRes
unsigned short int * m_Samples