Skip to main content

proof_engine/math/
mod.rs

1//! Mathematical primitives: functions, force fields, attractors.
2//!
3//! Every visual property in Proof Engine is driven by a `MathFunction`.
4//! Every spatial interaction is modeled as a `ForceField`.
5//! No keyframes. No tweens. Only functions.
6
7pub mod eval;
8pub mod attractors;
9pub mod noise;
10pub mod springs;
11pub mod fields;
12pub mod color;
13pub mod complex;
14pub mod curves;
15pub mod numerical;
16pub mod geometry;
17pub mod statistics;
18pub mod simulation;
19#[cfg(feature = "rhai-scripts")]
20pub mod scripted;
21
22pub use eval::MathFunction;
23pub use fields::{ForceField, Falloff, FieldTarget};
24pub use attractors::AttractorType;
25pub use springs::{SpringDamper, Spring3D, SpringDamper3};
26
27
28/// Evaluate a scalar function of time.
29/// `t` = elapsed seconds since engine start.
30/// `input` = chained input value (for composed functions).
31pub fn evaluate(f: &MathFunction, t: f32, input: f32) -> f32 {
32    f.evaluate(t, input)
33}
34
35/// Map a value from [in_min, in_max] to [out_min, out_max].
36#[inline]
37pub fn remap(v: f32, in_min: f32, in_max: f32, out_min: f32, out_max: f32) -> f32 {
38    let t = (v - in_min) / (in_max - in_min);
39    out_min + t * (out_max - out_min)
40}
41
42/// Smooth step (3t² - 2t³).
43#[inline]
44pub fn smoothstep(t: f32) -> f32 {
45    let t = t.clamp(0.0, 1.0);
46    t * t * (3.0 - 2.0 * t)
47}
48
49/// Smoother step (6t⁵ - 15t⁴ + 10t³).
50#[inline]
51pub fn smootherstep(t: f32) -> f32 {
52    let t = t.clamp(0.0, 1.0);
53    t * t * t * (t * (t * 6.0 - 15.0) + 10.0)
54}
55
56/// Lerp two colors.
57#[inline]
58pub fn lerp_color(a: (u8, u8, u8), b: (u8, u8, u8), t: f32) -> (u8, u8, u8) {
59    let t = t.clamp(0.0, 1.0);
60    (
61        (a.0 as f32 + (b.0 as f32 - a.0 as f32) * t) as u8,
62        (a.1 as f32 + (b.1 as f32 - a.1 as f32) * t) as u8,
63        (a.2 as f32 + (b.2 as f32 - a.2 as f32) * t) as u8,
64    )
65}
66
67/// Hsv to RGB.
68pub fn hsv_to_rgb(h: f32, s: f32, v: f32) -> (f32, f32, f32) {
69    if s == 0.0 { return (v, v, v); }
70    let h = h % 360.0;
71    let i = (h / 60.0) as u32;
72    let f = h / 60.0 - i as f32;
73    let p = v * (1.0 - s);
74    let q = v * (1.0 - s * f);
75    let t = v * (1.0 - s * (1.0 - f));
76    match i {
77        0 => (v, t, p),
78        1 => (q, v, p),
79        2 => (p, v, t),
80        3 => (p, q, v),
81        4 => (t, p, v),
82        _ => (v, p, q),
83    }
84}