-
Notifications
You must be signed in to change notification settings - Fork 1
/
reticulate-splines.js
71 lines (59 loc) · 1.56 KB
/
reticulate-splines.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
var cache = {
'1': bezier1
, '2': bezier2
, '3': bezier3
, '4': bezier4
}
module.exports = neat
module.exports.prepare = prepare
function neat(arr, t) {
return prepare(arr.length)(arr, t)
}
function prepare(pieces) {
pieces = +pieces|0
if (!pieces) throw new Error('Cannot create a interpolator with no elements')
if (cache[pieces]) return cache[pieces]
var fn = ['var ut = 1 - t', '']
var n = pieces
while (n--) {
for (var j = 0; j < n; j += 1) {
if (n+1 === pieces) {
fn.push('var p'+j+' = arr['+j+'] * ut + arr['+(j+1)+'] * t')
} else
if (n > 1) {
fn.push('p'+j+' = p'+j+' * ut + p'+(j+1)+' * t')
} else {
fn.push('return p'+j+' * ut + p'+(j+1)+' * t')
}
}
if (n > 1) fn.push('')
}
fn = [
'return function bezier'+pieces+'(arr, t) {'
, fn.map(function(s) { return ' ' + s }).join('\n')
, '}'
].join('\n')
return Function(fn)()
}
//
// Including the first four degrees
// manually - there's a slight performance penalty
// to generated code. It's outweighed by
// the gains of the optimisations, but always
// helps to cover the most common cases :)
//
function bezier1(arr) {
return arr[0]
}
function bezier2(arr, t) {
return arr[0] + (arr[1] - arr[0]) * t
}
function bezier3(arr, t) {
var ut = 1 - t
return (arr[0] * ut + arr[1] * t) * ut + (arr[1] * ut + arr[2] * t) * t
}
function bezier4(arr, t) {
var ut = 1 - t
var a1 = arr[1] * ut + arr[2] * t
return ((arr[0] * ut + arr[1] * t) * ut + a1 * t) * ut + (a1 * ut + (arr[2] * ut + arr[3] * t) * t) * t
}