Recently I've been looking at Povray, pyprocessing, and cfdg (version 3.0) as tools for creating digital images. I have branched two separate blogs where I mainly explore jruby + processing and processing.py

Thursday, 1 October 2009

Menger Sponge Revisited

Tom Carden produced an amazing Menger Sponge for processing alpha, somewhat inspired by Tom's sponge I've created an Object Orientated version, that does not need the elegant (if somewhat complicated) loop branching of Tom's version. In this version the cube data is stored as an ArrayList during setup, and is only rendered in the draw loop. The depth of recursion is managed by setting a minimum size for the inner cubes.

Here is the Sponge class.
// Sponge.pde by Martin Prout
class Sponge{
  int MIN_SIZE = 40; // 33 is a practical lower limit
  ArrayList cubeData;

  Sponge(float sz){
    cubeData = new ArrayList();
    fillCubeData(0, 0, 0, sz);
  }

  void fillCubeData(float x,float y,float z, float sz){
    float u = sz/3;
    if (sz < MIN_SIZE){ // recursion limited by minimum cube size
      float[] data = {x, y, z, sz};
      cubeData.add(data);
    }
    else{
      for (int i = -1; i <= 1; i++){
        for (int j = -1; j <= 1; j++){
          for (int k = -1; k <= 1; k++){
            if ((abs(i) + abs(j)+abs(k)) != 1 ) {
              fillCubeData(x + (i * u), y + (j * u), z + (k * u), u);
            }
          }
        }
      }
    }
  }

  void render(){
    float[] data;
    for (int i = 0; i < cubeData.size(); i++){
      data = (float[])cubeData.get(i); // cast back object to float array
      noStroke();
      pushMatrix();
      translate(data[0], data[1], data[2]);
      myBox(data[3]);
      popMatrix();
    }    
  }
}
void myBox(float sz){
      beginShape(QUADS);   
      fill(0, 0, 240); // blue  
      vertex(-sz/2,  sz/2,  sz/2); 
      vertex( sz/2,  sz/2,  sz/2); 
      vertex( sz/2, -sz/2,  sz/2); 
      vertex(-sz/2, -sz/2,  sz/2); 
      // still blue
      vertex( sz/2,  sz/2, -sz/2); 
      vertex(-sz/2,  sz/2, -sz/2); 
      vertex(-sz/2, -sz/2, -sz/2); 
      vertex( sz/2, -sz/2, -sz/2); 
      fill(240, 0, 0); // red
      vertex(-sz/2,  sz/2, -sz/2); 
      vertex(-sz/2,  sz/2,  sz/2); 
      vertex(-sz/2, -sz/2,  sz/2); 
      vertex(-sz/2, -sz/2, -sz/2); 
      // still red
      vertex( sz/2,  sz/2,  sz/2); 
      vertex( sz/2,  sz/2, -sz/2); 
      vertex( sz/2, -sz/2, -sz/2); 
      vertex( sz/2, -sz/2,  sz/2); 
      fill(0, 240, 0); // green
      vertex(-sz/2, -sz/2, -sz/2); 
      vertex( sz/2, -sz/2, -sz/2); 
      vertex( sz/2, -sz/2,  sz/2); 
      vertex(-sz/2, -sz/2,  sz/2); 
      // still green
      vertex(-sz/2,  sz/2, -sz/2); 
      vertex( sz/2,  sz/2, -sz/2); 
      vertex( sz/2,  sz/2,  sz/2); 
      vertex(-sz/2,  sz/2,  sz/2); 
      endShape();
    }

Here is the processing sketch that uses the Sponge class.

// menger.pde by Martin Prout
import processing.opengl.*;

float angle = 0.0;
float angleStep = PI/180.0;

Sponge sponge;
void setup(){
  size(600, 600, OPENGL);
  sponge = new Sponge(width/2);
  frameRate(60);
}

void draw(){
  background(0); 
  ambientLight( 150, 150, 150 );
  directionalLight( 220, 220, 220, -1, 1, 1);
  // set the cube spinning
  angle = (angle + angleStep) % TWO_PI;
  translate(width/2, height/2);
  rotateX(angle);
  rotateY(angle);
  rotateZ(angle);
  sponge.render();
}
 


I deleted my earlier blog entry which was mainly an updated version of Tom Cardens sponge, so the comments went with it. I just found this link which has got some amazing 3D shapes from a similar mould and even more here.

Over on my ruby processing blog I have created both a fake Menger sponge (the code is a lot less scary and there are many more squares on the cube faces), and a ruby-processing version of this sketch.

No comments:

Post a Comment

Followers

Blog Archive

About Me

My photo
Pembrokeshire, United Kingdom
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2