Nir Rachmel | LookingOutwards-1

by nir @ 2:40 am 24 January 2012

1. In the following link , I found a beautiful data visualization project by Jer Thorp. He was asked to visualize almost 140 years of the magazine Popular Science. The outcome is just beautiful, as can be seen – (Visualizing 138 Years of Popular Science Magazine. While is is a very creative idea, and very thoughtful, I wonder if the artist didn’t miss something. Besides being very aesthetically pleasing, this imagery does not convey any new information to the audience.

2. Another beautiful data visualization can be found in the following link. Following the riots in London, the artist mapped how misinformation could be spread on Twitter during a time of crisis. It’s visually appealing and invites the user to “play” with it for a while and learn. The user can choose different hoaxes and explore how the news spread among the twitter community. This kind of vizualization is very interesting, in my opinion, as it has political context and shows how twitter plays an important roles in these past few years’ events.

3. Last (but not least), Beautiful website. The interaction is very cool and engaging, but as always the case with these highly sophisticated html5 / css / js / flash techniques, one wonders what is the correct amount of “cool stuff”. Anything over that amount will very quickly lead to a slow website and impatient users not coming back ever again.

KaushalAgrawal – LookingOutwards – 1

by kaushal @ 1:12 am

Augmented Shadow

[youtube=https://www.youtube.com/watch?v=0arZMuPK58w]
The project was created by Joon Y. Moon, which uses light and boxes to create shadows and portrays life form around it. The cube blocks cast distorted shadows on the table top surface which looks like a house. The other elements such as trees, birds and people car projected on the surface. The design exhibits a form of life, where people move towards light sources and come back to their houses to light up the house. The project may be just an art form but can be used to do other interesting things. The idea of using shadows is very compelling and makes me think what more can we do with shadows and light forms.

Project Cascade

[youtube=https://www.youtube.com/watch?v=yQBOF7XeCE0]
Project Cascade was initiated by Mark Hansen at the NYTimes R&D. The project visualizes the spread of a message such as a tweet over social media. The project captures spread of a tweet takes over the social space and the people involved. The project maps beautifully captures the complex spread making it intuitive. The visualizations can be drilled down or rolled up to see key components, which makes it even more interesting. The idea can also be used to see how people interact in a more social setting like facebook, to identify outward people in your network as opposed to just being friends on the list.

All Eyes on you

[vimeo=https://vimeo.com/33186969 width=”600″]
This an installation named the Britzpetermann shop installation. It uses kinect, openframeworks and arduino to project generated eyes with different radius onto a glass pane. The installation is programmed such that the eyes are always looking at the person walking outside. What is really interesting about the project is that it take a simple concept of concentric circles and programs it to attract attention. The render of the eyes are really strong which adds to the overall effect. It would be interesting to see how this project is installed for advertising purposes, where the eyes look at you for a while and then diverts back to the product displayed on the window.

Zack J-W Face_OSC

by zack @ 1:01 am

One of the first things I noticed about Face_OSC is that it’s awesome and my wife thought you had to yell at it for it work.  The next thing I noticed is that it doesn’t read facial hair well and, well, I have some.

So I thought it would be appropriate to use Face_OSC to deal with the one thing it hadn’t, err, faced at least in a metaphorical sense.  I came to find out that it was a known unknown.  Golan lamented that it dealt with beards in a maddening way and Dan Wilcox suggested with one frown that it was a computational nightmare.  So I hope programmers get a kick out of it.

One technical hurdle was, using a camera for both the background image and face tracking meant two cameras (at least in my limited capacity as a coder).  Processing would not share with Face_OSC and vice versa from the computers built in camera.  Having an external web-cam meant I was always going to have an offset between the two focal points which is exacerbated by scale and movement.  A better code may be able to compensate for this.

Credit where credit is due:  Thanks to Dan Wilcox for bringing the Titty Tracker into the world.  Clearly an inspiration.

Video becomes worthless after 1:30…

[youtube https://www.youtube.com/watch?v=VToNr8IQTp4]

 

import processing.video.*;
Capture video;
 
import oscP5.*;
OscP5 oscP5;
 
PImage[] images = new PImage[6];
 
int b, found;
 
// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();
 
// gesture
float mouthHeight;
float mouthWidth;
float eyeLeft;
float eyeRight;
float eyebrowLeft;
float eyebrowRight;
float jaw;
float nostrils;
 
void setup()
{
  size(640,480);
  frameRate(2);
  imageMode(CENTER);
  b = 0;
 
  video = new Capture(this, width, height);
 
  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "poseScale", "/pose/scale");
  oscP5.plug(this, "posePosition", "/pose/position");
  oscP5.plug(this, "poseOrientation", "/pose/orientation");
  oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width");
  oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
  oscP5.plug(this, "eyeLeftReceived", "/gesture/eye/left");
  oscP5.plug(this, "eyeRightReceived", "/gesture/eye/right");
  oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left");
  oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right");
  oscP5.plug(this, "jawReceived", "/gesture/jaw");
  oscP5.plug(this, "nostrilsReceived", "/gesture/nostrils");
 
  for ( int i = 0; i< images.length; i++ )   {     images[i] = loadImage( i + ".png" );   // make sure images "0.png" to "?.png" exist   } } void draw() {     if (video.available()) {     video.read();     image(video, width/2, height/2);       // background(0);      if(found > 0)
  {
    scale(poseScale*.12);
    image(images[b], posePosition.x*poseScale - width*.75 ,posePosition.y*poseScale + height*.1);
  }
}
}
 
void keyPressed()
{
  if (keyPressed && key == ' ' )
  {
    b = (b + 1) % 6;
  }
  redraw();
}
 
// OSC CALLBACK FUNCTIONS
 
public void found(int i) {
  println("found: " + i);
  found = i;
}
 
public void poseScale(float s) {
  println("scale: " + s);
  poseScale = s;
}
 
public void posePosition(float x, float y) {
  println("pose position\tX: " + x + " Y: " + y );
  posePosition.set(x, y, 0);
}
 
public void poseOrientation(float x, float y, float z) {
  println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
  poseOrientation.set(x, y, z);
}
 
public void mouthWidthReceived(float w) {
  println("mouth Width: " + w);
  mouthWidth = w;
}
 
public void mouthHeightReceived(float h) {
  println("mouth height: " + h);
  mouthHeight = h;
}
 
public void eyeLeftReceived(float f) {
  println("eye left: " + f);
  eyeLeft = f;
}
 
public void eyeRightReceived(float f) {
  println("eye right: " + f);
  eyeRight = f;
}
 
public void eyebrowLeftReceived(float f) {
  println("eyebrow left: " + f);
  eyebrowLeft = f;
}
 
public void eyebrowRightReceived(float f) {
  println("eyebrow right: " + f);
  eyebrowRight = f;
}
 
public void jawReceived(float f) {
  println("jaw: " + f);
  jaw = f;
}
 
public void nostrilsReceived(float f) {
  println("nostrils: " + f);
  nostrils = f;
}
 
// all other OSC messages end up here
void oscEvent(OscMessage m) {
  if(m.isPlugged() == false) {
    println("UNPLUGGED: " + m);
  }
}

Zack J-W Look Out! – 2

by zack @ 11:33 pm 22 January 2012

For a time, it was good.  Then, seeds of dissent began to take root….at Gooski’s.

Ping pong playing robots have come a long way.  I can remember when ping pong playing robots were little more than a box holding a paddle and connecting with about 10% of incoming traffic.  Well, cousin, those days are over.
[youtube https://www.youtube.com/watch?v=vkk8kMm08cA]

I look forward to the days when they begin competing with humans.  And then beating them.  The first league of biological and artificial athletes.  Boy, won’t that be something?  A second Renaissance. Utopia. How could it possibly go wrong?

Nir Rachmel | 01-20-2012

by nir @ 10:34 pm 20 January 2012

Following is an image created by an algorithm inspired by Nake’s work from 1965.

 
Following is the code that generates an image following the same concepts as Nake's pioneering work in <a title="digital art" href="http://dam.org/artists/phase-one/frieder-nake" target="_blank">digital art</a> using a plotter.
 
NakeDraw myNake;
 
void setup() {
  size(801,801);
  background(255);
  stroke(0);
  myNake = new NakeDraw();
}
 
int drawOnce = 0;
 
void draw() {
  if (drawOnce == 0)
  {
    myNake.draw();
    drawOnce = 1;
  }
}
 
/**
* Class NakeDraw - Implements an algorithm to create an image inspired by Frieder Nake's work publshed 1956-57
* called Nr. 2 ("Klee").
* The image is composed of several repeated and random elements
* 1. Horizontal lines that "break" in the middle and change direction. They never intersect each other.
* 2. These lines create quadrilaterals between them.
* 3. Each quadrilateral can either be empty, have a random set of vertical+parallel lines or have a set of triangles
*
* Nir Rachmel, Interactive art and computational design, Jan 2012 (C)
* A link that helped analyze the original image: http://dada.compart-bremen.de/node/2875.
*/
class NakeDraw {
  int numOfRows; // number of rows on the canvas
  int numOfColumns; // number of columns on the canvas
  PVector[][] verticesArr; // array that holds all the vertices that define the skeleton of the horizontal lines
  float[] horizontalSpaces; // array to hold the distance that defines a horizontal section
  float baseBandWidth; // basic width between two consequtive horizontal lines (subject to noise)
  float verticalNoise; // vertical noise limit
  float smallNoise; // 
 
  // C'tor
  NakeDraw() {
    numOfRows = 11; // including both upper and lower frame borders
    numOfColumns = 9;
    verticesArr = new PVector[numOfRows][numOfColumns];
    horizontalSpaces = new float[] {1/6f, 1/6f, 1/12f, 1/6f, 1/12f, 1/12f, 1/6f, 1/12f};
    // Basic space between two horizontal lines
    baseBandWidth = height / 10;
    verticalNoise = baseBandWidth * 0.05;
    smallNoise    = baseBandWidth / 8;    
 
    // Initialize arrray
    for (int i=0 ; i &lt; numOfRows ; i = i+1)
    {
      for (int j=0 ; j &lt; numOfColumns ; j = j+1)
      {
        verticesArr[i][j] = new PVector(0,0);
      }
    }
 
  }
 
  // performs the drawing of the image. Using random numbers, the decision is made
  // for each quadrilateral if to leave it blank, fill it with horizontal lines or vertical lines.
  void draw()
  {
    // Draw the horizontal rows
     drawRows();
 
     // go over each quadrilateral and randomly draw lines / triangles / nothing
     int numOfBands = numOfRows -1;
     for (int i=0 ; i &lt; numOfBands ; i=i+1)
    {
       for (int j=0 ; j &lt; numOfColumns-1 ; j=j+1)
      {
         int pattern = int(random(0,3));
         if (pattern == 0)
         {
            drawVerticalLinesPattern(i,j);
         }
         if (pattern == 1)
         {
            drawTriangles(i,j);
         }
      }
    }
 
    // Circles are drawn on the image without relation to the other shapes.
    drawCircles();
  }
 
  /**
  * Draw the horiztonal rows.
  */
  void drawRows()
  {    
 
   // initialize top and bottom row (which are straight lines, part of the frame)
   verticesArr[0][0].set(0f,0f,0f);
   verticesArr[numOfRows-1][0].set(0f,height,0f);
   for (int j=1 ; j &lt; numOfColumns ; j=j+1)
   {
      float xVal = verticesArr[0][j-1].x + horizontalSpaces[j-1] * width;
      verticesArr[0][j].set(xVal, 0f, 0f);
      verticesArr[numOfRows-1][j].set(xVal,height,0f);
   }
 
    // Set the initial vertices on the left border
    for (int i=1 ; i&lt;numOfRows-1 ; i=i+1)
    {
       float yVal = 0;
       yVal = verticesArr[i-1][0].y + baseBandWidth + random(-verticalNoise, verticalNoise);
       verticesArr[i][0].set(0f,yVal,0f);
    }
 
    // start from each randomly generated vertex and draw a random horizontal line that stretches
    // all the way to the right border of the window. This line is not straight, and randomly changes its direction.
    for (int i=1 ; i &lt; numOfRows-1 ; i = i+1) // rows
    {
      for (int j=1 ; j &lt; numOfColumns ; j = j+1) // columns (first is already set)
      {
         float xVal = verticesArr[i][j-1].x + horizontalSpaces[j-1] * width;
         float yVal = verticesArr[i][j-1].y + random(-smallNoise, smallNoise);
         verticesArr[i][j].set(xVal, yVal, 0f);
          line(verticesArr[i][j-1].x,verticesArr[i][j-1].y,
               xVal, yVal);
      }
    }
  }
 
  /**
  * A helper function that calculates the y coordinates according to a given x coordinate, row and column
  * (that uniquely identifies a straight line on the screen)
  */
  float calculateY(int rowNum, int colNum, float xCoordinate, boolean isTop)
  {
       float yCoordinate = 0;
 
       if (isTop)
       {
         if (rowNum == 0)
         {
           yCoordinate = 0;
         }
         else
         {
           // y coordinate needs to be calculated for both top line and bottom.
           float slopeTop = (verticesArr[rowNum][colNum+1].y - verticesArr[rowNum][colNum].y) /
                       (verticesArr[rowNum][colNum+1].x - verticesArr[rowNum][colNum].x );
 
           float constValTop =  verticesArr[rowNum][colNum].y - slopeTop * verticesArr[rowNum][colNum].x;
 
           // now we have the equation, we can find the top coordinates for the vertical line
           yCoordinate = slopeTop * xCoordinate + constValTop;
         }
       }
       if (!isTop)
       {
         if (rowNum == (numOfRows - 1))
         {
           yCoordinate = height;
         }
         else
         {
           float slopeBottom = (verticesArr[rowNum+1][colNum+1].y - verticesArr[rowNum+1][colNum].y) /
                       (verticesArr[rowNum+1][colNum+1].x - verticesArr[rowNum+1][colNum].x );
 
           float constValBottom =  verticesArr[rowNum+1][colNum].y - slopeBottom * verticesArr[rowNum+1][colNum].x;
 
           yCoordinate = slopeBottom * xCoordinate + constValBottom;
         }  
 
       }
 
       return yCoordinate;
 
  }
 
  /**
  * Draws the random group of vertical lines as constrained by a single quadrilateral.
  * Will draw up to 15 lines.
  */
  void drawVerticalLinesPattern(int rowNum, int colNum)
  {
    /* Draw vertical lines */
    int numOfLines = int(random(1, 15));
    for (int i=0 ; i &lt; numOfLines ; i=i+1)
    {
       // x coordinate is just a random x between the two adjacent vertices
       println("rowNum is " + rowNum + " colNum is " + colNum);
       float xCoordinate = random(verticesArr[rowNum][colNum].x, verticesArr[rowNum][colNum+1].x);
 
       float yCoordinateTop = calculateY(rowNum, colNum, xCoordinate, true);
       float yCoordinateBottom = calculateY(rowNum, colNum, xCoordinate, false);       
 
       line(xCoordinate, yCoordinateTop, xCoordinate, yCoordinateBottom);
 
    }
 
  }
 
  /**
  * Draws the random group of triangles as contrained by a single quadrilateral.
  * Will draw up to 15 triangles.
  **/
  void drawTriangles(int rowNum, int colNum)
  {
     int numOfTriangles = int(random(1,15));
     for (int k=0 ; k &lt; numOfTriangles ; k = k+1)
     {
        // randomly select 3 x's
       float x1 = random(verticesArr[rowNum][colNum].x, verticesArr[rowNum][colNum+1].x);
       float x2 = random(verticesArr[rowNum][colNum].x, verticesArr[rowNum][colNum+1].x);
       float x3 = random(verticesArr[rowNum][colNum].x, verticesArr[rowNum][colNum+1].x);
 
       // x1 will always be on the top line, x2+x3 will be on the bottom line
       float y1 = calculateY(rowNum, colNum, x1,true);
       float y2 = calculateY(rowNum, colNum, x2, false);
       float y3 = calculateY(rowNum, colNum, x3, false );  
 
       line(x1,y1,x2,y2);
       line(x1,y1,x3,y3);
     }
 
  }
 
  /**
  * Draws random circles on the screen (up to 10). Radius and locations are random.
  * Locations are calculated such as the circle is always completely visible within the given window frame.
  **/
  void drawCircles()
  {
     int numOfCircles = int(random(1,11));
     noFill();
     for (int i=0 ; i &lt; numOfCircles ; i=i+1)
    {
       float circleRadius = random(1, baseBandWidth);
       float xCoordinates = random(circleRadius,width-circleRadius); // we want to make sure the circle can be fit entirely on our canvas
       float yCoordinates = random(circleRadius,height-circleRadius); // we want to make sure the circle can be fit entirely on our canvas
 
       ellipse(xCoordinates, yCoordinates, circleRadius, circleRadius);
    }
  }
 
}

Danger world!

by heather @ 12:04 pm 17 January 2012

“Danger” means hello in robo-speak!

Hello Class!

by admin @ 10:09 pm 16 January 2012

Welcome to WordPress. This was my first post.

« Previous Page
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2023 Interactive Art and Computational Design, Spring 2012 | powered by WordPress with Barecity