// Fungi02 // David Bollinger, July 2006 // http://www.davebollinger.com // for Processing 0015 Beta // /** Fungi #02
(minor variant of Fungi 01 with motion blur)
Click to advance to next set of coefficients. */ // the drawing buffer FixedPointBuffer buf; // screen origin and coordinate scaler float ctrx, ctry, scaler; // current z float z; // current random number seed to generate coef's int currentseed = 0; // number of control points int ncps = 100; // number of iterations per control point int niters = 1000; // coefficients float a, b, c, d, e, f; // color values, as used by the fixed point buffer int myred, mygrn, myblu; float myalf; void setup() { size (480, 480, P3D); buf = new FixedPointBuffer(width,height); ctrx = width / 2.0; ctry = height / 2.0; scaler = width / 5.0; framerate(30); myred = (255) << buf.shift; mygrn = (255/3) << buf.shift; myblu = (255/3/3) << buf.shift; myalf = 0.3; next(); } void next() { randomSeed(currentseed++); a = random(-4.0,4.0); b = random(-4.0,4.0); c = random(-4.0,4.0); d = random(-4.0,4.0); e = random(-4.0,4.0); f = random(-4.0,4.0); z = 0.0; buf.background(0,0,0); } int nframes = 0; void keyPressed() { if (key=='`') saveFrame("frame"+nframes+".tga"); nframes++; } void mousePressed() { next(); } void draw() { z += 0.001; buf.fade(); // for each of the many control points... for (int i=ncps; i>0; i--) { float x = random(-1.0,1.0); float y = random(-1.0,1.0); // for each step along the control point's journey... for (int j=niters; j>0; j--) { // some type of 2.5D or 3D function here: // (2.5D in this case, for performance reasons) float xp = sin(a*y) + sin(b*x) + sin(c*z); float yp = sin(d*x) + sin(e*y) + sin(f*z); x = xp; y = yp; buf.add(ctrx+x*scaler, ctry+y*scaler, myred, mygrn, myblu, myalf); } } buf.render(); } // an 8.16 fixed point rgb buffer with sub-pixel sampling // (the extra precision is used to reduce rounding errors during accumulation) class FixedPointBuffer { static final int shift = 16; // number of .fixed bits static final int fixone = 1<>= 1; grnbuf[idx] >>= 1; blubuf[idx] >>= 1; so scale by 3/4 instead... */ redbuf[idx] = (redbuf[idx]*3)>>2; grnbuf[idx] = (grnbuf[idx]*3)>>2; blubuf[idx] = (blubuf[idx]*3)>>2; } } // plot additively void add(float x, float y, int r, int g, int b, float alf) { // convert to continuous coordinates x -= 0.5; y -= 0.5; // bounds check if ((x<0.0) || (y<0.0) || (x>=wid-1.0) || (y>=hei-1.0)) return; // integral coordinates int ix1 = (int)(x); int iy1 = (int)(y); int ix2 = ix1 + 1; int iy2 = iy1 + 1; // fractional coordinates float fractx = x - (float)(ix1); float fracty = y - (float)(iy1); // reciprocal of fractional coordinates float recipx = 1.0 - fractx; float recipy = 1.0 - fracty; // preconvert color values to floats float fr = (float)(r); float fg = (float)(g); float fb = (float)(b); // plot it float ratio; int idx, c; // upper-left ratio = recipx * recipy * alf; idx = iy1 * width + ix1; c = (int)((ratio*fr) + redbuf[idx]); if (c>maxrgb) c=maxrgb; redbuf[idx] = c; c = (int)((ratio*fg) + grnbuf[idx]); if (c>maxrgb) c=maxrgb; grnbuf[idx] = c; c = (int)((ratio*fb) + blubuf[idx]); if (c>maxrgb) c=maxrgb; blubuf[idx] = c; // upper-right ratio = fractx * recipy * alf; idx = iy1 * width + ix2; c = (int)((ratio*fr) + redbuf[idx]); if (c>maxrgb) c=maxrgb; redbuf[idx] = c; c = (int)((ratio*fg) + grnbuf[idx]); if (c>maxrgb) c=maxrgb; grnbuf[idx] = c; c = (int)((ratio*fb) + blubuf[idx]); if (c>maxrgb) c=maxrgb; blubuf[idx] = c; // lower-left ratio = recipx * fracty * alf; idx = iy2 * width + ix1; c = (int)((ratio*fr) + redbuf[idx]); if (c>maxrgb) c=maxrgb; redbuf[idx] = c; c = (int)((ratio*fg) + grnbuf[idx]); if (c>maxrgb) c=maxrgb; grnbuf[idx] = c; c = (int)((ratio*fb) + blubuf[idx]); if (c>maxrgb) c=maxrgb; blubuf[idx] = c; // lower-right ratio = fractx * fracty * alf; idx = iy2 * width + ix2; c = (int)((ratio*fr) + redbuf[idx]); if (c>maxrgb) c=maxrgb; redbuf[idx] = c; c = (int)((ratio*fg) + grnbuf[idx]); if (c>maxrgb) c=maxrgb; grnbuf[idx] = c; c = (int)((ratio*fb) + blubuf[idx]); if (c>maxrgb) c=maxrgb; blubuf[idx] = c; } // render converts 8.shift format back down to 8 bit rgb void render() { for (int idx=area-1; idx>=0; idx--) { /* // general-purpose conversion for any shift... int r = ((redbuf[idx] >> shift) & 0xFF) << 16; int g = ((grnbuf[idx] >> shift) & 0xFF) << 8; int b = ((blubuf[idx] >> shift) & 0xFF); pixels[idx] = 0xFF000000 | r | g | b; */ // optimized for shift of 16 pixels[idx] = 0xFF000000 | (redbuf[idx] & 0xFF0000) | ((grnbuf[idx] & 0xFF0000) >> 8) | ((blubuf[idx] & 0xFF0000) >> 16); } updatePixels(); } }