32template <
typename T>
struct point
51 T
min{ -std::numeric_limits<T>::infinity() };
52 T
max{ +std::numeric_limits<T>::infinity() };
73 template <
typename iter>
spline_base(iter i_begin, iter i_end)
75 for(iter
i{ i_begin };
i != i_end; ++
i)
points.push_back({ i->x, i->y, 0 });
76 if(
points.empty())
throw std::invalid_argument(
"empty set of interpolation points");
82 template <
typename iter>
89 for(iter
i{ i_begin };
i != i_end; ++
i)
91 T
x{ std::fmod(
i->x, period) };
92 if(
x < 0)
x += period;
98 for(iter
i{ i_begin };
i != i_end; ++
i)
103 if(
points.empty())
throw std::invalid_argument(
"empty set of interpolation points");
113 bool periodic_ =
false)
114 :
spline_base(I.begin(), I.end(), x_lim_, y_lim_, periodic_)
129 x = std::fmod(
x, period);
130 if(
x <
points.front().x)
x += period;
134 n0 = n0 > 0 ? n0 - 1 :
points.size() - 1;
135 n1 = n0 + 1 <
points.size() ? n0 + 1 : 0;
150 if(n0 > 0) n0 = std::min(n0 - 1,
points.size() - 2);
160 y =
P.y + (
x -
P.x) *
P.dy;
164 const T dx{ (
x -
points[n0].x) / h };
165 const T dx2{ dx * dx };
166 const T dx3{ dx2 * dx };
169 const T h00{ 2 * dx3 - 3 * dx2 + 1 };
170 const T h10{ dx3 - 2 * dx2 + dx };
171 const T h01{ -2 * dx3 + 3 * dx2 };
172 const T h11{ dx3 - dx2 };
176 y = std::max(y,
y_lim.min);
177 y = std::min(y,
y_lim.max);
221 template <
typename iter>
227 template <
typename iter>
229 bool periodic_ =
false)
241 bool periodic_ =
false)
271 std::vector<T> Delta;
276 if(Delta[
N - 1] * Delta[0] <= 0)
279 points[0].dy = (Delta[
N - 1] + Delta[0]) / 2;
281 if(Delta[
i - 1] * Delta[
i] <= 0)
284 points[
i].dy = (Delta[
i - 1] + Delta[
i]) / 2;
288 if(std::abs(Delta[
i]) < std::numeric_limits<T>::epsilon())
292 const T alpha{
points[
i].dy / Delta[
i] };
293 const T beta{
points[i_1].dy / Delta[
i] };
294 const T tau{ alpha * alpha + beta * beta };
297 points[
i].dy = 3 * alpha * Delta[
i] / std::sqrt(tau);
298 points[i_1].dy = 3 * beta * Delta[
i] / std::sqrt(tau);
305 std::vector<T> Delta;
306 Delta.reserve(
N - 1);
311 if(Delta[
i - 1] * Delta[
i] <= 0)
314 points[
i].dy = (Delta[
i - 1] + Delta[
i]) / 2;
315 if(
N >= 2)
points[
N - 1].dy = Delta[
N - 2];
317 if(std::abs(Delta[
i]) < std::numeric_limits<T>::epsilon())
321 const T alpha{
points[
i].dy / Delta[
i] };
322 const T beta{
points[
i + 1].dy / Delta[
i] };
323 const T tau{ alpha * alpha + beta * beta };
326 points[
i].dy = 3 * alpha * Delta[
i] / std::sqrt(tau);
327 points[
i + 1].dy = 3 * beta * Delta[
i] / std::sqrt(tau);
335 template <
typename iter>
341 template <
typename iter>
343 bool periodic_ =
false)
355 const limits<T> &y_lim_,
bool periodic_ =
false)
378 static T
G(
const T S1,
const T S2,
const T h1,
const T h2)
382 const T alpha{ (h1 + 2 * h2) / (3 * (h1 + h2)) };
383 return S1 * S2 / (alpha * S2 + (1 - alpha) * S1);
397 std::vector<T> h, Delta;
407 points[0].dy =
G(Delta[
N - 1], Delta[0], h[
N - 1], h[0]);
412 std::vector<T> h, Delta;
414 Delta.reserve(
N - 1);
422 if(
N >= 2)
points[
N - 1].dy = Delta[
N - 2];
428 template <
typename iter>
434 template <
typename iter>
436 bool periodic_ =
false)
448 const limits<T> &y_lim_,
bool periodic_ =
false)
480 :
N{ N_ },
is_banded{ is_banded_ },
A(is_banded_ ? 3 * N_ : N_ * N_, 0)
488 if(
i == j)
return A[
i +
N];
489 if(
i + 1 == j)
return A[
i];
490 if(
i == j + 1)
return A[
i + 2 *
N];
499 if(
i == j)
return A[
i +
N];
500 if(
i + 1 == j)
return A[
i];
501 if(
i == j + 1)
return A[
i + 2 *
N];
521 if(
A.size() < 1)
return false;
527 const T t1{
A(
i,
i) };
533 A(
i + 1,
i + 1) -=
A(
i + 1,
i) *
A(
i,
i + 1);
545 const T t1{
A(
i,
i) };
566 if(
n < 1 or
A.size() != b.size())
return;
572 if(
i > 0) b[
i] -=
A(
i,
i - 1) * b[
i - 1];
577 if(
i + 1 <
n) b[
i] -=
A(
i,
i + 1) * b[
i + 1];
614 std::vector<T> Delta_x, Delta_y;
634 A(
i,
i - 1) = Delta_x[
i - 1] / 6;
635 A(
i,
i) = (Delta_x[
i - 1] + Delta_x[
i]) / 3;
636 A(
i,
i + 1) = Delta_x[
i] / 6;
637 b[
i] = Delta_y[
i] / Delta_x[
i] - Delta_y[
i - 1] / Delta_x[
i - 1];
641 A(0, 0) = (Delta_x[
N - 1] + Delta_x[0]) / 3;
642 A(
N - 1,
N - 1) = (Delta_x[
N - 2] + Delta_x[
N - 1]) / 3;
643 b[0] = Delta_y[0] / Delta_x[0] - Delta_y[
N - 1] / Delta_x[
N - 1];
644 b[
N - 1] = Delta_y[
N - 1] / Delta_x[
N - 1] - Delta_y[
N - 2] / Delta_x[
N - 2];
647 A(0, 1) = Delta_x[0] / 6;
648 A(
N - 1,
N - 2) = Delta_x[
N - 2] / 6;
649 A(0,
N - 1) =
A(
N - 1, 0) = Delta_x[
N - 1] / 6;
653 A(0, 1) =
A(1, 0) = (Delta_x[0] + Delta_x[1]) / 6;
668 c_i = Delta_y[
i] / Delta_x[
i] - Delta_x[
i] / 6 * (b[
i + 1] - b[
i]);
669 points[
i].dy = -Delta_x[
i] * b[
i] / 2 + c_i;
672 points[
N - 1].dy = Delta_x[
N - 2] * b[
N - 1] / 2 + c_i;
679 template <
typename iter>
685 template <
typename iter>
687 bool periodic_ =
false)
699 bool periodic_ =
false)
759 std::vector<interpol::point<float> >
v;
770 v.push_back({ curve->m_anchors[i].x * box_width + curve->m_min_x,
771 curve->m_anchors[i].y * box_height + curve->m_min_y });
775 const int firstPointX =
v.front().x * (sample->
m_samplingRes - 1);
776 const int firstPointY =
v.front().y * (sample->
m_outputRes - 1);
778 const int lastPointY =
v.back().y * (sample->
m_outputRes - 1);
785 { curve->m_min_y, curve->m_max_y },
false);
786 for(
int i = 0;
i <
n; ++
i)
790 else if(
i > lastPointX)
794 int val =
static_cast<int>(std::round(s(
i * res) * (sample->
m_outputRes - 1)));
795 if(val > maxY) val = maxY;
796 if(val < minY) val = minY;
804 { curve->m_min_y, curve->m_max_y },
false);
805 for(
int i = 0;
i <
n; ++
i)
809 else if(
i > lastPointX)
813 int val =
static_cast<int>(std::round(s(
i * res) * (sample->
m_outputRes - 1)));
814 if(val > maxY) val = maxY;
815 if(val < minY) val = minY;
823 { curve->m_min_y, curve->m_max_y },
false);
824 for(
int i = 0;
i <
n; ++
i)
828 else if(
i > lastPointX)
832 int val = std::round(s(
i * res) * (sample->
m_outputRes - 1));
833 if(val > maxY) val = maxY;
834 if(val < minY) val = minY;
855 std::vector<interpol::point<float> >
v;
866 v.push_back({ curve->m_anchors[i].x * box_width + curve->m_min_x,
867 curve->m_anchors[i].y * box_height + curve->m_min_y });
874 { curve->m_min_y, curve->m_max_y },
true);
876 sample->
m_Samples[
i] =
static_cast<unsigned short int>(std::round(s(
i * res) * (sample->
m_outputRes - 1)));
881 { curve->m_min_y, curve->m_max_y },
true);
883 sample->
m_Samples[
i] =
static_cast<unsigned short int>(std::round(s(
i * res) * (sample->
m_outputRes - 1)));
888 { curve->m_min_y, curve->m_max_y },
true);
890 sample->
m_Samples[
i] =
static_cast<unsigned short int>(std::round(s(
i * res) * (sample->
m_outputRes - 1)));
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)
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