// Spyrofoam // Dave Bollinger, Oct 2006 // http://www.davebollinger.com // rewritten for Processing Beta 0119 /** Press spacebar to generate new attractor

Quality Mode:
   1: render with points (aka "explore" mode) (default)
   2: render with rectangles (aka "billboard" mode)
   3: render with boxes (aka "draft" mode)
   4: render with spheres (aka "final" mode)
   fast CPU recommended for modes 3 & 4
   '[' ']' decrease/increase sphere radius

Camera:
   drag mouse to rotate
   arrow keys to pan
   +/- keys to zoom
   'x' resets camera to default

NOTE: most changes in settings will erase
the screen and restart the accumulation.

*/ IfsSystem ifs; static final int rmPOINTS = 0; static final int rmRECTS = 1; static final int rmBOXES = 2; static final int rmSPHERES = 3; int renderMode = rmPOINTS; float sphereSize = 4.0; float rotationX, rotationY; float cameraX, cameraY, cameraZ; int mouseDownX, mouseDownY; boolean bNeedErase = false; void setup() { size(300, 300, P3D); sphereDetail(8); ifs = new IfsSystem(6); next(); } void next() { do { ifs.create(); } while (!ifs.valid()); cameraReset(); } void draw() { if (bNeedErase) { background(#ffffff); bNeedErase = false; } colorMode(RGB); directionalLight(255,255,255, 0.5,0.5,-0.5); pointLight(255,255,255, 0,0,0); translate(width/2+cameraX, height/2+cameraY, cameraZ); scale(width/ifs.ex.width); rotateX(rotationX); rotateY(rotationY); colorMode(HSB); ifs.iterate(10,200,1000); } void keyPressed() { if (key==' ') next(); if (key=='1') setQuality(rmPOINTS); if (key=='2') setQuality(rmRECTS); if (key=='3') setQuality(rmBOXES); if (key=='4') setQuality(rmSPHERES); if (key=='[') sphereResize(-0.5); if (key==']') sphereResize(0.5); if (keyCode==LEFT) cameraMove(5,0,0); if (keyCode==RIGHT) cameraMove(-5,0,0); if (keyCode==UP) cameraMove(0,5,0); if (keyCode==DOWN) cameraMove(0,-5,0); if (key=='+') cameraMove(0,0,5); if (key=='-') cameraMove(0,0,-5); if (key=='x') cameraReset(); } void mouseDragged() { float rx = (mouseDownY-mouseY) / float(height) * TWO_PI; float ry = (mouseX-mouseDownX) / float(width) * TWO_PI; rotationX += (rx - rotationX) * 0.1; rotationY += (ry - rotationY) * 0.1; bNeedErase = true; } void mousePressed() { mouseDownX = mouseX; mouseDownY = mouseY; } // cheap pseudo-camera support void cameraReset() { cameraX = cameraY = 0.0; cameraZ = ifs.ex.minz - 200.0; rotationX = rotationY = 0.0; bNeedErase = true; } void cameraMove(float dx, float dy, float dz) { cameraX += dx; cameraY += dy; cameraZ += dz; bNeedErase = true; } void sphereResize(float ds) { sphereSize += ds; sphereSize = min(max(sphereSize,1.0),20.0); bNeedErase = true; } void setQuality(int q) { renderMode = q; bNeedErase = true; }