summaryrefslogtreecommitdiffstats
path: root/include/interpolate.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/interpolate.h')
-rwxr-xr-xinclude/interpolate.h205
1 files changed, 184 insertions, 21 deletions
diff --git a/include/interpolate.h b/include/interpolate.h
index 1f79405..da23315 100755
--- a/include/interpolate.h
+++ b/include/interpolate.h
@@ -1,31 +1,194 @@
// Math for Game Programmers: Fast and Funky 1D Nonlinear Transformations
// https://www.youtube.com/watch?v=mr5xkf6zSzk
+//
+// Thread safety: Safe for concurrent use (no shared state, pure functions).
+// Macros: Namespaced INTERP_* variants are collision-safe. Legacy un-prefixed
+// names are provided via #ifndef guard — if your code already defines e.g.
+// "mix", the library will not override it.
#ifndef INTERPOLATE_H
-#define INTERPOLATE_H
+#define INTERPOLATE_H
-#define smooth_start_2( t ) ( t * t )
-#define smooth_start_3( t ) ( smooth_start_2( t ) * t )
-#define smooth_start_4( t ) ( smooth_start_3( t ) * t )
-#define smooth_start_5( t ) ( smooth_start_4( t ) * t )
-#define smooth_start_6( t ) ( smooth_start_5( t ) * t )
+// Namespaced macros (safe from collisions). Use these in new code.
+#ifndef INTERP_FLIP
+#define INTERP_FLIP(x) (1.0 - (double)(x))
+#endif
+#ifndef INTERP_SCALE
+#define INTERP_SCALE(a, t) ((double)(t) * (double)(a))
+#endif
+#ifndef INTERP_REVERSE_SCALE
+#define INTERP_REVERSE_SCALE(a, t) ((1.0 - (double)(t)) * (double)(a))
+#endif
+#ifndef INTERP_MIX
+#define INTERP_MIX(a, b, b_weight) ((double)(a) + (double)(b_weight) * ((double)(b) - (double)(a)))
+#endif
+#ifndef INTERP_CROSSFADE
+#define INTERP_CROSSFADE(a, b, t) ((double)(a) + (double)(t) * ((double)(b) - (double)(a)))
+#endif
-#define smooth_stop_2( t ) ( flip( smooth_start_2( flip( t ) ) ) )
-#define smooth_stop_3( t ) ( flip( smooth_start_3( flip( t ) ) ) )
-#define smooth_stop_4( t ) ( flip( smooth_start_4( flip( t ) ) ) )
-#define smooth_stop_5( t ) ( flip( smooth_start_5( flip( t ) ) ) )
-#define smooth_stop_6( t ) ( flip( smooth_start_6( flip( t ) ) ) )
+#ifndef INTERP_SMOOTH_START_2
+#define INTERP_SMOOTH_START_2(t) ((double)(t) * (double)(t))
+#endif
+#ifndef INTERP_SMOOTH_START_3
+#define INTERP_SMOOTH_START_3(t) (INTERP_SMOOTH_START_2(t) * (double)(t))
+#endif
+#ifndef INTERP_SMOOTH_START_4
+#define INTERP_SMOOTH_START_4(t) (INTERP_SMOOTH_START_3(t) * (double)(t))
+#endif
+#ifndef INTERP_SMOOTH_START_5
+#define INTERP_SMOOTH_START_5(t) (INTERP_SMOOTH_START_4(t) * (double)(t))
+#endif
+#ifndef INTERP_SMOOTH_START_6
+#define INTERP_SMOOTH_START_6(t) (INTERP_SMOOTH_START_5(t) * (double)(t))
+#endif
-#define smooth_step_3( t ) ( crossfade( smooth_start_2( t ), smooth_stop_2( t ), t ) )
-#define mix( a, b, b_weight ) ( a + b_weight * ( b - a ) )
-#define crossfade( a, b, t ) ( a + t * ( b - a ) )
-#define scale( a, t ) ( t * a )
-#define reverse_scale( a, t ) ( ( 1 - t ) * a )
+#ifndef INTERP_SMOOTH_STOP_2
+#define INTERP_SMOOTH_STOP_2(t) (INTERP_FLIP(INTERP_SMOOTH_START_2(INTERP_FLIP(t))))
+#endif
+#ifndef INTERP_SMOOTH_STOP_3
+#define INTERP_SMOOTH_STOP_3(t) (INTERP_FLIP(INTERP_SMOOTH_START_3(INTERP_FLIP(t))))
+#endif
+#ifndef INTERP_SMOOTH_STOP_4
+#define INTERP_SMOOTH_STOP_4(t) (INTERP_FLIP(INTERP_SMOOTH_START_4(INTERP_FLIP(t))))
+#endif
+#ifndef INTERP_SMOOTH_STOP_5
+#define INTERP_SMOOTH_STOP_5(t) (INTERP_FLIP(INTERP_SMOOTH_START_5(INTERP_FLIP(t))))
+#endif
+#ifndef INTERP_SMOOTH_STOP_6
+#define INTERP_SMOOTH_STOP_6(t) (INTERP_FLIP(INTERP_SMOOTH_START_6(INTERP_FLIP(t))))
+#endif
-#define arch_2( t ) ( scale( flip( t ), t ) )
-#define smooth_start_arch_3( t ) ( scale( arch_2( t ), t ) )
-#define smooth_stop_arch_3( t ) ( reverse_scale( arch_2( t ), t ) )
+#ifndef INTERP_SMOOTH_STEP_3
+#define INTERP_SMOOTH_STEP_3(t) (INTERP_CROSSFADE(INTERP_SMOOTH_START_2(t), INTERP_SMOOTH_STOP_2(t), (double)(t)))
+#endif
-#define flip( x ) ( 1 - x )
+#ifndef INTERP_ARCH_2
+#define INTERP_ARCH_2(t) (INTERP_SCALE(INTERP_FLIP(t), (double)(t)))
+#endif
+#ifndef INTERP_SMOOTH_START_ARCH_3
+#define INTERP_SMOOTH_START_ARCH_3(t) (INTERP_SCALE(INTERP_ARCH_2(t), (double)(t)))
+#endif
+#ifndef INTERP_SMOOTH_STOP_ARCH_3
+#define INTERP_SMOOTH_STOP_ARCH_3(t) (INTERP_REVERSE_SCALE(INTERP_ARCH_2(t), (double)(t)))
+#endif
-#endif \ No newline at end of file
+// Legacy macro names — alias to namespaced variants when not already defined by user.
+#ifndef flip
+#define flip(x) INTERP_FLIP(x)
+#endif
+#ifndef scale
+#define scale(a, t) INTERP_SCALE(a, t)
+#endif
+#ifndef reverse_scale
+#define reverse_scale(a, t) INTERP_REVERSE_SCALE(a, t)
+#endif
+#ifndef mix
+#define mix(a, b, b_weight) INTERP_MIX(a, b, b_weight)
+#endif
+#ifndef crossfade
+#define crossfade(a, b, t) INTERP_CROSSFADE(a, b, t)
+#endif
+
+#ifndef smooth_start_2
+#define smooth_start_2(t) INTERP_SMOOTH_START_2(t)
+#endif
+#ifndef smooth_start_3
+#define smooth_start_3(t) INTERP_SMOOTH_START_3(t)
+#endif
+#ifndef smooth_start_4
+#define smooth_start_4(t) INTERP_SMOOTH_START_4(t)
+#endif
+#ifndef smooth_start_5
+#define smooth_start_5(t) INTERP_SMOOTH_START_5(t)
+#endif
+#ifndef smooth_start_6
+#define smooth_start_6(t) INTERP_SMOOTH_START_6(t)
+#endif
+
+#ifndef smooth_stop_2
+#define smooth_stop_2(t) INTERP_SMOOTH_STOP_2(t)
+#endif
+#ifndef smooth_stop_3
+#define smooth_stop_3(t) INTERP_SMOOTH_STOP_3(t)
+#endif
+#ifndef smooth_stop_4
+#define smooth_stop_4(t) INTERP_SMOOTH_STOP_4(t)
+#endif
+#ifndef smooth_stop_5
+#define smooth_stop_5(t) INTERP_SMOOTH_STOP_5(t)
+#endif
+#ifndef smooth_stop_6
+#define smooth_stop_6(t) INTERP_SMOOTH_STOP_6(t)
+#endif
+
+#ifndef smooth_step_3
+#define smooth_step_3(t) INTERP_SMOOTH_STEP_3(t)
+#endif
+
+#ifndef arch_2
+#define arch_2(t) INTERP_ARCH_2(t)
+#endif
+#ifndef smooth_start_arch_3
+#define smooth_start_arch_3(t) INTERP_SMOOTH_START_ARCH_3(t)
+#endif
+#ifndef smooth_stop_arch_3
+#define smooth_stop_arch_3(t) INTERP_SMOOTH_STOP_ARCH_3(t)
+#endif
+
+/* Function wrappers for debuggability (use these instead of macros when debugging) */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+double interpolate_flip(double t);
+double interpolate_scale(double a, double t);
+double interpolate_reverse_scale(double a, double t);
+double interpolate_mix(double a, double b, double b_weight);
+double interpolate_crossfade(double a, double b, double t);
+double interpolate_smooth_start_2(double t);
+double interpolate_smooth_start_3(double t);
+double interpolate_smooth_start_4(double t);
+double interpolate_smooth_start_5(double t);
+double interpolate_smooth_start_6(double t);
+double interpolate_smooth_stop_2(double t);
+double interpolate_smooth_stop_3(double t);
+double interpolate_smooth_stop_4(double t);
+double interpolate_smooth_stop_5(double t);
+double interpolate_smooth_stop_6(double t);
+double interpolate_smooth_step_3(double t);
+double interpolate_arch_2(double t);
+double interpolate_smooth_start_arch_3(double t);
+double interpolate_smooth_stop_arch_3(double t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#ifdef INTERPOLATE_IMPLEMENTATION
+#ifndef INTERPOLATE_IMPLEMENTED
+#define INTERPOLATE_IMPLEMENTED
+
+double interpolate_flip(double t) { return flip(t); }
+double interpolate_scale(double a, double t) { return scale(a, t); }
+double interpolate_reverse_scale(double a, double t) { return reverse_scale(a, t); }
+double interpolate_mix(double a, double b, double b_weight) { return mix(a, b, b_weight); }
+double interpolate_crossfade(double a, double b, double t) { return crossfade(a, b, t); }
+double interpolate_smooth_start_2(double t) { return smooth_start_2(t); }
+double interpolate_smooth_start_3(double t) { return smooth_start_3(t); }
+double interpolate_smooth_start_4(double t) { return smooth_start_4(t); }
+double interpolate_smooth_start_5(double t) { return smooth_start_5(t); }
+double interpolate_smooth_start_6(double t) { return smooth_start_6(t); }
+double interpolate_smooth_stop_2(double t) { return smooth_stop_2(t); }
+double interpolate_smooth_stop_3(double t) { return smooth_stop_3(t); }
+double interpolate_smooth_stop_4(double t) { return smooth_stop_4(t); }
+double interpolate_smooth_stop_5(double t) { return smooth_stop_5(t); }
+double interpolate_smooth_stop_6(double t) { return smooth_stop_6(t); }
+double interpolate_smooth_step_3(double t) { return smooth_step_3(t); }
+double interpolate_arch_2(double t) { return arch_2(t); }
+double interpolate_smooth_start_arch_3(double t) { return smooth_start_arch_3(t); }
+double interpolate_smooth_stop_arch_3(double t) { return smooth_stop_arch_3(t); }
+
+#endif /* INTERPOLATE_IMPLEMENTED */
+#endif // INTERPOLATE_IMPLEMENTATION \ No newline at end of file