// Structurally Open // By Ethan Miller 2005 // http://dma.sjsu.edu/~emiller/ // eth_anton@yahoo.com Vector nodes; int drift_factor = 3; int drift_variance = 2; double colorRange = 40; boolean newFrame = false; BImage bg; boolean bg_set = false; boolean show_bg = false; boolean all_still = false; void setup(){ size(320, 240); background(50); beginVideo(320, 240, 16); framerate(16); nodes = new Vector(2000); noStroke(); initNodes(); smooth(); } void initNodes(){ float ang = 0.0; float dist = 1.5; float anginc = 0.26; float distinc = 0.06; float pi_denom = 0.99; int c = 0; for(int i = 0; i < 3500; i++){ ang += anginc % 360; dist += distinc; float xpt = (cos(PI/pi_denom*ang)*dist) + width/2; float ypt = (sin(PI/pi_denom*ang)*dist) + height/2; if(xpt < 55 || xpt > 265 || ypt < -20 || ypt > 245) continue; nodes.addElement(new node(xpt, ypt)); c++; } println(c); } public void videoEvent(){ newFrame = true; } void mouseReleased(){ bg = video.copy(); bg_set = true; } void keyReleased(){ if(key == 's') show_bg = !show_bg; } void loop(){ if(!newFrame) return; if(bg_set){ image(bg, 0, 0); if(show_bg) return; }else{ background(0); } node n; for (Enumeration e = nodes.elements(); e.hasMoreElements();){ n = (node)e.nextElement(); n.drawnode(); } //fill(0); //rect(0,0, 60, 240); //rect(260, 0, 60, 240); } private class node{ public float x, y; private float origx, origy; private color c, lastc; private float df; private int[][] color_span; private int col_count = 10; private int col_at = 0; public node(float xpos, float ypos){ x = xpos; y = ypos; origx = xpos; origy = ypos; c = color(0, 0, 0); lastc = c; df = drift_factor + random(-drift_variance, drift_variance); color_span = new int[col_count][3]; for(int i = 0; i < col_count; i++){ color_span[i][0] = 0; color_span[i][1] = 0; color_span[i][2] = 0; } } public void drawnode(){ if(x < 55 || x > 265){ driftBack(); return; } int imgIndex = int(origy)*width + int(origx); try{ c = video.pixels[imgIndex]; if(!areColorsSimilar(c, lastc)) placeRand(); addColor(c); fill(avgColor()); }catch(ArrayIndexOutOfBoundsException e){ c = color(0,0,0); } float d = dist(x,y,width/2, height/2); float sz = d*0.05 + 1.5; ellipse(x, y, sz, sz); driftBack(); lastc = c; } private void addColor(color c){ color_span[col_at][0] = int(red(c)); color_span[col_at][1] = int(green(c)); color_span[col_at][2] = int(blue(c)); col_at++; col_at %= col_count; } private color avgColor(){ int r = 0; int g = 0; int b = 0; for(int i = 0; i < col_count; i++){ r += color_span[i][0]; g += color_span[i][1]; b += color_span[i][2]; } return color(r/col_count, g/col_count, b/col_count); } private void placeRand(){ x = random(width); y = random(height); } private void driftBack(){ float xdiff = origx - x; float ydiff = origy - y; if(xdiff == 0 && ydiff == 0) return; if(abs(xdiff) > .05){ x += xdiff/df; }else{ x = origx; } if(abs(ydiff) > .05){ y += ydiff/df; }else{ y = origy; } } } boolean areColorsSimilar(color a, color b){ boolean reds = abs(red(a) - red(b)) <= colorRange; boolean greens = abs(green(a) - green(b)) <= colorRange; boolean blues = abs(blue(a) - blue(b)) <= colorRange; return reds && greens && blues; }