From 4dfa34bfebd9245307a4041cbd5a259829d63f0b Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Thu, 21 Mar 2024 23:54:07 +0100 Subject: Add any_interpolate.h --- any_interpolate.h | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 any_interpolate.h (limited to 'any_interpolate.h') diff --git a/any_interpolate.h b/any_interpolate.h new file mode 100644 index 0000000..a670c13 --- /dev/null +++ b/any_interpolate.h @@ -0,0 +1,241 @@ +#ifndef ANY_INTERPOLATE_INCLUDE +#define ANY_INTERPOLATE_INCLUDE + +#ifdef __GNUC__ +#define ANY_INTERPOLATE_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) +#else +#define ANY_INTERPOLATE_ATTRIBUTE(...) +#endif + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_sign(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_lerp(double x, double a, double b); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_step(double x, double edge); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_normalize(double x, double edge0, double edge1); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_clamp(double x, double min, double max); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_steps(double x, unsigned int n); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_smoothstep(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_inverse_smoothstep(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_smootherstep(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_smootheststep(double x, double s); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_inverse_smootheststep(double x, double s); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_sstep(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_ssteppow(double x, double k); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_ssteppow2(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_inverse_ssteppow2(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_gain(double x, double k); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_inverse_gain(double x, double k); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_gain2(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_inverse_gain2(double x); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_hyperbolic_tan(double x, double k); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_quadratic_bezier(double x, double a, double b, double c); + +ANY_INTERPOLATE_ATTRIBUTE(const) +double any_cubic_bezier(double x, double a, double b, double c, double d); + +#endif + +#ifdef ANY_INTERPOLATE_IMPLEMENT + +#include + +// +// | -1 if x < 0 +// sign(x) = | 0 if x == 0 +// | 1 if x > 0 +// +double any_sign(double x) +{ + return copysign(1.0, x); +} + +// +// lerp(x) = a (1 - x) + b x +// +double any_lerp(double x, double a, double b) +{ + return a * (1.0 - x) + (b * x); +} + +// +// step(x) = | 0 if x < edge +// | 1 if x >= edge +// +double any_step(double x, double edge) +{ + return x < edge ? 0.0 : 1.0; +} + +// +// e1 - x +// normalize(x) = ------- => [0, 1] +// e1 - e0 +// +double any_normalize(double x, double edge0, double edge1) +{ + return (edge1 - x) / (edge1 - edge0); +} + +// | 0 if x < min +// clamp(x) = | x if min <= x <= max +// | 1 if x > max +// +double any_clamp(double x, double min, double max) +{ + const double t = x < min ? min : x; + return t > max ? max : t; +} + +double any_steps(double x, unsigned int n) +{ + return floor(x * n) * (1.0 / n); +} + +// +// smoothstep(x) = 3 x^2 - 2 x^3 +// +double any_smoothstep(double x) +{ + return x * x * (3.0 - 2.0 * x); +} + +double any_inverse_smoothstep(double x) +{ + return 0.5 - sin(asin(1.0 - 2.0 * x) / 3.0); +} + +// +// smootherstep(x) = 6 x^5 - 15 x^4 + 10 x^3 +// +double any_smootherstep(double x) +{ + return x * x * x * (x * (6.0 * x - 15.0) + 10.0); +} + +double any_smootheststep(double x, double s) +{ + // 2.0 / ln(2.0) + const double ss = 2.88539008178; + return 1.0 / (1.0 + exp2(tan(x * M_PI - 0.5 * M_PI) * -(s * ss))); +} + +double any_inverse_smootheststep(double x, double s) +{ + // 2.0 / ln(2.0) + const double ss = 2.88539008178; + return atan(log2(1.0 / (1.0 - x) - 1.0) / s) * (1.0 / M_PI) + 0.5; +} + +double any_sstep(double x) +{ + const double ix = 1.0 - x; + x *= x; + return x / (x + ix * ix); +} + +double any_ssteppow(double x, double k) +{ + double ix = 1.0 - x; + x = pow(x, k); + ix = pow(ix, k); + return x / (x + ix); +} + +double any_ssteppow2(double x) +{ + return x * x / ((2.0 * x * (x - 1.0)) + 1.0); +} + +double any_inverse_ssteppow2(double x); +{ + return (x - sqrt(x * (1.0 - x))) / (2.0 * x - 1.0); +} + +double any_gain(double x, double k) +{ + const double sign = any_sign(x - 0.5); + const double o = (1.0 + sign) / 2.0; + return o - 0.5 * sign * pow(2.0 * (o - sign * x), k); +} + +double any_inverse_gain(double x, double k) +{ + const double sign = any_sign(x - 0.5); + const double o = (1.0 + sign) / 2.0; + return o - 0.5 * sign * pow(2.0 * (o - sign * x), 1.0 / k); +} + +double any_gain2(double x) +{ + return (x < 0.5) ? 2.0 * x * x : 2.0 * x * (2.0 - x) - 1.0; +} + +double any_inverse_gain2(double x) +{ + return (x < 0.5) ? sqrt(2.0 * x) / 2.0 : 1.0 - sqrt(2.0 - 2.0 * x) / 2.0; +} + +double any_hyperbolic_tan(double x, double k) +{ + return 0.5 + 0.5 * tanh((x - 0.5) * k); +} + +// +// quadratic_bezier(x) = a (1 - x)^2 + 2b (1 - x) x + c x^2 +// +double any_quadratic_bezier(double x, double a, double b, double c) +{ + const double t = 1 - x; + return a * t * t + 2 * b * t * x + c * x * x; +} + +// +// cubic_bezier(x) = a (1 - x)^3 + 3b (1 - x)^2 x + 3c (1 - x) x^2 + d x^3 +// +double any_cubic_bezier(double x, double a, double b, double c, double d) +{ + const double t = 1 - x; + return a * (t * t * t) + 3 * b * (t * t * x) + 3 * c * (t * x * x) + d * (x * x * x); +} + +#endif -- cgit v1.2.3