Spaces:
Build error
Build error
function Natural(context) { | |
this._context = context; | |
} | |
Natural.prototype = { | |
areaStart: function() { | |
this._line = 0; | |
}, | |
areaEnd: function() { | |
this._line = NaN; | |
}, | |
lineStart: function() { | |
this._x = []; | |
this._y = []; | |
}, | |
lineEnd: function() { | |
var x = this._x, | |
y = this._y, | |
n = x.length; | |
if (n) { | |
this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); | |
if (n === 2) { | |
this._context.lineTo(x[1], y[1]); | |
} else { | |
var px = controlPoints(x), | |
py = controlPoints(y); | |
for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { | |
this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); | |
} | |
} | |
} | |
if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); | |
this._line = 1 - this._line; | |
this._x = this._y = null; | |
}, | |
point: function(x, y) { | |
this._x.push(+x); | |
this._y.push(+y); | |
} | |
}; | |
// See https://www.particleincell.com/2012/bezier-splines/ for derivation. | |
function controlPoints(x) { | |
var i, | |
n = x.length - 1, | |
m, | |
a = new Array(n), | |
b = new Array(n), | |
r = new Array(n); | |
a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; | |
for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; | |
a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; | |
for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; | |
a[n - 1] = r[n - 1] / b[n - 1]; | |
for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; | |
b[n - 1] = (x[n] + a[n - 1]) / 2; | |
for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; | |
return [a, b]; | |
} | |
export default function(context) { | |
return new Natural(context); | |
} | |