GENWARE

Biothing's Kernel
Archive for December, 2010

reTUR(n)INGmatter

AADRL Workshop 2 / reTUR(n)INGmatter
Tutor: Alisa Andrasek
TA: Jose Sanchez

In this second workshop we worked with the reaction diffusion algorithm over a volumetric grid as voxel space for activating formations within the machine constrains of D-Shape. We experimented in a 2d printing process that keeps moving up (2 and a half D) and 3d setups that needed more constrains not to end up with ‘islands in the sky’. Hybrid setups proved to be quite successful being able to reshape based on external stimuli like light vectors or conditions of interiority. By going into the R & D neighbor calculation we could start breaking the symmetry of the algorithm and start driving a more ‘design intent’ agenda.

reTUR(n)INGmatter from Jose Sanchez on Vimeo.

Processing ++ Kinect

So….. I got a kinect. :D
I found 2 libraries to work with it in processing:
-Dan Shiffman: http://www.shiffman.net/2010/11/14/kinect-and-processing/
-nocy: https://github.com/nrocy/processing-openkinect

I’m using the later. It seems to work faster but we are still getting some jittering. Apparently people have gotten rid of this problem in OpenFrameworks. The code I’m posting is using a 3d environment where points get the z location based on the depth map. Also, as image and z Depth where not matching perfectly, did some functions for tuning them.

import king.kinect.*;
import peasy.*;
import processing.opengl.*;
import toxi.geom.*;

PeasyCam cam;

PImage img, depth;

int COLS = 640 ;
int ROWS = 480;

jPoint [][] grid = new jPoint[COLS][ROWS];
int dep[][] = new int[COLS][ROWS];
int im[][] = new int[COLS][ROWS];

void setup() {
 size(900, 600,P3D);

 cam = new PeasyCam(this, 100);

 NativeKinect.init();
 NativeKinect.start();

 img = createImage(COLS,ROWS,RGB);
 depth = createImage(COLS,ROWS,RGB);

 int cX = 0;
 int cY = 0;

 for (int i = 0; i < COLS*ROWS; i++) {

 Vec3D ori = new Vec3D(cX,cY,0);
 grid[cX][cY] = new jPoint(ori);
 dep[cX][cY] = 0;
 im[cX][cY] = color(0,0,0);

 cX++;
 if(cX == COLS) {
 cY ++;
 cX = 0;
 }
 }
}

void draw() {

 background(0);
 depth.pixels = NativeKinect.getDepthMap();
 img.pixels = NativeKinect.getVideo();

 //println(brightness(depth.pixels[1]));

 int countX = 0;
 int countY = 0;

 int count = 0;

 for (int i = 0; i < ROWS; i++) {
 for (int j = 0; j < COLS; j++) {
 grid[j][i].run();
 dep[j][i] = depth.pixels[count];
 im[j][i] = img.pixels[count];
 count++;
 }
 }

 for (int i = 0; i < COLS; i++) {
 for (int j = 0; j < ROWS; j++) {

 float depthz = brightness(dep[i][j]);
 float mapDep = map(depthz,0,255,-400,400);
 grid[i][j].loc.z = mapDep;

 //float varX = map(mouseX,0,width,-100,100);   //435
 //float varY = map(mouseY,0,height,-100,100);  //418

 float varX = map(435,0,width,-100,100);
 float varY = map(418,0,height,-100,100);

 int nuX = i + int(varX);
 if(nuX > COLS-1){
 nuX = COLS-1;
 }
 if(nuX < 0){
 nuX = 0;
 }
 int nuY = j + int(varY);
 if(nuY > ROWS-1){
 nuY = ROWS-1;
 }
 if(nuY < 0){
 nuY = 0;
 }

 grid[i][j].mainCol = im[nuX][nuY];
 }
 }

println("mouse X: " + mouseX + ", mouse Y: " + mouseY);

 if(keyPressed) {
 if (key == 's') {
 println("image saved!!!");
 saveFrame("img-####.jpg");
 }
 }
}
class jPoint {

 Vec3D loc;

 color mainCol;

 float cellValue;
 float cellcolR;
 float cellcolG;
 float cellcolB;

 float limit = 300;

 jPoint(Vec3D _loc) {

 loc = _loc;
 }

 void run() {
 display();

 }

 void display() {
 //cellcolR = red(cellCol);
 //cellcolG = green(cellCol);
 //cellcolB = blue(cellCol);

 //stroke(cellcolR,cellcolG,cellcolB);
 //stroke(255);

 stroke(mainCol);
 float mapStr = map(loc.z,0,255,1,5);
 //strokeWeight(mapStr);
 strokeWeight(3);

 //line(loc.x,loc.y,0,loc.x,loc.y,cellcolR*0.02);
 point (loc.x,loc.y, loc.z);
 }
}

Intro Code

Playing around with processing.js and old bits of code from Daniel Shiffman’s flocking, I decided to create some intro script for my blog. The processing.js version was working fine but was a bit slow… also had some problems when loading an image or displaying different fonts. So I went back to the java version that can handle higher populations // better speed.
Here is the code:

//code version written by Jose Sanchez

PFont headline;
PFont local;
PFont small;

ArrayList agents;

float desiredseparation  = 30.0;
float neighbordistC = 100;
float neighbordistA = 40;

PImage b;

