Telling Stories With Data: Week 3

We were asked to take pictures for a week to create a data set that could then be visualized without the image data. I chose a compass as my subject and snapped a photo on my iPhone at noon, 3:00, 6:00; 9:00 and midnight.

Raw Data
wrist

After sorting through the available data (geocode, time, compass direction, color, indoor/outdoor, etc.), I realized that I couldn’t get away from the idea of the compass as a thing to find your way through space. My concept evolved into orienteering through spacetime – basically mapping the path that would take you directly back to the moment you began from rather than the path you followed chronologically. So, if you turned 180 degrees and projected back through space-time in the right dimensions, you would end up in the moment in which the experiment began. I created a Processing sketch from the raw data to map the distance and facing direction in cylindrical space. I brought this map image into Illustrator and put a front end on it, including a blend that shows what cone of space-time I tend to travel in.

Orienteering in Space-Time
Orienteering

GL Art: Week 2

Due Week 2

  • Red book (Third Edition) chapter 2 “Drawing Geometric Objects” pages 42-47
  • Get a basic OpenGL app running in Eclipse
  • Look at the DemoBasicGeometry.java code in the demo folder
  • Using the program above as a starting point, experiment with creating geometry
    — fill the screen with shapes
    — bonus points if they move
    — bonus points if they change color

Rotation

package voxels;

import com.sun.opengl.util.Animator;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import java.lang.Math.*;

/**
 * Test.java <BR>
 * author: Brian Paul (converted to Java by Ron Cemer and Sven Goethel) <P>
 *
 * This version is equal to Brian Paul's version 1.2 1999/10/21
 */

public class Test implements GLEventListener {

    float frameCount;

    public static void main(String[] args) {
        Frame frame = new Frame("Test");
        GLCanvas canvas = new GLCanvas();

        canvas.addGLEventListener(new Test());
        frame.add(canvas);
        frame.setSize(640, 480);
        final Animator animator = new Animator(canvas);
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                // Run this on another thread than the AWT event queue to
                // make sure the call to Animator.stop() completes before
                // exiting
                new Thread(new Runnable() {

                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });
        // Center frame
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        animator.start();

    }

    public void init(GLAutoDrawable drawable) {
        // Use debug pipeline
        // drawable.setGL(new DebugGL(drawable.getGL()));

        GL gl = drawable.getGL();
        System.err.println("INIT GL IS: " + gl.getClass().getName());

        // Enable VSync
        gl.setSwapInterval(1);

        // Setup the drawing area and shading mode
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glShadeModel(GL.GL_SMOOTH); // try setting this to GL_FLAT and see what happens.
    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        GL gl = drawable.getGL();
        GLU glu = new GLU();

        if (height <= 0) { // avoid a divide by zero error!

            height = 1;
        }
        final float h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, h, 1.0, 20.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();

        // Clear the drawing area
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        // Reset the current matrix to the "identity"
        gl.glLoadIdentity();

        // Move the "drawing cursor" around
        gl.glTranslatef(0.0f, 0.0f, -10.0f);

        gl.glPushMatrix();
        gl.glRotatef(frameCount, 1.0f, 1.0f, 0.0f);
        // Drawing Using Triangles
        for (int i = 0; i < 45; i++) {
            gl.glPushMatrix();
            gl.glRotatef(i*3, 1.0f, 0.0f, 0.0f);
            gl.glBegin(GL.GL_TRIANGLES);
            gl.glColor3f(1.0f, 0.0f, 0.0f);    // Set the current drawing color to red
            gl.glVertex3f(0.0f, 1.0f, 0.0f);   // Top
            gl.glColor3f(0.0f, 1.0f, 0.0f);    // Set the current drawing color to green
            gl.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
            gl.glColor3f(0.0f, 0.0f, 1.0f);    // Set the current drawing color to blue
            gl.glVertex3f(1.0f, -1.0f, 0.0f);  // Bottom Right
            // Finished Drawing The Triangle
            gl.glEnd();
            gl.glPopMatrix();
        }

        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glRotatef(-frameCount,1.0f,0.0f,1.0f);
        for(int i=0; i<72; i++){
            gl.glPushMatrix();
            gl.glRotatef(i*5,0.0f,0.0f,1.0f);
            gl.glTranslatef(3.0f, 0.0f, 0.0f);
            gl.glColor3f(1.0f,1.0f,1.0f);
            gl.glBegin(GL.GL_POINTS);
            gl.glVertex3f(0.0f,0.0f,0.0f);
            gl.glEnd();
            gl.glPopMatrix();
        }
        gl.glPopMatrix();

        //System.out.println(frameCount);
        frameCount++;

        // Flush all drawing operations to the graphics card
        gl.glFlush();
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }
}

