1,965 Views
//Depths 
//Ale González, 2013
//A drawing generator created to show how to implement an efficient perlin noise vector field using lookup tables

final int 
  WIDTH   = 800,
  HEIGHT  = 800,
  MAX_AGE = 100,
  STEPS = 900,
  FILL = #000000,
  STROKE = #FFFFFF,
  ALFA = 50,
  BACKGROUND = #EEEEEE;

final float 
  SMOOTHNESS = .0005;

PVector[] DIRECTIONS;
int[][] INDICES;
ArrayList<Particle> particles;

PGraphics bg;

void setup() 
{
    size(800, 800);
    fill(FILL, ALFA);
    stroke(STROKE, ALFA);
    
    //Create a fancy degraded background
    reset();
    
    //LUT to store the indices associated with the vector field
    INDICES = new int[WIDTH][HEIGHT];
    for (int y = 0; y < HEIGHT; y++) for (int x = 0; x < WIDTH; x++) 
        INDICES[x][y] = int(noise(x*SMOOTHNESS, y*SMOOTHNESS)*STEPS); 

    //LUT to store the directions associated with the vector field
    DIRECTIONS = new PVector[STEPS];
    for (int i = 0; i < STEPS; i++) 
        DIRECTIONS[i] = new PVector(cos(i*.5)*.1, sin(i*.5)*.1);  
    
    //Particles
    particles = new ArrayList<Particle>();
}
 
void reset(){
    loadPixels();
    for (int i=0; i<WIDTH*HEIGHT; i++) 
        pixels[i] = (0xFF - floor(dist(i%WIDTH, i/HEIGHT, WIDTH/2, HEIGHT/2)*.25)) * 0x01010101;
    updatePixels();
} 
  
void draw()
{
    if(mousePressed) 
        particles.add(new Particle(new PVector(mouseX, mouseY)));   
    
    for(int i = 0; i < particles.size(); i++) {
        Particle p = particles.get(i);
        if (p.isDead() == false) {
            p.update();
            p.draw();
        }
        else 
            particles.remove(i);
    }
}

void keyPressed(){
    reset();  
}

class Particle
{   
  PVector pos, vel;
  int age, x, y;
    
  public Particle(PVector p)
  {
    pos = p;
    vel = new PVector();
    age = MAX_AGE;
  }
   
  boolean isDead() { return age==0; } 
    
  void draw() {  ellipse(pos.x, pos.y, age, age); }  
    
  void update() 
  { 
    age--;
    vel.add(DIRECTIONS[INDICES[(int(pos.x)+WIDTH)%WIDTH][(int(pos.y)+HEIGHT)%HEIGHT]]);
    pos.add(vel);
  }
}