Voronoi regions using cones

From Processing

Jump to: navigation, search
Versions: 1.0+
Contributors: Tom Carden
Started: 2006-03-10


This is a first pass attempt at converting a classic OpenGL hardware hack into Processing 3D.

Source Code

/**
voronoicones taken from http://processinghacks.com/hacks:voronoicones
@author Tom Carden
*/
 
// draws 32 points and their approximate voronoi regions
// only using cones, and P3D's depth buffer
 
int NUM_POINTS = 12;
float x[];  // point x
float y[];  // point y
float av[]; // point angular velocity
color c[];  // point color
 
void setup() {
  size(400,400, P3D);
 
  // FIXME: ortho seems to be a bit strange, I am investigating
  ortho(-width/2,width/2,-height/2,height/2,-10,10);
 
  x = new float[NUM_POINTS];
  y = new float[NUM_POINTS];
  av = new float[NUM_POINTS];
  c = new color[NUM_POINTS];
 
  for (int i = 0; i < NUM_POINTS; i++) {
    x[i] = random(width);
    y[i] = random(height);
    av[i] = random(-0.02,0.02);
    c[i] = color(random(255),random(255),random(255));
  }
 
}
 
void draw() {
 
  background(0);
 
  // draw the cones
  pushMatrix();
  // -10 means the cones are below the surface
  // (so we can draw on top of them later)
  translate(0,0,-10);
  for (int i = 0; i < NUM_POINTS; i++) {
    fill(c[i]);
    noStroke();
    // if you have more points, use a smaller radius 
    // (but you risk having gaps)
    cone(x[i],y[i],200.0,10.0); 
  }
  popMatrix();
 
  // give user control of first point
  x[0] = mouseX;
  y[0] = mouseY;
 
  // on mouse pressed, orbit the points around the centre of the screen
  if (mousePressed) {  
    for (int i = 1; i < NUM_POINTS; i++) {
      float r = dist(width/2,height/2,x[i],y[i]);
      float a = atan2(y[i]-(height/2),x[i]-(width/2)) + av[i];
      x[i] = (width/2) + (r * cos(a));
      y[i] = (height/2) + (r * sin(a));
    }
  }
 
  // draw dots for the points
  for (int i = 0; i < NUM_POINTS; i++) {
    fill(0);
    noStroke();
    ellipse(x[i],y[i],5.0,5.0);
  }
 
}
 
/**
cone taken from http://processinghacks.com/hacks:cone
@author Tom Carden
*/
 
 
static float unitConeX[];
static float unitConeY[];
static int coneDetail;
 
static {
  coneDetail(24);
}
 
// just inits the points of a circle, 
// if you're doing lots of cones the same size 
// then you'll want to cache height and radius too
static void coneDetail(int det) {
  coneDetail = det;
  unitConeX = new float[det+1];
  unitConeY = new float[det+1];
  for (int i = 0; i <= det; i++) {
    float a1 = TWO_PI * i / det;
    unitConeX[i] = (float)Math.cos(a1);
    unitConeY[i] = (float)Math.sin(a1);
  }
}
 
// places a cone with it's base centred at (x,y),
// beight h in positive z, radius r.
void cone(float x, float y, float r, float h) {
  pushMatrix();
  translate(x,y);
  scale(r,r);
  beginShape(TRIANGLES);
  for (int i = 0; i < coneDetail; i++) {
    vertex(unitConeX[i],unitConeY[i],0.0);
    vertex(unitConeX[i+1],unitConeY[i+1],0.0);
    vertex(0,0,h);
  }
  endShape();
  popMatrix();
}

Downloads

Related Links

Personal tools