My intent for this final project was to create a simple abstraction from an image and then generate a 3D representation based on the abstraction. The code was specifically designed for the exportation of layers with the intent to laser cut those layers on acrylic and then stack them together to create a 3D experience from a 2D image. I used a picture of a snowflake to create each layer with the hope to create a physical and abstracted "snowflake" once the layers were stacked. The digital representation displays these layers in a way that mimics snow falling to the song, "Let it Snow" by Frank Sinatra.

The code is simple but it primarily uses a basic "for loop," that is essentially finding the brightness of pixels in the snowflake picture and mapping them. For the first pixel, an ellipse will draw outward from the center at a distance based on the brightness of that pixel. The second pixel generates the second ellipse that has been rotated slightly from the first and also plotted away from the center based on the second pixel brightness. It maps each ellipse for each pixel for the first row of 64 pixels. With each pass of the "for loop," the program moves to the next row of pixels, and translates in the z direction to map that row of pixels. The program will continue to map 64 layers, or 64 rows of pixels.

I am really happy with the way this code turned out. This has to be my favorite project yet, because though it was very simple, it turned out to be several things at once. I got an abstraction from an image, a music visualizer, and an output to create a physical model of the program. I feel that this program is one that showcases and demonstrates the possibilities of programming.

View program in action. (need Java enabled web browser)

The program live drawing.  

Model

Below is the 3D representation of the programs output. Laser cut acrylic and bolted together.

Source Code:

 

//press m to unmute the volume.
//let it snow. 

//import processing.pdf.*;
import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioPlayer clip;
BeatDetect beat;
BeatListener bl;

//boolean record;

PImage flake;
float t = 0;


void setup(){
  size(500, 500,P3D);
  background(143,144,144);
  
 /*because I wanted to make 64 layers of acrylic, I made the snow 
 flake picture 64x64 pixels. This is why the number 64 is relavent. */
 
  flake = loadImage("flakefinal.jpg");


  minim = new Minim(this);
  clip = minim.loadFile("let it snow.mp3");

  beat = new BeatDetect(clip.bufferSize(), clip.sampleRate());
  beat.setSensitivity(100);

  bl = new BeatListener(beat, clip);  
  clip.loop();
  clip.mute();


}

int i=0;

void draw(){
  //For the code submission, I am commenting out the pdf output. this was for 3d representation.
  //  if (record) {
  //    beginRecord(PDF, "star-##.pdf"); 
  //  }
  if(i==64){
    i =0;
  }
  ellipseMode(CENTER);

  int n = flake.width;

  flake.loadPixels();
  float b = 0; //brightness

  camera(260,250,600,300,140,100,0,1,0);
  rectMode(CENTER);
  fill(143,144,144,.5);
  rect(width*2,height*2,5000,5000); //this is for the fading effect.
  translate(width/2,height/2,i*10); //I translate sketch to the center and extrude in the z plane.

   /* The next section is a for loop that is essentially finding the brightness
  of pixels in the snow flake picture and mapping them. for the first pixel, an ellipse
  will draw outward from the center at a distance based on the brightness of that pixel. 
  the second ellipse for the second pixel is rotated slightly from the first and also plotted away
  from the center based on the second pixel brightness. It maps each ellipse for each pixel for
  the first row of 64 pixels. With each pass of the for loop, the program moves to the next
  row of pixels, and translates in the z direction to map that row of pixels. it continues to map
  for 64 layers.*/

  for (int c=0+i*n;c < n+i*n;c++){

    t = brightness(flake.pixels[c]);
    float m = map(t,0,255,0,64);
    pushMatrix();
    rotate((2*PI/64)*c);
    noStroke();
    fill(206,217,224,30);
    ellipse(m,m,10,10);

    popMatrix();


  }

  //
  //  if (record) {
  //    endRecord();
  //    record = false;
  //  }
  //  if (frameCount <= 65){
  //    record = true;
  //  }
  if ( beat.isHat() ){ // this is telling the program to translate in the z direction, every time
                       // that the hat is dectected. 
    i++;

  }
}

void keyPressed()
{
  if ( key == 'm' )
  {
    if ( clip.isMuted() )
    {
      clip.unmute();
    }
    else
    {
      clip.mute();
    }
  }
}

void stop()
{

  clip.close();

  minim.stop();
  super.stop();     
}

class BeatListener implements AudioListener
{
  private BeatDetect beat;
  private AudioPlayer source;

  BeatListener(BeatDetect beat, AudioPlayer source)
  {
    this.source = source;
    this.source.addListener(this);
    this.beat = beat;
  }

  void samples(float[] samps)
  {
    beat.detect(source.mix);
  }

  void samples(float[] sampsL, float[] sampsR)
  {
    beat.detect(source.mix);
  } 

}