caryclark | 3257c12 | 2015-11-16 13:36:08 -0800 | [diff] [blame] | 1 | function interp(A, B, t) { |
| 2 | return A + (B - A) * t; |
| 3 | } |
| 4 | |
| 5 | function interp_cubic_coords(x1, x2, x3, x4, t) |
| 6 | { |
| 7 | var ab = interp(x1, x2, t); |
| 8 | var bc = interp(x2, x3, t); |
| 9 | var cd = interp(x3, x4, t); |
| 10 | var abc = interp(ab, bc, t); |
| 11 | var bcd = interp(bc, cd, t); |
| 12 | var abcd = interp(abc, bcd, t); |
| 13 | return abcd; |
| 14 | } |
| 15 | |
| 16 | // FIXME : only works for path with single cubic |
| 17 | function path_partial(value, path) { |
| 18 | assert(isArray(path)); |
| 19 | var out = []; |
| 20 | for (var cIndex = 0; cIndex < path.length; ++cIndex) { |
| 21 | out[cIndex] = {}; |
| 22 | var curveKey = Object.keys(path[cIndex])[0]; |
| 23 | var curve = path[cIndex][curveKey]; |
| 24 | var outArray; |
| 25 | switch (curveKey) { |
| 26 | case "cubic": |
| 27 | var x1 = curve[0], y1 = curve[1], x2 = curve[2], y2 = curve[3]; |
| 28 | var x3 = curve[4], y3 = curve[5], x4 = curve[6], y4 = curve[7]; |
| 29 | var t1 = 0, t2 = value; |
| 30 | var ax = interp_cubic_coords(x1, x2, x3, x4, t1); |
| 31 | var ay = interp_cubic_coords(y1, y2, y3, y4, t1); |
| 32 | var ex = interp_cubic_coords(x1, x2, x3, x4, (t1*2+t2)/3); |
| 33 | var ey = interp_cubic_coords(y1, y2, y3, y4, (t1*2+t2)/3); |
| 34 | var fx = interp_cubic_coords(x1, x2, x3, x4, (t1+t2*2)/3); |
| 35 | var fy = interp_cubic_coords(y1, y2, y3, y4, (t1+t2*2)/3); |
| 36 | var dx = interp_cubic_coords(x1, x2, x3, x4, t2); |
| 37 | var dy = interp_cubic_coords(y1, y2, y3, y4, t2); |
| 38 | var mx = ex * 27 - ax * 8 - dx; |
| 39 | var my = ey * 27 - ay * 8 - dy; |
| 40 | var nx = fx * 27 - ax - dx * 8; |
| 41 | var ny = fy * 27 - ay - dy * 8; |
| 42 | var bx = (mx * 2 - nx) / 18; |
| 43 | var by = (my * 2 - ny) / 18; |
| 44 | var cx = (nx * 2 - mx) / 18; |
| 45 | var cy = (ny * 2 - my) / 18; |
| 46 | outArray = [ |
| 47 | ax, ay, bx, by, cx, cy, dx, dy |
| 48 | ]; |
| 49 | break; |
| 50 | default: |
| 51 | assert(0); // unimplemented |
| 52 | } |
| 53 | out[cIndex][curveKey] = outArray; |
| 54 | } |
| 55 | return out; |
| 56 | } |
| 57 | |
| 58 | function interp_paths(value, paths) { |
| 59 | assert(isArray(paths)); |
| 60 | assert(paths.length == 2); |
| 61 | var curves0 = paths[0]; |
| 62 | assert(isArray(curves0)); |
| 63 | var curves1 = paths[1]; |
| 64 | assert(isArray(curves1)); |
| 65 | assert(curves0.length == curves1.length); |
| 66 | var out = []; |
| 67 | for (var cIndex = 0; cIndex < curves0.length; ++cIndex) { |
| 68 | out[cIndex] = {}; |
| 69 | var curve0Key = Object.keys(curves0[cIndex])[0]; |
| 70 | var curve1Key = Object.keys(curves1[cIndex])[0]; |
| 71 | assert(curve0Key == curve1Key); |
| 72 | var curve0 = curves0[cIndex][curve0Key]; |
| 73 | var curve1 = curves1[cIndex][curve1Key]; |
| 74 | assert(isArray(curve0)); |
| 75 | assert(isArray(curve1)); |
| 76 | assert(curve0.length == curve1.length); |
| 77 | var outArray = []; |
| 78 | for (var i = 0; i < curve1.length; ++i) { |
| 79 | outArray[i] = curve0[i] + (curve1[i] - curve0[i]) * value; |
| 80 | } |
| 81 | out[cIndex][curve0Key] = outArray; |
| 82 | } |
| 83 | return out; |
| 84 | } |