Due Week 3

  • Redbook: in Chapter 2: “Describing Points, Lines, and Polygons”, pages 37-47 (stop at “Basic State Management” or “Displaying Points, Lines, and Polygons)
  • Redbook: in Chapter 3: “Viewing and Modelling Transformations”, pages 106-113 (stop at “Viewing Transformations”)
  • Translate, rotate and scale
  • Create a simple animated “solar system” using rotating cubes.

Nature of Code: Week 2

Due for Week 2

  • Assignment: Sign up for the class mailing list: join-itp-noc@lists.nyu.edu
  • Assignment: Take a look at these two examples of a square randomly moving around the screen: Walker without vectors, Walker with vectors. Find an example of real-world “natural” motion (preferably in the form of an online video) and develop a set of rules for moving the Walker. Can you do it without using any random whatsoever? Without changing how the square looks at all (changing size or rotation is ok), can you give it a personality or make it appear to have an emotional quality? Create a second version with the same behavior, but with your own non-square design. Feel free to design an environment for the Walker to live in as well. We’ll compare the versions in class next week. Can we create something natural through algorithmic behaviors alone? How much does visual design play a part? Post a link to your work, as well as any thoughts on the above, on the homework wiki.
  • Reading: Processing PVector tutorial, also available as PDF.
  • Reading: Computational Beauty of Nature, Introduction, Gary William Flake (you must be logged in through NYU to access the online version.)
  • Reading: Probability Theory — great friendly site!
    Mathematics and Physics for Programmers, Chapter 1 — Numbers, Danny Kodicek (optional)

lostSouls

The acceleration vectors are set by the brightness value of the perlin noise.
Eric did something similar and more interactive.

// Acceleration
// Nature of Code
// 2/2/10
// Author: voxels at g/mail

float noiseScale=0.0175;
float push = 0.06;
int thresh = 400;
float velConstrain = .2;

float[] fog;  

Lost soul, soul2, soul3;  

void setup(){
  size(400,400);
  smooth();
  createFog();

  color redPoint = color(brightness(get(width/2, height/2)),0,0);
  color greenPoint = color(0,brightness(get(width*2/3, height*2/3)),0);
  color bluePoint = color(0,0,brightness(get(width/5, height*4/5)));

  soul = new Lost(width/2, height/2, 0,0,0,0,redPoint);
  soul2 = new Lost(width*2/3,height*2/3,0,0,0,0,greenPoint);
  soul3 = new Lost(width/5,height*4/5,0,0,0,0,bluePoint);
}


void draw(){
  background(0);

  updateFog();

  updatePoint(soul);
  updatePoint(soul2);
  updatePoint(soul3);

  soul.render();
  soul2.render();
  soul3.render();
}

void createFog(){
  fog = new float[height*width];
  for(int i=0; i<width; i++){
    for(int j=0; j<height; j++){
      fog[i+j*height] = noise(i*noiseScale,j*noiseScale) * 255-20;
    }
  }

  loadPixels();
  for(int i=0; i<pixels.length; i++){
    color fogPoint = color(fog[i]);
    pixels[i] = fogPoint;
  }
  updatePixels();
  calculateNext();
}

