-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.js
94 lines (74 loc) · 2.33 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
var add = require('gl-vec2/add');
var scale = require('gl-vec2/scale');
var distance = require('gl-vec2/distance');
var interpolatePoint = function(p0, p1, p2, p3, t0, t1, t2, t3, t) {
var a1, a2, a3, b1, b2, c;
a1 = [];
a2 = [];
a3 = [];
b1 = [];
b2 = [];
c = [];
add(a1, scale([], p0, (t1 - t)/(t1 - t0)), scale([], p1, (t - t0)/(t1 - t0)));
add(a2, scale([], p1, (t2 - t)/(t2 - t1)), scale([], p2, (t - t1)/(t2 - t1)));
add(a3, scale([], p2, (t3 - t)/(t3 - t2)), scale([], p3, (t - t2)/(t3 - t2)));
add(b1, scale([], a1, (t2 - t)/(t2 - t0)), scale([], a2, (t - t0)/(t2 - t0)));
add(b2, scale([], a2, (t3 - t)/(t3 - t1)), scale([], a3, (t - t1)/(t3 - t1)));
add(c, scale([], b1, (t2 - t)/(t2 - t1)), scale([], b2, (t - t1)/(t2 - t1)));
return c;
};
var catmullRomSplineSegment = function(p0, p1, p2, p3, samples, knot) {
var t, t0, t1, t2, t3, segmentDist;
var points = [];
segmentDist = distance(p1, p2);
t0 = 0;
t1 = Math.pow(distance(p0, p1), knot);
t2 = Math.pow(segmentDist, knot) + t1;
t3 = Math.pow(distance(p2, p3), knot) + t2;
if (!samples) {
samples = segmentDist * 1.5;
}
var sampleStep = (t2 - t1) / samples;
t = t1;
while (t < t2) {
t += sampleStep;
points.push(interpolatePoint(p0, p1, p2, p3, t0, t1, t2, t3, t));
}
return points;
};
var catmullRomSpline = function(controlPoints, options) {
if (controlPoints.length < 4) {
throw "Must have at least 4 control points to generate catmull rom spline";
}
var points = [];
var p0, p1, p2, p3, offset;
options = options || {};
var knot = options.knot || 0.5;
var samples = options.samples;
controlPoints.forEach(function(point, i) {
offset = 1;
p0 = point;
do {
p1 = controlPoints[i + offset];
offset++;
} while (p0 && p1 && p0[0] === p1[0] && p0[1] === p1[1]);
do {
p2 = controlPoints[i + offset];
offset++;
} while (p1 && p2 && p1[0] === p2[0] && p1[1] === p2[1]);
do {
p3 = controlPoints[i + offset];
offset++;
} while (p2 && p3 && p2[0] === p3[0] && p2[1] === p3[1]);
if (!(p1 && p2 && p3)) {
return;
}
points.push(p1);
points = points.concat(catmullRomSplineSegment(p0, p1, p2, p3, samples, knot));
if (!controlPoints[offset]) {
points.push(p2);
}
});
return points;
};
module.exports = catmullRomSpline;