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;
    ...