void updateFog(){
  loadPixels();
  for(int i=0; i<pixels.length; i++){
    color fogPoint = color(fog[i]);
    pixels[i] = fogPoint;
  }
  updatePixels();
  calculateNext();
}

void calculateNext(){
  for(int i=0; i<width; i++){
    for(int j=0; j<height; j++){
      fog[i+j*height] = noise((i+frameCount*.75+1)*noiseScale,(j+frameCount*.75+1)*noiseScale) * 255;
    }
  }
}

class Lost{
  PVector pos;
  PVector vel;
  PVector acc;
  color intensity;
  boolean up;
  boolean right;

  Lost(int posX, int posY, int velX, int velY, int accX, int accY, color _intensity){
    pos = new PVector (posX, posY);
    vel = new PVector (velX, velY);
    acc = new PVector (accX, accY);
    intensity = _intensity;
    up = true;
    right = true;
  }

  void constrainSoul(){
    constrain(pos.x,5,width-5);
    constrain(pos.y,5,height-5);
    constrain(vel.x,-1*velConstrain,velConstrain);
    constrain(vel.y,-1*velConstrain,velConstrain);

    if(pos.x <=5){
      vel.x = -1*vel.x;
    }
    if(pos.x >= width-5){
      vel.x = -1*vel.x;
    }
    if(pos.y <= 5){
      vel.y = -1*vel.y;
    }
    if(pos.y > height-5){
      vel.y = -1*vel.y;
    }
  }

  void render(){
    stroke(intensity);
    strokeWeight(1);
    noFill();
    ellipse(pos.x, pos.y,5,5);
  }
}



void updatePoint(Lost _soul){
  checkDirection(_soul);
  _soul.vel.add(_soul.acc);
  _soul.pos.add(_soul.vel);
  _soul.acc.mult(0);

 
  //set the colors
  color redPoint = color(brightness(get(int(soul.pos.x), int(soul.pos.y))),0,0);
  color greenPoint = color(0,brightness(get(int(soul2.pos.x), int(soul2.pos.y))),0);
  color bluePoint = color(0,0,brightness(get(int(soul3.pos.x), int(soul3.pos.y))));
  soul.intensity = redPoint;
  soul2.intensity = greenPoint;
  soul3.intensity = bluePoint;
 
  //constrain
  _soul.constrainSoul();
}



void checkDirection(Lost _soul){

  int x = int(_soul.pos.x);
  int y = int(_soul.pos.y);
 
  float top = brightness(get(x,y-1));
  float bottom = brightness(get(x, y+1));
  float left = brightness(get(x-1, y));
  float right = brightness(get(x+1, y));
 
  //Check to see if the top is a stronger repulsion than the bottom
  if(top <= bottom){
    _soul.up = true;
  }
  else{
    _soul.up = false;
  }
 
  //Set the acceleration based on the brightness value
  if(_soul.up == true){
    _soul.acc.y = map(top,0,thresh, -push,push);
  }
  else if(_soul.up == false){
    _soul.acc.y = map(bottom,0,thresh,-push,push);
  }


  //Check again for left vs. right
  if(right <= left){
    _soul.right = true;
  }
  else{
    _soul.right = false;
  }
 
  //Set the acceleration based on the brightness value
  if(_soul.right == true){
    _soul.acc.x = map(right,0,thresh,-push,push);
  }
  else if(_soul.right == false){
    _soul.acc.x = map(left,0,thresh,-push,push);
  }
 
  //Accellerate only in one direction at a time
  if(_soul.up == true && _soul.right == true && top > right){
    _soul.acc.x = 0;
  }
  else if(_soul.up == true && _soul.right == true && top < right){
    _soul.acc.y = 0;
  }
  else if(soul.up == false && _soul.right == true && bottom > right){
    _soul.acc.x = 0;
  }
  else if(soul.up == false && _soul.right == true && bottom < right){
    _soul.acc.y = 0;
  }
  else if(_soul.up == true && _soul.right == false && top > left){
    _soul.acc.x = 0;
  }
  else if(_soul.up == true && _soul.right == false && top < left){
    _soul.acc.y = 0;
  }
  else if(_soul.up == false && _soul.right == false && bottom > left){
    _soul.acc.x = 0;
  }
  else if(_soul.up == false && _soul.right == false && bottom < left){
    _soul.acc.y = 0;
  }
 
  /*
  println("TOP: " + top + "\t" + "BOT:"  + bottom + "\t" + "LEF:" + left + "\t" + "RGT:" + right + "\t" + "U:" + _soul.up + "\t" + "R" + _soul.right);
  println("UP: " + _soul.up + "\t" + "RIGHT: " + soul.right);
  println("aY: " + _soul.acc.y + "aX:" + _soul.acc.x);
  println();
  */

}

