circumcenter

by Darby Rathbone

HTML

<div>
    <canvas></canvas>
</div>

CSS

html, body {
    margin:0px;
    padding:0px;
    width:100%;
    height:100%;
}
body>div {
    position:fixed;
    top:1px;
    bottom:1px;
    left:1px;
    right:1px;
}
div * {
    outline:1px dashed red;
}

JavaScript

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = parseInt(getComputedStyle(canvas.parentElement).width, 10);
canvas.height = parseInt(getComputedStyle(canvas.parentElement).height, 10);
var points = [],
    ctx = canvas.getContext('2d'),
    clickhandler = function (e) {
        setTimeout(points.push([e.pageX + Math.random(), e.pageY + Math.random()]));
    }, _push = points.push,
    circles = [];
points.push = function (_n) {
    var n = [].slice.call(_n);
    _push.call(this, n);
    ctx.beginPath();
    ctx.arc(n[0], n[1], 2, 0, Math.PI * 2, false);
    ctx.stroke();
    n.name = points.length;
    n.d = [];
    var checkpoints = [];
    var foundposition = circles.filter(function (e) {
        return ((e.radius ) * (e.radius )) > (((e[0] - n[0]) * (e[0] - n[0])) + ((e[1] - n[1]) * (e[1] - n[1])));
    });
    foundposition.forEach(function (h, i) {
        circles.splice(1, i);
        h.points.forEach(function (f) {
            checkpoints.push(f);
        })});
    for(var i = 0, e = checkpoints[i];e;e=checkpoints[++i]){
 for(var j = 0, f = checkpoints[j];f;f=checkpoints[++j]){
        var newc = [];
        newc.name = [e.name, f.name, n.name].sort().join();
        if (f.name !== e.name && n.name !== e.name && f.name !== n.name && !circles.some(function (g) {
            return g.name === newc.name;
        })) {

            var x1 = n[0] | 0,
                x2 = e[0] | 0,
                x3 = f[0] | 0,
                y1 = n[1] | 0,
                y2 = e[1] | 0,
                y3 = f[1] | 0;
            var cx = -((((y1 + y3) / 2) - ((x1 + x3) / 2) * (-(x1 - x3) / (y1 - y3))) - (((y2 + y3) / 2) - ((x2 + x3) / 2) * (-(x2 - x3) / (y2 - y3)))) / ((-(x1 - x3) / (y1 - y3)) - (-(x2 - x3) / (y2 - y3)));

            var cy = (-(x2 - x3) / (y2 - y3)) * cx + ((y2 + y3) / 2) - ((x2 + x3) / 2) * (-(x2 - x3) / (y2 - y3));
            newc.push(cx, cy);
            newc.radius = Math.sqrt((cx - e[0]) * (cx - e[0]) + (cy - e[1]) * (cy -...