CS 2, Winter 2009
Programming for Interactive Digital Arts

Jan 5: 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
    unbearable lightness chronodraw without title
  • Motion
    manifest pond ricochet
  • Image and video
    shadow monsters khronos timescape

Closer to home, take a look at some of the works produced last year, following the [ex] links in the "due" column on last year's schedule page.

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; and how to represent and simulate the movements and interactions of physical objects. See the course schedule.

Administrative stuff

See course homepage and blackboard site.

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

Getting started

Walk through SA 1.

Get acquainted with the Processing environment, by playing with provided sketches; e.g., Topics | Simulate | 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:
    // An ellipse with center at (50,50) and size of 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()
    {
      // An ellipse with center at (mouseX,mouseY) and size of 25x25
      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()
    {
      // Only when the mouse button is held down...
      if (mousePressed) {
        // An ellipse with center at (mouseX,mouseY) and size of 25x25
        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]