var con = console; var maxIterations = 1000; var iterations = 0; var runs = 0; var testSize = 12; var padding = testSize / 2; var gridSize = 60; var maxPaths = 13000;//gridSize * 4;// 500; // bails at maxPaths attempts... usually almost fills the space, leaving a few pleasant gaps var px = gridSize / 2; var py = 0; var direction = 2; var canvas = document.getElementById("2d"); canvas.width = canvas.height = gridSize * testSize; var shape = canvas.getContext("2d"); // var out = document.getElementById("out"); var currentPath = -1; // var paths = []; var path; var grid = []; for (var i = 0; i < gridSize; i++) { grid[i] = []; for (var j = 0; j < gridSize; j++) { grid[i][j] = 0; } } function drawLayer() { for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { shape.fillStyle = "rgba(0,0,0,0.1)"; shape.fillRect(x * testSize + 1, y * testSize + 1, testSize - 2, testSize - 2); } } } drawLayer() function drawPath(path) { // if (path.length == 1) return; // draw single dots??? var colour = ~~((currentPath * 10) % maxPaths / maxPaths * 360); shape.beginPath(); // shape.strokeStyle = "hsla(" + colour + ",100%,60%,1)"; // shape.strokeStyle = "hsla(" + colour + ",100%,60%,1)"; var brightness = 60 + ~~(Math.random() * 20); if(Math.random() > 0.95) brightness = 100; // draw an occasional bright mutant shape.strokeStyle = "hsla(0,0%," + brightness + "%,1)"; shape.lineWidth = 2; for ( var i = 0, il = path.length; i < il; i++) { var node = path[i], x = node[0] * testSize + padding, y = node[1] * testSize + padding; if (i == 0) { shape.moveTo(x, y); } else { shape.lineTo(x, y); } } shape.stroke(); for ( var i = 0, il = path.length; i < il; i++) { var node = path[i], x = node[0] * testSize + padding, y = node[1] * testSize + padding; shape.beginPath(); shape.arc(x, y, padding / 2, 0, 2 * Math.PI, false); // shape.fillStyle = "hsla(" + colour + ",50%,50%,1)"; shape.fillStyle = "hsla(0,0%," + brightness + "%,1)"; shape.fill(); shape.closePath(); shape.beginPath(); shape.arc(x, y, padding / 2 - 2, 0, 2 * Math.PI, false); shape.fillStyle = "#666"; shape.fill(); shape.closePath(); } } function pointValid(x, y) { return grid[y] != undefined && grid[y][x] != undefined; } function pointFree(x, y) { return pointValid(x, y) && grid[y][x] != 1; } function getNextPoint(x, y) { var newX = x, newY = y, newDir = Math.floor(Math.random() * 3) - 1; var dir = (4 + direction + newDir) % 4; // make sure dir is not backwards. direction = dir; switch (dir) { case 0: newY--; break; // up case 1: newX++; break; // right case 2: newY++; break; // down case 3: newX--; break; // left } var valid = pointValid(newX, newY); // con.log(taken, newX, newY) if (valid) { if (pointFree(newX, newY)) { return { x:newX, y:newY, direction: dir, complete: false } } else { return { x:newX, y:newY, direction: dir, complete: true } } } else { return getNextPoint(x, y); // try again, with original point. } } function calcSection() { var nextPoint = getNextPoint(px,py) if (nextPoint.complete === true) { drawPath(path); if (currentPath < maxPaths) { // newPath(); setTimeout( function() { newPath() }, 10); } } else { px = nextPoint.x; py = nextPoint.y; // con.log('nextPoint', px, py) grid[py][px] = 1; path.push([px,py]); // paths[currentPath] = path; iterations++; // drawPath(path); if (iterations < maxIterations ) { // setTimeout( function() { calcSection() }, 30); calcSection(); } else { con.log("iterations reached", iterations, maxIterations); } // if (iterations < 60 ) calcSection(); } } var startPositions = gridSize * 4; var start = []; for ( var i = 0; i < startPositions; i++ ) { start[i] = i; } function newStart() { if ( currentPath < gridSize * 4 ) { // do a lap around around the edges first... var startIndex = start[ ~~(Math.random() * start.length) ]; // con.log( start); // con.log(startIndex); start.splice(startIndex, 1); // con.log( start); startIndex = currentPath; px = 0; py = 0; var edge = Math.floor(startIndex / gridSize); var remain = startIndex % gridSize; switch (edge) { case 0: // top px = startIndex; py = 0; direction = 2; break; case 1: // right px = gridSize - 1; py = remain; direction = 3; break; case 2: // bottom px = gridSize - remain; py = gridSize - 1; direction = 0; break; case 3: // left px = 0; py = gridSize - remain; direction = 1; break; } /* px = 0 + ~~(Math.random() * (gridSize - 1)); py = 0 + ~~(Math.random() * (gridSize - 1)); var edge = Math.round(Math.random() * 4); con.log("edge", edge); switch (edge) { case 0: py = 0; break; // top case 1: px = gridSize - 1; break; // right case 2: py = gridSize - 1; break; // bottom case 3: px = 0; break; // left } */ } else { px = ~~(Math.random() * (gridSize - 1)); py = ~~(Math.random() * (gridSize - 1)); direction = ~~(Math.random() * 4); } if (!pointFree(px, py) && iterations < maxIterations) { currentPath++; iterations++; // con.log("finding new start!!!"); newStart(); } } function newPath() { currentPath++; newStart(); iterations = 0; path = []; path.push([px,py]); grid[py][px] = 1; calcSection(); } newPath();