Due for Week 3

  • Reading: Newtonian Physics, An Online Textbook (This is long, you may find Chapter 4 to be particularly relevant to this week’s discussion.)
  • Reading: The Physics Classroom — Newton’s Laws
  • Reading: Mathematics and Physics for Programmers, Chapters 12 and 14, Danny Kodicek (suggested)
  • Rework your motion sketch from week 1 using PVector. Try incorporating the concept of forces into the environment by affecting only the acceleration. Create a formula for calculating a dynamic acceleration, one that changes over time based on any number of factors. Make more than one object by creating an array.
  • Redo the basic forces examples to have a Liquid class. Make more than one liquid object. Example Answer
  • Research a force not covered in class and implement it as a vector.
  • Use the concept of forces to visualize some input (could be data, literal example would be get windspeed online and translate to a wind force in Processing, but feel free to think more abstractly)

GL Art: Week 1

Due Week 2

  • Red book (Third Edition) chapter 2 “Drawing Geometric Objects” pages 42-47
  • Get a basic OpenGL app running in Eclipse
  • Look at the DemoBasicGeometry.java code in the demo folder
  • Using the program above as a starting point, experiment with creating geometry
    — fill the screen with shapes
    — bonus points if they move
    — bonus points if they change color

Hello World
Hello World

Spring Semester 2010 Book List

Nature of Code Computational Beauty of Nature, Gary Flake
Mathematics and Physics for Programmers, Danny Kodicek

GL Art
OpenGL Programming Guide (the Red Book), Woo, Neider, Davis
Essential Mathematics for Games, James Verth

Learning Bit-by-Bit
–technical
Handbook of Fingerprint Recognition
Author: Davide Maltoni, Dario Maio, Anil K. Jain, Salil Prabhakar

*Programming Collective Intelligence
Author: Toby Segaran

*~Natural Language Processing With Python
Author: Ewan Klein, Edward Loper, Steven Bird
Online here:

http://www.nltk.org/book

~Speech and Language Processing
Author: Daniel Jurafsky and James H. Martin

~Artificial Intelligence
Author: George F. Luger

Reliable Face Recognition Methods
Author: Harry Wechsler

Handbook of Face Recognition
Edited By: Stan Z. Li, Anil K. Jain

Introduction to Machine Learning
Author: Ethem Alpaydin

–critical
Surveillance: Power, Problems, and Politics
Edited by: Sean P. Hier and Josh Greenberg Publisher: UBC Press

*Niche Envy: Marketing Discrimination in the Digital Age
Author: Joseph Turow Publisher: MIT Press

Technologies of Insecurity
Edited By: Katja Franko Aas, Helene Oppen Gundhus, Heidi Mork Lomell

~The Philosophy of Mind
Edited By: Brian Beakley and Peter Ludlow Publisher: MIT Press

*Does Technology Drive History?
Edited By: Merritt Roe Smith, Leo Marx Publisher: MIT Press, Copyright Date: 1994

Nature of Code: Week 1

