Homework 8: Processing Animation

Update: example solutions posted.

Due: Thursday Dec 6, 11:59PM.

To submit: Send an email to me at jal2016@email.vccs.edu with subject CSC 110 HW8 with your program(s) attached in a zip file.

Note that every Processing program consists of a directory with one or more .pde files inside. Simple programs will have just a single file, that by default will have the same base name as the directory. Your zip file should preserve the directory structure.

For any problems that require just a single file (like both programs for this homework), your source files and directories should be named with the form NAME_HW#_PROBLEM#.pde. For example, I would save problem #2 for this assignment with the name lepak_hw8_2.pde. Include a comment at the top of all programs that you submit, of the following form (shown for my same example):

// Joel Lepak
// CSC 110 HW8 #2
  1. Modify the following program so that the circle changes color when the mouse passes over it.

    // HW8 Circle starting point.
    
    void setup() {
        size(300, 300);
        noStroke();
    }
    
    float diam = 30;
    
    // This function is called once per frame.
    void draw() {
        // Clear to a new green background.
        background(0, 255, 0);
        // Draw circle
        ellipse(width/2, height/2, diam, diam);
    }
    
    // HW8 Circle
    
    void setup() {
      size(300, 300);
      smooth();
      noStroke();
      // Initialize circle center
      centerX = width/2;
      centerY = height/2;
    }
    
    // Circle diameter and center.
    float diam = 100;
    float centerX, centerY;
    
    // This function is called once per frame.
    void draw() {
      // Clear to a new green background.
      background(0, 255, 0);
    
      // Set fill color based on whether mouse is inside
      // circle, by checking distance from circle center.
      if (dist(mouseX, mouseY, centerX, centerY) < diam/2) {
        fill(0);
      }
      else {
        fill(0xFF);
      }
      // Draw circle
      ellipse(width/2, height/2, diam, diam);
    }
    
  2. Modify the program from #1 so that you can "bump" the circle with the mouse to push it around. Make the "bump" strength depend on how fast the mouse was moving when it hit the ball. This could be the starting point for an interactive billiards simulation. You might need to define an acceleration/deceleration rate and set up variables to track location and velocity. You might also need to think about how to handle the bumping so that you don't allow another accidental bump immediately after the first.

    // HW8 Circle
    
    void setup() {
      size(300, 300);
      smooth();
      noStroke();
      // Initialize circle center
      centerX = width/2;
      centerY = height/2;
    }
    
    // Circle diameter, center, and velocity
    float diam = 50;
    float radius = diam/2;
    float centerX, centerY;
    float vX = 0;
    float vY = 0;
    
    // Variable used to make sure we don't register
    // more than 1 "hit" if when we run into the ball.
    boolean hitLastFrame = false;
    
    // Variable to control how quickly ball slows down.
    // 1 => never stops.
    float damping = 0.96;
    
    // Control how mouse speed relates to ball speed
    // when ball is hit.  Lower => slower.
    float impactFactor = 0.5;
    
    // This function is called once per frame.
    void draw() {
      // Clear to a new green background.
      background(0, 255, 0);
    
      // Set fill color based on whether mouse is inside
      // circle, by checking distance from circle center.
      if (dist(mouseX, mouseY, centerX, centerY) < radius) {
        fill(0);
    
        // Check hitLastFrame to see if we have already
        // registered the hit
        if (!hitLastFrame) {
          float mouseSpeed = dist(mouseX, mouseY, pmouseX, pmouseY);
          float pushX = (centerX - mouseX)/radius;
          float pushY = (centerY - mouseY)/radius;
    
          vX = vX + pushX * mouseSpeed * impactFactor;
          vY = vY + pushY * mouseSpeed * impactFactor;
          println("vX = " + vX + ", vY = " + vY);
        }
        hitLastFrame = true;
      }
      else {
        fill(0xFF);
        hitLastFrame = false;
      }
    
      // Update ball position
      centerX = centerX + vX;
      centerY = centerY + vY;
    
      // Handle bouncing off sides.
    
      // Bouncing means velocity is reversed.
      // Check to see if it hits left or right side.
      if (centerX + diam/2 > width)
        vX = -abs(vX);
      if (centerX - diam/2 < 0)
        vX = abs(vX);
    
      // Check to see if it hits top or bottom.
      if (centerY + diam/2 > height)
        vY = -abs(vY);
      if (centerY - diam/2 < 0)
        vY = abs(vY);
    
      // Damp ball velocity so that it eventually slows to
      // a stop.
      vX = vX * damping;
      vY = vY * damping;
    
      // Draw ball.
      ellipse(centerX, centerY, diam, diam);
    }
    
  3. Examine the program below. Explain what it is doing, and modify the variables or other drawing settings so that it draws a more interesting picture that uses the same idea.

    // Polar coordinates.
    
    // Basic setup.
    size(300, 300);
    noStroke();
    fill(255, 100, 100);
    background(100, 100, 255);
    
    float angle = radians(144);
    float radius = 100;
    
    // See http://processing.org/reference/ for details.
    translate(width/2, height/2);
    
    beginShape();
    for (int i = 0; i < 360; i = i + 1) {
      float theta = i * angle;
      float x = radius * cos(theta);
      float y = radius * sin(theta);
      vertex(x, y);
    }
    endShape();
    

    The program is drawing a picture using polar coordinates. angle defines how much the drawing turns for each new point, and radius defines how far out from the center each point is drawn. Here's an example that changes the radius as we go along, and uses a different drawing angle:

    // Polar coordinates.
    
    // Basic setup.
    size(300, 300);
    smooth();
    stroke(255, 100, 100);
    strokeWeight(2);
    noFill();
    background(100, 100, 255);
    
    float angle = radians(50);
    float radius = 100;
    
    // See http://processing.org/reference/ for details.
    translate(width/2, height/2);
    
    beginShape();
    for (int i = 0; i < 360; i = i + 1) {
      float theta = i * angle;
      float x = (i/3.0) * cos(theta);
      float y = (i/3.0) * sin(theta);
      vertex(x, y);
    }
    endShape();