// Maze Blur 01 // David Bollinger // http://www.davebollinger.com // for Processing 0109 Beta /** Press 'p' to toggle the maze path overlay
Press 'r' to toggle the path retrace visibility
Click to advance early to next set of random parameters
*/ static int [] dxs = {1,0,-1,0}; static int [] dys = {0,-1,0,1}; Grid grid; Vector walkers; PImage texture; float turnLikelihood; float spawnLikelihood; float mixingRatio; int currentseed = 1; int nextwait = 0; boolean bHideRetrace = true; boolean bOverlayPath = false; void setup() { size(300,300); grid = new Grid(width, height, 1); texture = loadImage("duck300.jpg"); framerate(30); walkers = new Vector(1000); next(); } void draw() { if (nextwait > 0) { if (--nextwait <= 0) next(); else return; } for (int i=0, sz=walkers.size(); i0.5) ? (olddir+1)%4 : (olddir+3)%4; } void spawn(int x, int y, int d) { walkers.add( new Walker(x, y, d) ); grid.occupy(x,y); } void spawn(int x, int y, int d, color c) { walkers.add( new Walker(x, y, d, c) ); grid.occupy(x,y); } color blend(color c1, color c2, float t) { t = min(max(t,0),1.0); float r1 = red(c1), g1 = green(c1), b1 = blue(c1); float r2 = red(c2), g2 = green(c2), b2 = blue(c2); return color( r1+t*(r2-r1), g1+t*(g2-g1), b1+t*(b2-b1) ); } class Walker { int x, y, ox, oy, dir; color c; Walker(int _x, int _y, int _d) { this(_x, _y, _d, texture.get(_x*grid.rez+grid.rez/2, _y*grid.rez+grid.rez/2) ); } Walker(int _x, int _y, int _d, color _c) { ox = x = _x; oy = y = _y; dir = _d; c = _c; } void move() { // spawn a child? if (random(1.0) < spawnLikelihood) { int pd = perpdir(dir); if (grid.isEmpty(x+dxs[pd], y+dys[pd])) spawn(x, y, pd, c); } // change direction at random? boolean redir = (random(1.0) < turnLikelihood); if (redir) dir = randdir(dir); // calc new position, check if stuck int newx = x + dxs[dir]; int newy = y + dys[dir]; boolean stuck = grid.isSolid(newx,newy); // if stuck try to jump onto a prior track if (stuck) { dir = randdir(dir); // for next pass if (grid.isValidCoords(newx,newy)) { // "jump" to those coordinates ox = x = newx; oy = y = newy; return; } } else { if ((x!=newx) || (y!=newy)) { // "walk" to new coordinates ox = x; oy = y; x = newx; y = newy; grid.occupy(x,y); } } } void draw(boolean bHideRetrace, boolean bOverlayPath) { if ((bHideRetrace) && (x==ox) && (y==oy)) return; color newc = texture.get(x*grid.rez+grid.rez/2, y*grid.rez+grid.rez/2); c = blend(c, newc, mixingRatio); fill(c); noStroke(); rect(x*grid.rez, y*grid.rez, grid.rez, grid.rez); if (bOverlayPath) { stroke(#ffffff); line(ox*grid.rez+grid.rez/2, oy*grid.rez+grid.rez/2, x*grid.rez+grid.rez/2, y*grid.rez+grid.rez/2); } } } class Grid { static final int EMPTY = 0; static final int SOLID = 1; int [][] grid; int wid, hei; int rows, cols, rez; int cellcount, solidcount; Grid(int w, int h, int r) { wid = w; hei = h; setRez(r); grid = new int[hei][wid]; wipe(); } void setRez(int r) { rez = r; cols = wid / rez; rows = hei / rez; cellcount = rows * cols; } void wipe() { for (int r=0; r=0) && (r>=0) && (c=cellcount); } void set(int c, int r, int v) { if (isValidCoords(c,r)) { if ((grid[r][c]==SOLID) && (v==EMPTY)) solidcount--; if ((grid[r][c]==EMPTY) && (v==SOLID)) solidcount++; grid[r][c] = v; } } int get(int c, int r) { if (isValidCoords(c,r)) return grid[r][c]; else return SOLID; } boolean isEmpty(int c, int r) { return (this.get(c,r) == EMPTY); } boolean isSolid(int c, int r) { return (this.get(c,r) == SOLID); } void occupy(int c, int r) { this.set(c, r, SOLID); } }