Universe of integer/primitive pythagorean triples - plus demo

 (function(){

    var alg = function(n){
        var base=2*n;
        return [
            [base+1, base*n + base, base*n + base+1],
            [2*base + 4, 2*base*n + 4*base + 3, 2*base*n + 4*base + 5]            
        ];
    }
    var sym=function(a,b,c){
        return [
            [[a,b,c],[-a,b,c],[-a, -b, c], [a, -b, c]],[[b,a,c],[-b,a,c],[-b, -a, c], [b, -a, c]]
        ];
    }
    var symList=function(abc){
        return sym(abc[0], abc[1], abc[2]);
    }
    var symMatrix=function(abcABC){
        return [symList(abcABC[0]), symList(abcABC[1])];
    }
    var abc = function(a, b, c){
        //122, 212, 223; neg b when T1, neg a when T3...
        return [[[
            -a + 2*b + 2*c,
            -2*a + b + 2*c,
            -2*a + 2*b + 3*c
        ],[
            a + 2*b + 2*c,
            2*a + b + 2*c,
            2*a + 2*b + 3*c
        ],[
            a - 2*b + 2*c,
            2*a - b + 2*c,
            2*a - 2*b + 3*c
        ]], [[
            2*a + b - c,
            -2*a + 2*b + 2*c,
            -2*a + b + 3*c
        ],[
            2*a + b + c,
            2*a - 2*b + 2*c,
            2*a - b + 3*c
        ],[
            2*a - b + c,
            2*a + 2*b + 2*c,
            2*a + b + 3*c
        ]]];
    }
    var gen = function(root){        
        var clone= [[[
          abc(root[0][0][0][0], root[0][0][0][1], root[0][0][0][2]),
            abc(root[0][0][1][0], root[0][0][1][1], root[0][0][1][2]),
            abc(root[0][0][2][0], root[0][0][2][1], root[0][0][2][2]),
            abc(root[0][0][3][0], root[0][0][3][1], root[0][0][3][2])
        ], [
          abc(root[0][1][0][0], root[0][1][0][1], root[0][1][0][2]),
            abc(root[0][1][1][0], root[0][1][1][1], root[0][1][1][2]),
            abc(root[0][1][2][0], root[0][1][2][1], root[0][1][2][2]),
            abc(root[0][1][3][0], root[0][1][3][1], root[0][1][3][2])
        ]], [[
          abc(root[1][0][0][0], root[1][0][0][1], root[1][0][0][2]),
            abc(root[1][0][1][0], root[1][0][1][1], root[1][0][1][2]),
            abc(root[1][0][2][0], root[1][0][2][1], root[1][0][2][2]),
            abc(root[1][0][3][0], root[1][0][3][1], root[1][0][3][2])
        ], [
          abc(root[1][1][0][0], root[1][1][0][1], root[1][1][0][2]),
            abc(root[1][1][1][0], root[1][1][1][1], root[1][1][1][2]),
            abc(root[1][1][2][0], root[1][1][2][1], root[1][1][2][2]),
            abc(root[1][1][3][0], root[1][1][3][1], root[1][1][3][2])
        ]]];
        clone.path = function(odd,ab, quadrant, prime, turn, side){
            console.log(clone[odd][ab][quadrant][prime][turn][side]);
        }
        return clone;
    }
    var time = function(i){
        var private = symMatrix(alg(i));
        var public = gen(private);
        return {
            private : private,
            public: public
        }
    }
    
    var space = function(context, time){
        context.beginPath();
        context.moveTo(time.private[0][0][0], time.private[0][0][1]);
        var odd = [].concat(time.public);
        var counter = 0, atom=[];
        while(odd.length){
            var ab = [].concat(odd.shift());
            while(ab.length){
                var quadrant = [].concat(ab.shift());
                while(quadrant.length){                    
                    var prime = [].concat(quadrant.shift());
                    var abc = [].concat(time.private[odd.length][ab.length][quadrant.length]);
                    atom.push(
                    {
                        odd: odd.length,
                        ab: ab.length,
                        quadrant: quadrant.length,
                        a: abc[0],
                        b: abc[1],
                        c: abc[2],
                        xy: function(x, y){
                            return [x+this.a, y+this.b, this.c];
                        }
                    });
                    while(prime.length){
                        var turn = [].concat(prime.shift());
                        while(turn.length){
                            abc = [].concat(turn.shift());
                            atom.push(
                                {
                                    odd: odd.length,
                                    ab: ab.length,
                                    quadrant: quadrant.length,
                                    time: prime.length,
                                    turn: turn.length,
                                    a: abc[0],
                                    b: abc[1],
                                    c: abc[2],
                                    xy: function(x, y){
                                        return [x+this.a, y+this.b, this.c];
                                    }
                                });
                        }
                    }
                }
            }
        }
        return atom;   
    }
    
    var canvas = document.createElement("canvas");
    var origin = [window.innerWidth/2, window.innerHeight/2];
    canvas.width = window.innerWidth;
    canvas.height=window.innerHeight;
    var context = canvas.getContext("2d");
    
    var pointEvent = document.createEvent("Event"), collisionPoint = document.createEvent("Event");
    pointEvent.initEvent("point", true, true), collisionPoint.initEvent("collision");
    var history = [[],[]];    
    var spawn = [];
    var collision = function(index, point){
        history[1][index].push(point);
        spawn.push(function(){console.log('tick');tick(point, point.x, point.y)});
    }
    var pixel = function(point){
        history[0].push(point.id), history[1].push([point]);
        context.rect(point.x, point.y, 1, 1);
        context.stroke();
    }
    var atomic = function(event){
        event.point.id = event.point.x + "," + event.point.y;
        var index = history[0].indexOf(event.point.id);
        (index>-1) ? collision(index, event.point) : pixel(event.point);
    }
    var tick = function(local, x, y){
        var spot = local.xy(x, y);
        local.x = spot[0];
        local.y = spot[1];
        pointEvent.point = local;
        document.dispatchEvent(pointEvent);
    }
    
    document.addEventListener("point", atomic, true);
    
    window.addEventListener("load", function(event){
        document.body.appendChild(canvas);
        var root = 0;
        var less = root-10, more = root+10, data, atom, matrix=[];
        while(less<more){
            data = time(less);
            matrix.push(space(context, data));
            less++;
        }
        
        document.addEventListener("mouseup", function(event){
            var exwall = [].concat(matrix), wall, x=event.clientX, y=event.clientY;
            console.log(event);
            while(exwall.length){
                wall = [].concat(exwall.shift());
                while(wall.length){
                    tick(wall.shift(), x, y);
                }
            }
            var thread = window.setInterval(function(){
                if(spawn.length){
                    console.log("go");
                    while(spawn.length){
                        spawn.shift()();
                    }
                } else {
                    console.log("stop");
                    window.clearInterval(thread);
                }
            }, 30);
       }, true);
        
    });
})();

Comments