void setup() {

  size(1440,300);
  background(0);
  smooth();

  agents = new ArrayList();

  headline = createFont("FFScala-32.vlw", 20);
  local = createFont("FFScala-32.vlw", 10);
  small = createFont("FFScala-32.vlw", 7);

  for(int i = 0; i &lt; 500 ;i++) {
    agents.add(new Agent(new PVector(random(width),0)));
  }

  frameRate(30);
}

void draw() {
  //background(0,1);
  noStroke();
  fill(0,9);
  rect(0,0,width,height);

  for(int i = 0; i &lt; agents.size(); i++) {
    Agent a = (Agent) agents.get(i);
    a.run();
  }

  if(mouseX &gt; 0 &amp;&amp; mouseX &lt; 300) {
    if(mouseY &gt; 200 &amp;&amp; mouseY &lt; height) {
      fill(255);
      if(mousePressed) {
        link("http://genware.org/blog/");
      }
    }
    else {
      fill(255,10);
    }
  }
  else {
    fill(255,10);
  }

  noStroke();
  //text label
  textFont(headline);
  text("[GENWARE.ORG]", 30, 270);
  textFont(local);
  text("// OPEN KNOWLEDGE REPOSITORY", 190, 270);
  textFont(small);
  text("++ CLICK ON SCREEN TO ADD MORE AGENTS", 30, 20);
  text("++ CLICK ON TITLE TO CONTINUE", 30, 30);

  if(mousePressed) {
    agents.add(new Agent(new PVector(mouseX,mouseY)));
  }
}
//code version written by Jose Sanchez

class Agent {

  PVector loc = new PVector(width/2,height/2);
  PVector vel = new PVector(random(-1,1),random(-1,1));
  PVector acc= new PVector(0,0);
  float r = 12;
  float maxspeed =9;
  float maxforce = 0.4;
  float maxVel = 9;
  float vx, vy;

  float stiffness = 0.006;
  float damping = -0.7;

  Agent(PVector _loc) {
    loc = _loc;
  }

  void run() {
    display();
    flock();
    borders();
  }

  void flock() {
    PVector sep = new PVector(0,0);
    PVector ali = new PVector(0,0);
    PVector coh = new PVector(0,0);
    PVector sum = new PVector(0,0);

    int count1 = 0;
    int count2 = 0;
    int count3 = 0;

    if(frameCount % 1 == 0) {
      for (int i = 0 ; i &lt; agents.size(); i++) {
        Agent other = (Agent) agents.get(i);
        float d = PVector.dist(loc,other.loc);

        //-----------------------------------------------------------------
        if ((d &gt; 0) &amp;&amp; (d &lt; desiredseparation)) {
          // Calculate vector pointing away from neighbor
          PVector diff = PVector.sub(loc,other.loc);
          diff.normalize();
          diff.div(d);        // Weight by distance
          sep.add(diff);
          count1++;            // Keep track of how many
        }

        //-----------------------------------------------------------------
        if ((d &gt; 0) &amp;&amp; (d &lt; neighbordistA)) {
          ali.add(other.vel);
          count2++;
        }

        //-----------------------------------------------------------------
        if ((d &gt; 0) &amp;&amp; (d &lt; neighbordistC)) {
          sum.add(other.loc); // Add location
          count3++;
        }
      }
    }

    //-----------------------------------------------------------------
    //-----------------------------------------------------------------
    if (count1 &gt; 0) {
      sep.div((float)count1);
    }

    // As long as the vector is greater than 0
    if (sep.mag() &gt; 0) {
      // Implement Reynolds: Steering = Desired - Velocity
      sep.normalize();
      sep.mult(maxspeed);
      sep.sub(vel);
      sep.limit(maxforce);
    }
    //-----------------------------------------------------------------
    if (count2 &gt; 0) {
      ali.div((float)count2);
      ali.limit(maxforce);
    }

    // As long as the vector is greater than 0
    if (ali.mag() &gt; 0) {
      // Implement Reynolds: Steering = Desired - Velocity
      ali.normalize();
      ali.mult(maxspeed);
      ali.sub(vel);
      ali.limit(maxforce);
    }
    //-----------------------------------------------------------------
    if (count3 &gt; 0) {
      sum.div((float)count3);
      sum.sub(loc);
      sum.normalize();
      sum.mult(maxVel);
      sum.sub(vel);
      sum.limit(maxforce);

      coh.add(sum); //  steer(coh,false);  // Steer towards the location
    }

    sep.mult(3);
    ali.mult(0.1);
    coh.mult(0.2);

    acc.add(sep);
    acc.add(ali);
    acc.add(coh);

    vel.add(acc);
    vel.limit(maxVel);
    loc.add(vel);
    acc = new PVector(0,0);
  }

  // Wraparound
  void borders() {
    if (loc.x &lt; 0) loc.x = width;
    if (loc.y &lt; 0) loc.y = height;
    if (loc.x &gt; width) loc.x = 0;
    if (loc.y &gt; height) loc.y  = 0;
  }

  void display() {
    fill(3,180,255);
    float v = vel.mag();
    float c = map(v,0,maxVel,255,100);
    float c2 = map(v,0,maxVel,100,255);
    fill(0,c2,255);
    //stroke(255);
    noStroke();
    strokeWeight(1);

    ellipse(loc.x,loc.y,r,r);

    PVector ep =  new PVector(vel.x,vel.y);
    ep.normalize();
    ep.mult(8);
    ep.add(loc);

    stroke(255);
    //line (loc.x,loc.y,ep.x,ep.y);
  }
}