// // name: curved_substrate.pde // // desc: several changes were made to the substrate watercolor experiment // created by jared tarbell; i wanted to rework the substrate using // curved lines. several other changes (colors, line distribution, etc) // were introduced, search for 'kiddphunk' to see changed sections. // // info: bugs, blame and beratement -> <- // // => www.kiddphunk.com/experiments/ // // => code augmented from original source, 'substrate.pde' : // // Substrate Watercolor // j.tarbell June, 2004 // Albuquerque, New Mexico // complexification.net // // remember: andre the giant has a posse. // // todo: * nap // /////////////////////////////////////////////////////////////////////////////// int dimx = 750; int dimy = 300; int num = 0; // kiddphunk change: lower maxnum, no lines, several modes of rendering- // play with render_type int maxnum = 25; int render_type = 7; //int(random(1, 7)); boolean nolines = false; // grid of cracks int[] cgrid; Crack[] cracks; // color parameters int curr_count = 0; int maxpal = 512; // kiddphunk change: start growth in one quadrant float growth_times = 3; int quadrant = int(random(1, 5)); // kiddphunk change: single color optional shading color singlecolor, singlecolor2; boolean use_singlecolor = false; boolean use_dualcolor = false; // kiddphunk change: 3 separate palettes color[] goodcolor; color[] goodcolor1 = new color[maxpal]; color[] goodcolor2 = new color[maxpal]; color[] goodcolor3 = new color[maxpal]; int numpal = 0; int numpal1 = 0; int numpal2 = 0; int numpal3 = 0; // sand painters SandPainter[] sands; // MAIN METHODS --------------------------------------------- void setup() { //kiddphunk change: resize dimentions setRenderType(); size(dimx,dimy); background(255); // kiddphunk change: load 3 palettes int r = int(random(100)); if (r < 20) { goodcolor1 = takecolor("lmpalette.gif", 1); goodcolor2 = takecolor("lmpalette.gif", 2); goodcolor3 = takecolor("lmpalette.gif", 3); } else if (r < 60) { goodcolor1 = takecolor("color2.gif", 1); goodcolor2 = takecolor("color1.gif", 2); goodcolor3 = takecolor("color1.gif", 3); } else { goodcolor1 = takecolor("fractal1.gif", 1); goodcolor2 = takecolor("fractal2.gif", 2); goodcolor3 = takecolor("fractal1.gif", 3); } println("using color palette r: "+r); goodcolor = goodcolor1; numpal = numpal1; background(255); quadrant = int(random(1, 5)); cgrid = new int[dimx*dimy]; cracks = new Crack[maxnum]; begin(false); } void loop() { // kiddphunk addition: change up the palette periodically if (++curr_count % 20 == 0) { int subcount = 1+curr_count % 3; switch (subcount) { case 1: goodcolor = goodcolor1; numpal = numpal1; break; case 2: goodcolor = goodcolor2; numpal = numpal2; break; case 3: goodcolor = goodcolor3; numpal = numpal3; break; } } // crack all cracks for (int n=0;n=0) && (x1=0) && (y1=1.0) { stroke(myc); point(x1,y1); } else { int r, g, b; color c; c = get(x1, y1); r = int(red(c) + (red(myc) - red(c)) * a); g = int(green(c) +(green(myc) - green(c)) * a); b = int(blue(c) + (blue(myc) - blue(c)) * a); color nc = color(r, g, b); stroke(nc); point(x1,y1); } } } // OBJECTS ------------------------------------------------------- class Crack { float x, y; float t; // direction of travel in degrees // sand painter SandPainter sp; Crack() { // find placement along existing crack findStart(); sp = new SandPainter(); // kiddphunk addition: support for dual color shading if (use_singlecolor || use_dualcolor) { sp.c = singlecolor; } if (use_dualcolor) { if (int(random(1, 100)) < 55) { sp.c = singlecolor2; } } } void findStart() { // pick random point int px=0; int py=0; // shift until crack is found boolean found=false; int timeout = 0; while ((!found) || (timeout++>1000)) { // kiddphunk change: make 'clump' for more variation boolean cont = (random(1, 100) > 50) ? true : false; for (int a=0; a dimy/2); break; case 3: cont = (px > dimx/2 && py < dimy/2); break; case 4: cont = (px > dimx/2 && py > dimy/2); break; } } if (cgrid[py*dimx+px]<10000) { found=true; } } if (found) { // start crack int a = cgrid[py*dimx+px]; if (random(100)<50) { a-=90+int(random(-2,2.1)); } else { a+=90+int(random(-2,2.1)); } startCrack(px,py,a); } else { //println("timeout: "+timeout); } } void startCrack(int X, int Y, int T) { x=X; y=Y; t=T;//%360; x+=0.61*cos(t*PI/180); y+=0.61*sin(t*PI/180); } void move() { // continue cracking // kiddphunk change: algorithm change to utilize a position-based curve instead of a line // x+=y/100*0.42*cos(t*PI/180); // y+=x/100*0.42*sin(t*PI/180); x+=y/100*0.42*cos(t*PI/180); y+=x/100*0.42*sin(t*PI/180); // bound check float z = 0.33; int cx = int(x+random(-z,z)); // add fuzz int cy = int(y+random(-z,z)); // draw sand painter regionColor(); // kiddphunk change: made wider and more translucent // draw black crack if (!nolines) { tpoint(cx,cy,#000000,0.4); tpoint(cx+1,cy,#000000,0.1); tpoint(cx,cy+1,#000000,0.1); tpoint(cx+1,cy+1,#000000,0.1); } if ((cx>=0) && (cx=0) && (cy10000) || (abs(cgrid[cy*dimx+cx]-t)<5)) { // continue cracking cgrid[cy*dimx+cx]=int(t); } else if (abs(cgrid[cy*dimx+cx]-t)>2) { // crack encountered (not self), stop cracking findStart(); makeCrack(); } } else { // out of bounds, stop cracking findStart(); makeCrack(); } } void regionColor() { // start checking one step away float rx=x; float ry=y; boolean openspace=true; // find extents of open space while (openspace) { // move perpendicular to crack rx+=0.81*sin(t*PI/180); ry-=0.81*cos(t*PI/180); int cx = int(rx); int cy = int(ry); if ((cx>=0) && (cx=0) && (cy10000) { // space is open } else { openspace=false; } } else { openspace=false; } } // kiddphunk addition: use single color gradient color c = sp.c; if (use_singlecolor || use_dualcolor) { // c = singlecolor; int r = int(red(c)) - int(rx/16) - int(ry/16); int g = int(green(c)) - int(rx/16) - int(ry/16); int b = int(blue(c)) - int(rx/16) - int(ry/16); c = color(r, g, b); } // draw sand painter sp.render(rx,ry,x,y,c); } } class SandPainter { float p; public color c; float g; SandPainter() { p = 0.0; c = somecolor(); g = random(0.01,0.1); } // kiddphunk addition: added color pass to render for x-y color change void render(float x, float y, float ox, float oy, color c) { // modulate gain g+=random(-0.050,0.050); float maxg = 1.0; if (g<0) g=0; if (g>maxg) g=maxg; // calculate grains by distance //int grains = int(sqrt((ox-x)*(ox-x)+(oy-y)*(oy-y))); int grains = 64; // lay down grains of sand (transparent pixels) float w = g/(grains-1); for (int i=0;i