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

Wednesday, 21 December 2011

Menger Sponge Example

Here is an example sketch that shows how to adjust the position and size of the processing elements in the PovRAY scene. This is done using either the provided scalePovray (or rotatePovray functions) or the custom declares. These custom declares are written to the ini file, and override the default settings of the template files (version 0.6 povwriter here).

   1 import povexport.*;
   2 import povexport.povwriter.*;
   3 boolean record = false;
   4 float angle = 0.0;
   5 float angleStep = PI/180.0;
   6 Process povray;
   7 PovExporter export;
   8 
   9 Sponge sponge;
  10 void setup() {
  11   size(600, 600, P3D);
  12   export = new PovExporter(this);
  13   export.chooseTemplate();
  14   export.storeSettings();
  15   noStroke();
  16   sponge = new Sponge(width/2);
  17   export.createIniFile(dataPath("menger.ini"), 11);
  18   export.addDeclareOption("TransXP5", "-25"); // custom declare,translates X axis in PovRAY
  19   export.addDeclareOption("TransYP5", "20"); // custom declare,translates Y axis in PovRAY
  20   export.scalePovray(0.5);
  21   export.writeIniFile();
  22 }
  23 
  24 void draw() {
  25   background(0); 
  26   lights();
  27 
  28   if (record) {
  29     noLights();
  30     noLoop();
  31     beginRaw(PovExporter.POV, dataPath("menger.pov"));
  32   }
  33   try {  
  34     if (povray != null && povray.waitFor() == 0) {      
  35       display();
  36     }
  37     else
  38       render();
  39   }
  40   catch(InterruptedException e) {
  41     e.printStackTrace();
  42   }
  43   if (record) {
  44     endRaw();
  45     record = false;
  46     loop();
  47   }
  48 }
  49 
  50 void render() {
  51   angle = (angle + angleStep) % TWO_PI;  
  52   translate(width/2, height*0.35, -width/4);
  53   rotateZ(angle);
  54   rotateY(angle);
  55   sponge.render();
  56 }
  57 
  58 void display() {
  59  // background(255);
  60   PImage img = loadImage(dataPath("menger.png"), "png");
  61   background(img);
  62 }
  63 
  64 void keyPressed() {
  65   switch(key) {
  66   case 'r':  // create balls.pov and balls.ini files 
  67   case 'R':  // Quality 1 ...7... 11 (low ... medium ... high)
  68     record = true;        
  69     break;
  70   case 't':  // run PovRAY calling balls.ini
  71   case 'T':  
  72     povray = export.rayTrace(); 
  73     break;
  74   case 'e':
  75   case 'E':
  76     if (this.record == false) {
  77       String[] args = {
  78         export.getJEditPath(), dataPath("menger.pov")
  79       };
  80       exec(args); // open sphere.pov with jEdit
  81     }
  82     break;
  83   }
  84 }
  85 
  86 
  87 // Sponge.pde by Martin Prout
  88 class Sponge{
  89   color col1 = color(0.6667, 1, 0.5);
  90   color col2 = color(0.5, 1, 0.5);
  91   color col3 = color(0.83333, 1, 0.5);
  92   color col4 = color(0.16667, 1, 0.5);
  93   color col5 = color(0.33334, 1, 0.5);
  94   int MIN_SIZE = 50; // 33 is a practical lower limit, depends on your graphics card?
  95   ArrayList cubeData;
  96 
  97   Sponge(float sz){
  98     cubeData = new ArrayList();
  99     fillCubeData(0, 0, 0, sz);
 100   }
 101 
 102   void fillCubeData(float x,float y,float z, float sz){
 103     float u = sz/3;
 104     if (sz < MIN_SIZE){ // recursion limited by minimum cube size
 105       CubeData data = new CubeData(x, y, z, sz);
 106       cubeData.add(data);
 107     }
 108     else{
 109       for (int i = -1; i <= 1; i++){
 110         for (int j = -1; j <= 1; j++){
 111           for (int k = -1; k <= 1; k++){
 112             if ((abs(i) + abs(j) + abs(k)) > 1 ) {
 113               fillCubeData(x + (i * u), y + (j * u), z + (k * u), u);
 114             }
 115           }
 116         }
 117       }
 118     }
 119   }
 120 
 121   void render(){
 122     CubeData data;
 123     for (int i = 0; i < cubeData.size(); i++){
 124       data = (CubeData)cubeData.get(i); // cast back object to CubeData
 125       pushMatrix();
 126       translate(data.x, data.y, data.z);
 127       myBox(data.sz);
 128       popMatrix();
 129     }    
 130   }
 131 
 132 
 133   void myBox(float sz){
 134     noStroke();
 135     // Original had different color faces
 136     beginShape(QUADS);
 137     vertex(-sz/2,  sz/2,  sz/2); 
 138     vertex( sz/2,  sz/2,  sz/2); 
 139     vertex( sz/2, -sz/2,  sz/2); 
 140     vertex(-sz/2, -sz/2,  sz/2); 
 141     vertex( sz/2,  sz/2, -sz/2); 
 142     vertex(-sz/2,  sz/2, -sz/2); 
 143     vertex(-sz/2, -sz/2, -sz/2); 
 144     vertex( sz/2, -sz/2, -sz/2); 
 145     vertex(-sz/2,  sz/2, -sz/2); 
 146     vertex(-sz/2,  sz/2,  sz/2); 
 147     vertex(-sz/2, -sz/2,  sz/2); 
 148     vertex(-sz/2, -sz/2, -sz/2);
 149     vertex( sz/2,  sz/2,  sz/2); 
 150     vertex( sz/2,  sz/2, -sz/2); 
 151     vertex( sz/2, -sz/2, -sz/2); 
 152     vertex( sz/2, -sz/2,  sz/2);
 153     vertex(-sz/2, -sz/2, -sz/2); 
 154     vertex( sz/2, -sz/2, -sz/2); 
 155     vertex( sz/2, -sz/2,  sz/2); 
 156     vertex(-sz/2, -sz/2,  sz/2);
 157     vertex(-sz/2,  sz/2, -sz/2); 
 158     vertex( sz/2,  sz/2, -sz/2); 
 159     vertex( sz/2,  sz/2,  sz/2); 
 160     vertex(-sz/2,  sz/2,  sz/2); 
 161     endShape();
 162   }
 163 }
 164 
 165 // CubeData.pde
 166 
 167 class CubeData{
 168   float x;
 169   float y;
 170   float z;
 171   float sz;
 172   
 173   CubeData(float x, float y, float z, float sz){
 174     this.x = x;
 175     this.y = y;
 176     this.z = z;
 177     this.sz = sz;
 178   }
 179 } 

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