CS 2, Winter 2008
Programming for Interactive Digital Arts

Jan 7: Introduction


What's this course about?

Let's look at the title -- what's your perspective on these phrases?

  • Digital arts
  • Programming
  • Interactive

High-level topics covered (click images; examples from the Processing exhibition):

  • Interactive animation
    manifest haohao pond ricochet sodaprocessing
  • Image and video
    shadow monsters khronos timescape
  • Information visualization
    london tube sotu dumpster

The goal of this course is to teach you the fundamental techniques underlying works like these, and give you the chance to develop your own interactive works. To get there, we will cover topics such as how to represent and manipulate two-dimensional shapes, color, and images; how to represent and respond to input from mouse, keyboard, webcam, and the network; how to represent and simulate the movements and interactions of physical objects; and how to visually represent and explore abstract information. See the course schedule.

Administrative stuff

See course homepage and blackboard site.

  • Who, what, where
  • Homework, projects, quizzes
  • Honor code
  • Disabilities

Getting started

Walk through HW 0.

Get acquainted with the Processing environment, by playing with provided sketches; e.g., softbody:

pde screenshot screenshot

An example

The following steps build up an interactive sketch. Don't worry about the details here -- we'll do that over the next week(s). Just take it in holistically, to get a feel for what it's like to work with Processing. Each step has a link to an applet so that you can see it in action. In general, a good way to learn is to load examples into Processing yourself, and modify and play around with them. You can either download the source code from the applet page, or simply cut and paste from this page.

  1. We'll start with what's perhaps the simplest possible sketch -- an ellipse, here at position (50,50) and of size 25x25:
    ellipse(50,50,25,25);
    
    screenshot[applet]
  2. That's not interactive, but by having the Processing draw() function plot an ellipse at the current mouse position each frame, we have perhaps the simplest possible interactive sketch, a drawing program:
    // What to do every frame
    void draw()
    {
      ellipse(mouseX,mouseY,25,25);
    }
    
    screenshot[applet]
  3. Now let's make it so that we only draw when the mouse is pressed:
    // What to do every frame
    void draw()
    {
      if (mousePressed) {
        ellipse(mouseX,mouseY,25,25);
      }
    }
    
    screenshot[applet]
  4. Let's customize the set-up, and add in a splash of color:
    // Initialization
    void setup()
    {
      size(500,500);          // Make the window bigger
      smooth();               // Make the edges smoother (anti-aliased)
      background(0,0,0);      // Black background
      noStroke();             // Don't draw the border around the ellipses         
    }
    
    // What to do every frame
    void draw()
    {
      if (mousePressed) {
        // Choose random red, green, and blue components of the fill color.
        fill(random(255),random(255),random(255));
        ellipse(mouseX,mouseY,25,25);
      }
    }
    
    screenshot[applet]
  5. To make this a bit more interactive, for the next couple of steps we'll re-develop an example by Sharp Hall on the Processing exhibition.
    First, instead of ellipses, let's draw lines (from the last mouse position to the current one). Let's also have the computer draw some random squares.
    // Initialization
    void setup()
    {
      size(500,500);          // Make the window bigger
      smooth();               // Make the edges smoother (anti-aliased)
      background(0,0,0);      // Black background
      frameRate(15);          // Slow it down -- 15 frames per second
    }
    
    // What to do every frame
    void draw()
    {
      if (mousePressed) {
        // Choose random red, green, and blue components of the stroke color
        // Also make it slightly opaque (200)
        stroke(random(255),random(255),random(255),200);
        // Choose random width of the stroke
        strokeWeight(random(30));
        // Now draw a line from the current mouse position to the previous one
        line(mouseX,mouseY,pmouseX,pmouseY);
      }
      
      // Every fifth frame, draw a square
      if (frameCount % 5 == 0) {
        // Random fill color; somewhat more opaque
        noStroke();
        fill(random(0,60),random(30,80),random(80,120),100);
        // Random position; size 100x100
        rect(random(width),random(height), 100,100);
      }
    }
    
    screenshot[applet]
  6. Finally, let's give the computer an even larger role, by letting it continue our line for a bit, and even start up its own series of lines.
    // Stuff that needs to be remembered from one frame to the next
    float x, y;            // The end of the line
    float dx, dy;          // The length of the line
    float strength=0;      // Computer-drawn lines decay and fade away
    int lastLineFrame=0;   // When did the last computer-drawn line start?
    
    // Initialization
    void setup()
    {
      size(500,500);          // Make the window bigger
      smooth();               // Make the edges smoother (anti-aliased)
      background(0,0,0);      // Black background
      frameRate(15);          // Slow it down -- 15 frames per second
    }
    
    // What to do every frame
    void draw()
    {
      if (mousePressed) {
        // Choose random red, green, and blue components of the stroke color
        // Also make it slightly opaque (200)
        stroke(random(255),random(255),random(255),200);
        // Choose random width of the stroke
        strokeWeight(random(30));
        // Now draw a line from the current mouse position to the previous one
        line(mouseX,mouseY,pmouseX,pmouseY);
        // Remember this line
        x = mouseX; y = mouseY;
        dx = mouseX-pmouseX; dy = mouseY-pmouseY;
        strength = 1.0;
        lastLineFrame = frameCount;
      }
      else {
        if (frameCount - lastLineFrame > 35) {
          // Start a new random computer-drawn line
          x = random(width);
          y = random(height);
          dx = random(-8,8);
          dy = random(-8,8);
          strength = 1.0;
          lastLineFrame = frameCount;
        }
        if (strength > 0.01) {
          // Continue a decaying line kind of along the same direction
          float x2 = x, y2 = y;
          x = x+random(3*dx);
          y = y+random(3*dy);
          // Random color and weight like before; note that opacity is a function of strength
          stroke(random(255),random(255),random(255),200*strength);
          strokeWeight(random(30));
          line(x,y,x2,y2);
          // Decay
          strength = strength * 0.9;
        }
      }
      
      // Every fifth frame, draw a square
      if (frameCount % 5 == 0) {
        // Random fill color; somewhat more opaque
        noStroke();
        fill(random(0,60),random(30,80),random(80,120),100);
        // Random position; size 100x100
        rect(random(width),random(height), 100,100);
      }
    }
    
    screenshot[applet]