6#ifndef THEORETICA_SPLINES_H
7#define THEORETICA_SPLINES_H
9#include "../core/constants.h"
10#include "../algebra/algebra_types.h"
18 return (x1 + interp * (x2 - x1));
23 template<
unsigned int N>
25 const vec<real, N>& P1,
const vec<real, N>& P2,
real interp) {
27 return (P1 + (P2 - P1) * interp);
33 return (value - x1) / (x2 - x1);
38 template<
unsigned int N>
40 const vec<real, N>& P1,
const vec<real, N>& P2,
real value) {
45 for (
int i = 1; i < N; ++i) {
61 return lerp(oFrom, oTo,
invlerp(iFrom, iTo, value));
66 template<
unsigned int N>
68 const vec<real, N>& iFrom,
const vec<real, N>& iTo,
69 const vec<real, N>& oFrom,
const vec<real, N>& oTo,
real value) {
70 return lerp(oFrom, oTo,
invlerp(iFrom, iTo, value));
75 template<
unsigned int N>
77 const vec<real, N>& P1,
const vec<real, N>& P2,
real interp) {
79 return (P1 + (P2 - P1) * interp).normalized();
84 template<
unsigned int N>
86 const vec<real, N>& P1,
const vec<real, N>& P2,
real t) {
90 const real P1_l = P1.norm();
91 const real P2_l = P2.norm();
95 if(P1_l == 0 || P2_l == 0) {
97 return vec<real, N>(
nan());
101 real omega =
acos((P1 * P2) / (P1_l * P2_l));
107 return vec<real, N>(
nan());
110 return (P1 *
sin((1 - t) * omega) + P2 *
sin(t * omega)) / s;
126 const real x =
clamp((interp - x1) / (x2 - x1), 0.0, 1.0);
129 return x * x * (3 - 2 * x);
142 const real x =
clamp((interp - x1) / (x2 - x1), 0.0, 1.0);
145 return x * x * x * (x * (x * 6 - 15) + 10);
153 template<
unsigned int N>
155 const vec<real, N>& P0,
const vec<real, N>& P1,
156 const vec<real, N>& P2,
real t) {
163 template<
unsigned int N>
165 const vec<real, N>& P0,
const vec<real, N>& P1,
166 const vec<real, N>& P2, vec<real, N> P3,
real t) {
168 const vec<real, N> A =
lerp(P0, P1, t);
169 const vec<real, N> B =
lerp(P1, P2, t);
170 const vec<real, N> C =
lerp(P2, P3, t);
172 const vec<real, N> D =
lerp(A, B, t);
173 const vec<real, N>
E =
lerp(B, C, t);
175 return lerp(D,
E, t);
189 template<
unsigned int N>
190 inline vec<real, N>
bezier(
const std::vector<vec<real, N>>& points,
real t) {
192 if(points.size() < 2) {
194 return vec<real, N>(
nan());
199 return vec<real, N>(
nan());
202 std::vector<vec<real, N>> p = points;
204 for (
int index = p.size(); index > 1; --index) {
206 for (
int i = 0; i < index - 1; ++i)
207 p[i] =
lerp(p[i], p[i + 1], t);
229 :
x(
x),
a(
a), b(b), c(c), d(d) {}
235 const real h = X -
x;
236 return a + h * (b + h * (c + h * d));
243 const real h = X -
x;
244 return b + h * (c * 2 + h * d * 3);
252 template<
typename DataPo
ints = std::vector<vec2>>
260 const unsigned int n = p.size() - 1;
262 std::vector<real> dx(n);
263 std::vector<real> delta(n);
267 std::vector<real> alpha(n + 1);
268 std::vector<real> beta(n + 1);
269 std::vector<real> gamma(n + 1);
275 std::vector<real> b(n);
276 std::vector<real> c(n + 1);
277 std::vector<real> d(n);
279 for (
unsigned int i = 0; i < n; ++i)
280 dx[i] = p[i + 1][0] - p[i][0];
282 for (
unsigned int i = 1; i < n; ++i)
284 ((p[i + 1][1] - p[i][1]) / dx[i])
285 - (p[i][1] - p[i - 1][1]) / dx[i - 1]);
287 for (
unsigned int i = 1; i < n; ++i) {
288 alpha[i] = 2 * (p[i + 1][0] - p[i - 1][0]) - dx[i - 1] * beta[i - 1];
289 beta[i] = dx[i] / alpha[i];
290 gamma[i] = (delta[i] - dx[i] * gamma[i - 1]) / alpha[i];
300 for (
int i = n - 1; i >= 0; --i) {
302 c[i] = gamma[i] - beta[i] * c[i + 1];
303 b[i] = (p[i + 1][1] - p[i][1]) / dx[i]
304 - dx[i] * (c[i + 1] + 2 * c[i]) / 3.0;
305 d[i] = (c[i + 1] - c[i]) / (3.0 * dx[i]);
308 std::vector<spline_node> nodes(n);
310 for (
unsigned int i = 0; i < n; ++i)
311 nodes[i] =
spline_node(p[i][0], p[i][1], b[i], c[i], d[i]);
320 template<
typename Dataset1,
typename Dataset2>
322 const Dataset1& x,
const Dataset2& y) {
329 if(x.size() != y.size()) {
334 const unsigned int n = x.size() - 1;
336 std::vector<real> dx(n);
337 std::vector<real> delta(n);
341 std::vector<real> alpha(n + 1);
342 std::vector<real> beta(n + 1);
343 std::vector<real> gamma(n + 1);
349 std::vector<real> b(n);
350 std::vector<real> c(n + 1);
351 std::vector<real> d(n);
353 for (
unsigned int i = 0; i < n; ++i)
354 dx[i] = x[i + 1] - x[i];
356 for (
unsigned int i = 1; i < n; ++i)
358 ((y[i + 1] - y[i]) / dx[i])
359 - (y[i] - y[i - 1]) / dx[i - 1]);
361 for (
unsigned int i = 1; i < n; ++i) {
362 alpha[i] = 2 * (x[i + 1] - x[i - 1]) - dx[i - 1] * beta[i - 1];
363 beta[i] = dx[i] / alpha[i];
364 gamma[i] = (delta[i] - dx[i] * gamma[i - 1]) / alpha[i];
374 for (
int i = n - 1; i >= 0; --i) {
376 c[i] = gamma[i] - beta[i] * c[i + 1];
377 b[i] = (y[i + 1] - y[i]) / dx[i]
378 - dx[i] * (c[i + 1] + 2 * c[i]) / 3.0;
379 d[i] = (c[i + 1] - c[i]) / (3.0 * dx[i]);
382 std::vector<spline_node> nodes(n);
384 for (
unsigned int i = 0; i < n; ++i)
385 nodes[i] =
spline_node(x[i], y[i], b[i], c[i], d[i]);
403 template<
typename DataPo
ints = std::vector<vec2>>
411 template<
typename Dataset1,
typename Dataset2>
412 spline(
const Dataset1& X,
const Dataset2& Y) {
428 for (
int i =
int(
nodes.size()) - 1; i > 0; --i)
441 for (
unsigned int i =
nodes.size() - 1; i > 0; --i)
443 return nodes[i].deriv(x);
446 return nodes[0].deriv(x);
452 return nodes.begin();
A natural cubic spline interpolation class.
Definition splines.h:393
spline(const Dataset1 &X, const Dataset2 &Y)
Construct the natural cubic spline interpolation from the sets of X and Y data points.
Definition splines.h:412
real operator()(real x) const
Evaluate the natural cubic spline interpolation at a given point.
Definition splines.h:426
real deriv(real x) const
Evaluate the derivative of the natural cubic spline interpolation at a given point.
Definition splines.h:439
auto end()
Get an iterator to one plus the last spline element.
Definition splines.h:457
auto begin()
Get an iterator to the first spline element.
Definition splines.h:451
spline(const DataPoints &p)
Construct the natural cubic spline interpolation from a vector of coordinate pairs.
Definition splines.h:404
spline & operator=(const spline &other)
Copy from another spline.
Definition splines.h:418
std::vector< spline_node > nodes
The computed nodes of the natural cubic spline interpolation over the points.
Definition splines.h:398
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition error.h:238
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:198
real smootherstep(real x1, real x2, real interp)
Smootherstep interpolation.
Definition splines.h:134
vec< real, N > nlerp(const vec< real, N > &P1, const vec< real, N > &P2, real interp)
Normalized linear interpolation.
Definition splines.h:76
real remap(real iFrom, real iTo, real oFrom, real oTo, real value)
Remap a value from one range to another.
Definition splines.h:60
real smoothstep(real x1, real x2, real interp)
Smoothstep interpolation.
Definition splines.h:118
real invlerp(real x1, real x2, real value)
Inverse linear interpolation.
Definition splines.h:32
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:78
std::vector< spline_node > cubic_splines(DataPoints p)
Compute the cubic splines interpolation of a set of data points.
Definition splines.h:253
@ InvalidArgument
Invalid argument.
@ OutOfDomain
Argument out of domain.
@ ImpossibleOperation
Mathematically impossible operation.
@ DivByZero
Division by zero.
real lerp(real x1, real x2, real interp)
Linear interpolation.
Definition splines.h:17
constexpr real E
The Euler mathematical constant (e)
Definition constants.h:237
vec< real, N > bezier(const std::vector< vec< real, N > > &points, real t)
Generic Bezier curve in N dimensions.
Definition splines.h:190
vec< real, N > cubic_bezier(const vec< real, N > &P0, const vec< real, N > &P1, const vec< real, N > &P2, vec< real, N > P3, real t)
Cubic Bezier curve.
Definition splines.h:164
dual2 acos(dual2 x)
Compute the arcosine of a second order dual number.
Definition dual2_functions.h:223
vec< real, N > slerp(const vec< real, N > &P1, const vec< real, N > &P2, real t)
Spherical interpolation.
Definition splines.h:85
dual2 sin(dual2 x)
Compute the sine of a second order dual number.
Definition dual2_functions.h:72
real clamp(real x, real a, real b)
Clamp x between a and b.
Definition real_analysis.h:355
vec< real, N > quadratic_bezier(const vec< real, N > &P0, const vec< real, N > &P1, const vec< real, N > &P2, real t)
Quadratic Bezier curve.
Definition splines.h:154
A cubic splines node for a given x interval.
Definition splines.h:215
spline_node()
Default constructor.
Definition splines.h:225
real operator()(real X) const
Evaluate the interpolating cubic spline (no check on the input value is performed!...
Definition splines.h:234
real deriv(real X) const
Evaluate the derivative of the interpolating cubic spline (no check on the input value is performed)
Definition splines.h:242
real x
Upper extreme of the interpolation interval .
Definition splines.h:218
real a
Coefficients of the interpolating cubic spline .
Definition splines.h:222
spline_node(real x, real a, real b, real c, real d)
Construct from and polynomial coefficients.
Definition splines.h:228