BezierBounce
by Santiago J
HTML
<canvas id="main-canvas"></canvas>
CSS
body {
background-color: #333;
color: #eee;
}
JavaScript
(function(exports) {
var t1, t2;
function tic() {
t1 = Date.now();
}
function toc() {
t2 = Date.now();
console.log(t2 - t1 + " ms");
return t2 - t1;
}
exports.tic = tic;
exports.toc = toc;
})(this);
(function(exports) {
var oneThird = 1 / 3;
Math.cbrt = function(x) {
return x < 0 ? -Math.pow(-x, oneThird) : Math.pow(x, oneThird);
};
function solveCubic(c, s) {
var num; // number of different roots
var epsilon = 1e-9, aThird = 1 / 3;
// normal form: x^3 + Ax^2 + Bx + C = 0
var
A = c[1] / c[0],
B = c[2] / c[0],
C = c[3] / c[0];
// substitute x = y - A/3 to eliminate quadric term:
// x^3 +px + q = 0
var
sq_A = A * A,
p = aThird * (-aThird * sq_A + B),
q = 0.5 * (2/27 * A * sq_A - aThird * A * B + C);
// use Cardano's formula
var
cb_p = p * p * p,
D = q * q + cb_p;
if (Math.abs(D) < epsilon) { // D == 0
if (Math.abs(q) < epsilon) { // q == 0
// one triple solution
s[0] = 0;
num = 1;
} else {
// one single and one double solution
var u = Math.cbrt(-q);
s[0] = 2 * u;
s[1] = -u;
num = 2;
}
} else if (D < 0) {
// Casus irreducibilis: three real solutions
var
phi = aThird * Math.acos(-q / Math.sqrt(-cb_p)),
t = 2 * Math.sqrt(-p);
s[0] = t * Math.cos(phi);
s[1] = -t * Math.cos(phi + Math.PI * aThird);
s[2] = -t * Math.cos(phi - Math.PI * aThird);
num = 3;
} else { // D > 0
// one real solution
var
sqrt_D = Math.sqrt(D),
u = Math.cbrt(sqrt_D - q),
v = Math.cbrt(sqrt_D + q);
s[0] = u + v;
...