Due for Week 2

  • Assignment: Sign up for the class mailing list: join-itp-noc@lists.nyu.edu
  • Assignment: Take a look at these two examples of a square randomly moving around the screen: Walker without vectors, Walker with vectors. Find an example of real-world “natural” motion (preferably in the form of an online video) and develop a set of rules for moving the Walker. Can you do it without using any random whatsoever? Without changing how the square looks at all (changing size or rotation is ok), can you give it a personality or make it appear to have an emotional quality? Create a second version with the same behavior, but with your own non-square design. Feel free to design an environment for the Walker to live in as well. We’ll compare the versions in class next week. Can we create something natural through algorithmic behaviors alone? How much does visual design play a part? Post a link to your work, as well as any thoughts on the above, on the homework wiki.
  • Reading: Processing PVector tutorial, also available as PDF.
  • Reading: Computational Beauty of Nature, Introduction, Gary William Flake (you must be logged in through NYU to access the online version.)
  • Reading: Probability Theory — great friendly site!
  • Reading:
    Mathematics and Physics for Programmers, Chapter 1 — Numbers, Danny Kodicek (optional)

More… »

Countrytime Lemonade

I’ve been in pursuit of an idea all semester that, on a sort of a whim, I decided to make the goal of my final project in Physical Computing. When I got to ITP, I had already put together a few processing sketches that modeled a system of capturing laser light in a 3D space in order to make a volumetric display. They were based off a reference design I had seen of a rotating helicoid that happens to cover all of the space in a cylinder while letting you pass light through the space at right angles.

I was inspired by Matt Parker’s lumarca which itself was based on another designer’s dream of suspending light in space using relatively cheap materials. Matt uses string suspended vertically to catch the light of a projector that has an image screened at the lens. I want to improve upon this by placing photons in space directly on moving objects. So that, with the right timing, you could fake a pretty dense object. Practically, I think a voxel could be created by dropping water, or some more refractive liquid, and shooting three lasers (r,g,b) through it.

I floated this idea on the Physical Computing listserv and basically got laughed at. (I made it even worse by suggesting that this experiment was just a step along the way to using lasers to place photons directly on the retina.) In sum, Tom Igoe, my physical computing professor and a very smart guy, kindly nudged that it was too hard for what they try to do at ITP. For me, that was a perverse motivation to keep after it.

More… »

Oh Mother!

Applications was the one class where I probably should have been keeping a blog the whole time but didn’t require me to keep it. We had some interesting people come in to give us a look at their work, such as Vita Acconci, Mya Lin, Bob Greenberg of R/GA, Craig Newmark, the design team at Antennae (who did the MTA ticket machines), the guy who is doing the interactive art for the 9/11 Memorial. We also had former students and a woman who had some interesting ideas about ambient reminders that you aren’t breathing when you use your computer.

But, we all, in groups of four or five, had to present to the full class a reaction to a speaker. Our presentation was in October (I think) and we were paired with the head of content at the New York Hall of Science in the World’s Fair Park. My group partners were Josh Clayton, Mark Triant, and Soo Yun Yun.

This was probably the hardest assignment I had all semester in terms of working in a group. There really isn’t anyone in ITP that I don’t like, but the pressure of presenting to the full class (including Red) combined with meeting these people for the first time contributed to some tense moments as we labored over the language of four questions. Josh and I were probably the farthest apart in terms of personality, but I really appreciated having the chance to speak to his Mom and get a peek of where he comes from. I would rely on Mark’s intelligence to answer a lot of very complex questions that I wouldn’t ask other people. Soo Yun is a beautiful artist and someone who draws me into being a better version of myself.

We had some ideas before visiting the museum, but it was really the experience of playing with each other and seeing how children and parents marveled at the same exhibits that led to our presentation. I noticed a father and his child both going nuts over the same optical illusion that I was bowled over by, and I thought, “wouldn’t it be interesting to call someone’s parents and ask about that moment.” We chatted about it over lunch and went with the idea. In the end, we wanted everyone to pair up with someone, call someone that knew them well, and hand over the phone to their partner who would ask these four questions:

  1. Tell me about a time this person has learned something from you.
  2. What is something you hope for this person to learn?
  3. What pushed this person to learn?
  4. What is this person up to in graduate school?

