1 module plot2d.interp; 2 3 auto lineInterp(RV, RK)(RV vals, RK keys, float t) 4 { 5 import std.range; 6 7 typeof(keys.front) ak = keys.front, bk = keys.front; 8 typeof(vals.front) av = vals.front, bv = vals.front; 9 10 if (t < keys.front) return vals.front; 11 12 bool pair = true; 13 14 foreach (k, v; lockstep(keys, vals)) 15 { 16 if (t < k) 17 { 18 bk = k; 19 bv = v; 20 pair = true; 21 break; 22 } 23 ak = k; 24 av = v; 25 pair = false; 26 } 27 28 if (!pair) return av; 29 30 auto c = (t - ak) / (bk - ak); 31 return av + (bv - av) * c; 32 } 33 34 unittest 35 { 36 import std.math; 37 auto v = [1.0f, 4, 5]; 38 auto k = [0.0f, 1.0f, 2.0f]; 39 40 enum eps = float.epsilon; 41 assert(fabs(lineInterp(v, k, -1) - v[0]) < eps); 42 assert(fabs(lineInterp(v, k, 0) - v[0]) < eps); 43 assert(fabs(lineInterp(v, k, 0.5) - 2.5) < eps); 44 assert(fabs(lineInterp(v, k, 1) - 4) < eps); 45 assert(fabs(lineInterp(v, k, 1.5) - 4.5) < eps); 46 assert(fabs(lineInterp(v, k, 2) - 5) < eps); 47 assert(fabs(lineInterp(v, k, 3) - 5) < eps); 48 } 49 50 T bezierInterp(size_t N, T)(auto ref const T[N] p, float t) 51 { 52 static if (N > 2) 53 { 54 T[N-1] tmp; 55 foreach (i; 0 .. N-1) 56 tmp[i] = p[i] + (p[i+1] - p[i]) * t; 57 return bezierInterp(tmp, t); 58 } 59 else static if (N==2) 60 return p[0] + (p[1] - p[0]) * t; 61 else static assert(0, "need min 2 values for interpolation"); 62 }