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