There was endless debate over these questions. Finding the right balance of text that wouldn’t be leading but also extract what we wanted was a big challenge, and at times I was overly aggressive to move things in the direction I believed in. I am usually pretty good at navigating group dynamics, but in this case, especially at ITP, there are bound to be people who are just as committed to their ideas as I am, and they’re not necessarily compatible. It was a very interesting exercise in design collaboration, as long as you don’t take it personally.

We were worried that people wouldn’t have anyone to call. That problem largely solved itself, and a few minutes after getting into the exercise (with 120+ people in pairs), I realized that it was going better than expected. I wish I had photos of the event itself. Todd Holoubek was running around with a camera, but I’m not sure what he does with all those shots.

So, we managed to succeed in getting almost everyone to call their parents and have them interviewed by a complete stranger about very personal things. This was an exercise in: getting to know your partner, getting to know yourself, sharing your experience at ITP with your loved ones, and showing how we learn at our core. Much better than hiding everyone’s shit and making them find it. We got a lot of positive feedback, and I hope that even more than the students, the parents, friends, boyfriends etc. will remember the experience.

foundData

We had an assignment in Visualizing Data that was a bit overwhelming in terms of scope and underwhelming in terms of learning a few weeks ago, so a lot of us got together into small groups to manage it. Fortunately, Rune and I found each other. Rune has some serious design skill and it turns out that he’s a mean coder too. I could learn a lot for him.. Except that that I ended up just getting out of his way for most of the work.

We were tasked to find three images that could be read in as data and then reinterpreted into a visualization. (The teaching goal was to show us a way to fake data until we could get the real thing, but I think I found that a bit too imprecise to be palatable.) Rune found an image of Hurricane Katrina that he quickly tore apart. I found a couple images of Solar Wind and one very high resolution image of the Rosetta Stone.

Hurricane Katrina

Solar Wind

Magnetosphere

Rosetta Stone

The images we used included some light cleanup such as recopying the magnetosphere in illustrator and taking some of the noise out of the rosetta stone. I spent most of my time trying to get the Rosetta Stone into Processing. The file itself is not large in terms of size – less than 2Mb, but it is huge in terms of pixels. Turns out that unpacking all of those pixels (over 39,000,000) is a task that Java sort of chokes on (at least at my skill level). I did a lot of troubleshooting on file type, file size, coding environment, java memory allocation, and after asking around, abandoned pursuit. My plan was to take the white blobs and do some kind of blob detection on them. I had hoped to visually alphabetize each “character” so you would get similar looking pieces lined up next to each other and get a rudimentary alphabet for each language (except the hieroglyphics). This was not to be. Time and frustration.

More… »

Final Project

SpaceFace was the product for the last assignment in class. We were told to keep going with a project that we felt wasn’t quite finished, and I chose After Effects because it’s the piece of software I know the least about. I just spent about 10 minutes looking this project over again and poking around to see what I could easily change to make it a “final final” project. Unfortch, I think I would have to start from scratch again to really make the changes we discussed in class, and 20 seconds of footage in After Effects is really about 6 hours or work, at least with my skill.

Katherine and I never got to making the concept of our original effort. I also abandoned it for this assignment. I’ve had an illustrator file kicking around for a while that I thought might be interesting to animate because it’s about 100+ layers making up a single object (a self portrait). I also wanted to keep going with the puppetry of NASA imagery, so I put one and one in the pot and stirred. As always at ITP, time limited the quality of the project. (Actually, I sincerely hope that I get more than a week or even a month to seriously consider most things I might design professionally, but that may not be the case). I’ll leave out the specific criticism I received in class, mostly because it’s a marker in time and should be presented here without bias, but suffice to say, there were things I learned that I agree with and would change if ever I were to revisit the piece (I’d say there’s a 50/50 shot of that).

This ended up being a sort of branding reel that might show up to advertise the production studio before the movie begins. I might take the concept and clean it up to put before anything in a portfolio.

spaceFace
SpaceFace