Week 4

Introduction to Iteration

This example by Dan Shiffman is quite nice. After this example, I’ll give a formula for the most simple case of iterating something N times, for some value N.

sketch

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com
// Example 6-1: Many lines

function setup() {
    createCanvas(480, 270);
    background(255);
    // Legs
    stroke(0);
    line(50,60,50,80);
    line(60,60,60,80);
    line(70,60,70,80);
    line(80,60,80,80);
    line(90,60,90,80);
    line(100,60,100,80);
    line(110,60,110,80);
    line(120,60,120,80);
    line(130,60,130,80);
    line(140,60,140,80);
    line(150,60,150,80);
}

preiter

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com
// Example 6-2: Many lines with variables

function setup() {
    createCanvas(480, 270);
    background(255);
    // Legs
    stroke(0);
    var y = 80; // Vertical location of each line
    var x = 50; // Initial horizontal location for first line
    var spacing = 10; // How far apart is each line
    var len = 20; // Length of each line
    // Draw the first leg.
    line(x, y, x, y + len);
    // Add spacing so the next leg appears 10 pixels to the right.
    x = x + spacing;
    // Continue this process for each leg, repeating it over and over.
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
    x = x + spacing;
    line(x, y, x, y + len);
}

iter

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com
// Example 6-6: Legs with a for loop

function setup() {
    createCanvas(480, 270);
    background(255);

    var y = 80; // Vertical location of each line
    var spacing = 10; // How far apart is each line
    var len = 20; // Length of each line

    // Translation of the legs while loop to a for loop.
    for (var x = 50; x <= 150; x += spacing) {
        line(x, y, x, y + len);
    }
}

Exercise: Write code to draw 10 boxes across a canvas.

 

    To write a for loop:

  1. Pick a variable name (let’s say VARNAME)
  2. Pick a STARTINGVALUE
  3. Pick an INCREMENT
  4. Pick a LIMIT that is one greater than the last value of VARNAME
  5. Decide WHAT_TO_DO with each value of VARNAME
  6. Fill in the template:

    for (var VARNAME = STARTINGVALUE; VARNAME < LIMIT; VARNAME += INCREMENT) {
        WHAT_TO_DO;

    }

The most common case is i = 0, 1, 2, 3, …, n-1:

for (var i = 0; i < n; i += 1) {
    WHAT_TO_DO;
}

Note that i takes on n different values. Because we start numbering at 0, the last value of i is n-1, not n. Make sure you understand this! It’s confusing at first, but if you always start counting at 0, and if the limit is always n, the number of times you want the loop to run, and if you always write i < n (never write i <= n even though Dan Shiffman did it) then you’ll be programming like a pro.

Example of N Iterations

Here’s an example: Draw 5000 random rectangles. This will change every time you reload the page.

rndrect

function setup() {
    createCanvas(200, 200);
    background(200);
    for (var i = 0; i < 5000; i++) {
        fill(random(200), random(200), random(200));
        rect(random(400), random(400), random(50), random(50));
    }
    noLoop(); // turn off looping
}

function draw() {
}

Using var in for Loops

You can write for (i = ...) rather then for (var i = ...). The difference is that if you write var, you are declaring the loop variable to be a local variable. You can get the same effect by writing var i; for (i = ...). If you do not write var, you might be declaring or reusing a global variable, which might have unintended side effects. You will usually get away with it, but you can’t afford to live so dangerously because the problems will be very subtle and mysterious. Declaring the loop variable with var is equivalent to declaring the variable (but not initializing it) at the beginning of the function.

Optional reading/exercise

w3schools for loop

More Examples of For Loops

sketch

function setup() {
    createCanvas(600, 400);
}

function draw() {
    background(200)
    for (var i = 0; i < 10; i++) {
        rect(i*50, 200, 25, 25);
    }
}

// above is equivalent to

// function draw() {
//     rect(0, 200, 25, 25);
//     rect(50, 200, 25, 25);
//     rect(100, 200, 25, 25);
//     rect(150, 200, 25, 25);
//     rect(200, 200, 25, 25);
//     rect(250, 200, 25, 25);
//     rect(300, 200, 25, 25);
//     rect(350, 200, 25, 25);
//     rect(400, 200, 25, 25);
//     rect(450, 200, 25, 25);
// }

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry

function setup() {
    createCanvas(600, 400);
    strokeWeight(8);
}

function draw() {
    background(200);
    for (var i = 20; i < 400; i += 60) { // try changing "60" to other numbers
        line(i, 40, i + 60, 80);
    }
}

// above is equivalent to

// function draw() {
//     line(20, 40, 80, 80);
//     line(80, 40, 140, 80);
//     line(140, 40, 200, 80);
//     line(200, 40, 260, 80);
//     line(260, 40, 320, 80);
//     line(320, 40, 380, 80);
//     line(380, 40, 440, 80);
// }

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry

function setup() {
    createCanvas(480, 240);
    strokeWeight(2);
}

function draw() {
    background(200);
    for (var i = 20; i < 400; i += 20) {
      line(i, 0, 1.5*i, 120);
    }
}

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry

function setup() {
    createCanvas(480, 240);
    strokeWeight(2);
}

function draw() {
    background(200);
    for (var i = 20; i < 400; i += 20) {
      line(i, 0, 1.5*i, 120);
      line(1.5*i, 120, 1.2*i, 240);
    }
}

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry

// SEE ALSO: nested_loops1

function setup() {
    createCanvas(600, 400);
    noStroke();
}

function draw() {
    background(0);
    for (var y = 0; y < height+25; y += 50) {
      fill(255, 140);
      ellipse(0, y, 50, 50);
    }
    for (var x = 0; x < width+25; x += 50) {
      fill(255, 140);
      ellipse(x, 0, 50, 50);
    }
}

