Polygonal Camera

posted by on 2014.08.13, under Processing
13:

It has been a while since my last update, and in particular since my last Processing code! So, here’s something very simple. Basically, it’s a grid of points connected by lines, which form the edges of polygons. The points move almost periodically: each of them undergoes an oscillatory motion, to which I’ve added a bit of noise, to make things more interesting. The polygons, which during the motion change their shape as the vertices move, are colored. Here comes the nice part: the color of a single polygon is given by taking at its geometric center the color of the pixel of the image obtained by capturing a frame via the webcam. In this way, the colors are “smeared”, but you can still somehow discern the webcam input. Here’s the code.

import processing.video.*;

Capture cam;

int n = 30;
float t = 0;
Point[][] points = new Point[n][n];

void setup(){
  size(320, 240);
  cam = new Capture(this, 320, 240, 30);
  cam.start();
  background(0);

  /* Setup the grid;
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < n; j++)
    {
      points[i][j] = new Point(i*width/n, j*height/n);
    }
  }
}

void draw(){
   if(cam.available()) {
    cam.read();
  }  
 background(0);
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < n; j++)
    {
      points[i][j].move();
      points[i][j].display();
    }
  }
  grid(points);
  t+= 0.1;
}

void grid(Point[][] gr){
  int c_x, c_y;
  for (int i = 0 ; i < n; i++){
    for (int j = 0; j < n; j++){
      if ( j < n -1 && i < n - 1){
        stroke(255, 100);
       /* Compute the geometric center;

        c_x = constrain(int((gr[i][j].pos.x + gr[i][j + 1].pos.x + gr[i + 1][j + 1].pos.x + gr[i + 1][j].pos.x)/4), 0, width);
        c_y = constrain(int((gr[i][j].pos.y + gr[i][j + 1].pos.y + gr[i + 1][j + 1].pos.y + gr[i + 1][j].pos.y)/4), 0, height);
       
          /* Create the polygon;
          fill(cam.pixels[constrain(c_x + width*c_y, 0, cam.pixels.length - 1)], 250);
          beginShape();
          vertex(gr[i][j].pos.x, gr[i][j].pos.y);
          vertex(gr[i][j + 1].pos.x, gr[i][j + 1].pos.y);
          vertex(gr[i + 1][j + 1].pos.x, gr[i + 1][j + 1].pos.y);
          vertex(gr[i + 1][j].pos.x, gr[i + 1][j].pos.y);
        endShape();
      }
    }
  }
}

/* Define the class Point

class Point{
  PVector pos;
  float angle;
  float depth;
  PVector dir;
  float phase;
  float vel;
 
Point(float _x, float _y){
  pos = new PVector(_x, _y);
  angle = random(0.0, 2*PI);
  depth = random(0.8, 2.4);
  dir = new PVector(cos(angle), sin(angle));
  vel = random(0.5, 1.5);
}

void display(){
  noStroke();
  fill(255, 255);
  ellipse(pos.x, pos.y, 4, 4);
}

void move(){
  /* Oscillatory motion with noise which depends on the "time" variable t;
  pos.x = pos.x + dir.x * cos(vel*t + noise(t*angle)*0.1) * depth;
  pos.y = pos.y + dir.y * cos(vel*t + noise(t*angle)*0.1) * depth;
}

}

Warning: Kids, don’t code the way I do! In this case I was particularly lazy: indeed, a more elegant way to do it would have been to create another class, say Grid, and hide there the polygon making, etc. The code would have been more readable and reusable, that way. But as I said, lazyness. :)

Here’s a little video of what you get

(If it doesn’t work, you can download or stream this )

pagetop