Practice Exercises

screen-shot-2016-09-21-at-8-25-55-am

screen-shot-2016-09-21-at-8-26-54-am

screen-shot-2016-09-21-at-8-30-52-am

screen-shot-2016-09-21-at-8-34-12-am

screen-shot-2016-09-21-at-8-35-58-am

Functions

Today we introduce functions. Not just calling functions (such as rect). Not just defining function (such as draw). We will talk about:

  • Inventing your own concept or abstraction.
  • Defining your own function to implement that concept.
  • Calling your function.

You can read more online about functions here

Exercise: Modify the example at w3schools to compute the quotient of two numbers. Modify the function call to compute 600 / 23.

Here’s a simple program:

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry

function setup() {
    createCanvas(480, 120);
}

function draw() {
    background(204);
    
    // Left owl
    translate(110, 110);
    stroke(0);
    strokeWeight(70);
    line(0, -35, 0, -65); // Body
    noStroke();
    fill(255);
    ellipse(-17.5, -65, 35, 35);  // Left eye dome
    ellipse(17.5, -65, 35, 35);   // Right eye dome
    arc(0, -65, 70, 70, 0, PI);   // Chin
    fill(0);
    ellipse(-14, -65, 8, 8);  // Left eye
    ellipse(14, -65, 8, 8);   // Right eye
    quad(0, -58, 4, -51, 0, -44, -4, -51); // Beak
    
    // Right owl
    translate(70, 0);
    stroke(0);
    strokeWeight(70);
    line(0, -35, 0, -65); // Body
    noStroke();
    fill(255);
    ellipse(-17.5, -65, 35, 35);  // Left eye dome
    ellipse(17.5, -65, 35, 35);   // Right eye dome
    arc(0, -65, 70, 70, 0, PI);   // Chin
    fill(0);
    ellipse(-14, -65, 8, 8);  // Left eye
    ellipse(14, -65, 8, 8);   // Right eye
    quad(0, -58, 4, -51, 0, -44, -4, -51); // Beak
}

Here’s a version using function definition:

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry


function setup() {
    createCanvas(480, 120);
}

function draw() {
    background(204);
    owl(110, 110);
    owl(180, 110);
}

function owl(x, y) {
    push();
    translate(x, y);
    stroke(0);
    strokeWeight(70);
    line(0, -35, 0, -65); // Body
    noStroke();
    fill(255);
    ellipse(-17.5, -65, 35, 35); // Left eye dome
    ellipse(17.5, -65, 35, 35);  // Right eye dome
    arc(0, -65, 70, 70, 0, PI);  // Chin
    fill(0);
    ellipse(-14, -65, 8, 8); // Left eye
    ellipse(14, -65, 8, 8);  // Right eye
    quad(0, -58, 4, -51, 0, -44, -4, -51); // Beak
    pop();
}

We can even make owls inside a for loop:

sketch

// Getting Started with p5.js
// Lauren McCarthy, Casey Reas, Ben Fry

function setup() {
    createCanvas(480, 120);
}

function draw() {
    background(204);
    for (var x = 35; x < width + 70; x += 70) {
        owl(x, 110);
    }
}

function owl(x, y) {
    push();
    translate(x, y);
    stroke(0);
    strokeWeight(70);
    line(0, -35, 0, -65);  // Body
    noStroke();
    fill(255);
    ellipse(-17.5, -65, 35, 35);  // Left eye dome
    ellipse(17.5, -65, 35, 35);   // Right eye dome
    arc(0, -65, 70, 70, 0, PI);   // Chin
    fill(0);
    ellipse(-14, -65, 8, 8); // Left eye
    ellipse(14, -65, 8, 8);  // Right eye
    quad(0, -58, 4, -51, 0, -44, -4, -51); // Beak
    pop();
}

Nested Function Calls

You can call functions from within functions. Here is a program to draw a house. It decomposes the house into components and uses a function to draw each one. You can imagine how this could really be helpful in a much more complex drawing. (Warning: Do not make a function called window because window is already used by p5js.)

complex

// this example uses functions to give names to collections
// of related operations (as in house = roof + window + door +...)
// or simply to say that, e.g., the triangle is really
// the implementation of "roof"

function setup() {
    createCanvas(400, 400);
    frameRate(10);
}

var x = 100;

function draw() {
    background(150, 200, 150);
    house(computeX(mouseX), computeY(mouseX));
    house(mouseX + 100, mouseY + 20);
    push();
    scale(0.1);
    for (var i = 0; i < 20; i = i + 1) {
        house(mouseX + 100 + i * 150, mouseY + 100);
    }
    pop();
}

function computeX(x) {
    return sin(x) * 50 + 50;
}

function computeY(y) {
    return -cos(y) * 50 + 50;
}

function house(x, y) {
    roof(x, y);
    rect(x + 20, y, 160, 100); // main building
    door(x, y);
    aWindow(x, y);
}

function roof(x, y) {
    triangle(x, y, x + 100, y - 50, x + 200, y);
}

function door(x, y) {
    rect(x + 100, y + 30, 30, 70);
}

// I'm afraid "window" might refer to the current window of the
// browser or p5.js frame, so I'm using a safer function name:
function aWindow(x, y) {
    rect(x + 50, y + 30, 30, 30);
}

Parameters

We call the actual values you list between parentheses when you call a function arguments. When you call point(20, 50), the arguments are 20 and 50.

When you define a function, you can provide parameters which act just like new local variables that are initialized to the arguments provided by the caller. Read this sentence again. It’s important! Here’s an example where we define house with location parameters x and y.

Exercise: Explain how parameters are used in the previous examples.