tutorial 1.3:

drawing a circle with loops



Introduction: Loops
A loop is an incredibly useful tool in programming. Using a loop you can repetitively perform a particular block of code until a condition that you define is met. Loops consisting of just a few lines can easily replace hundreds of lines of hardcoded instructions. Just because a loop repeats the same instructions over and over, it doesn't have to do exactly the same thing each time around.



It's essential that you specify when the loop will end. So-called endless loops will cause your sketch to become sluggish and (eventually) crash. You can specify that a loop should end after a particular number of iterations, or when a condition that you specify is met.



There are several types of loops. The type that we'll use most often in this class is known as the 'for' loop: this allows you to repeat a block of code until a specific condition has been met. Another useful type is the while loop, which repeats a block of code until a given condition that you specify ceases to be true.



Loops example
We'll begin with the 'makeCircle' function that we wrote in the last tutorial. Here's the function:

/*
Function makeCircle
 parameters: circle radius, circle color, x-position, y-position
 purpose: creates a circle with the desired parameters
 */
void makeCircle(int myRadius, int myColor, int myX, int myY) {
   stroke (myColor);
   ellipse(myX, myY, myRadius, myRadius);
}

What we're going to do in this example is simply to add a loop within the draw() function, creating a number of concentric circles. We can use a 'for' loop because we want to repeat the loop a specified number of times. Let's first create a global variable to store the diameter of the circle:

int diam; // the diameter of the current circle

The 'for' loop consists of the following parts (text borrowed from PHP.net): Syntax

 for (init; condition; increment)
  {
  code to be executed;
  }

Parameters:



  • init: Mostly used to set a counter variable (but can be any code to be executed once at the beginning of the loop)

  • condition: Evaluated for each loop iteration. If it evaluates to TRUE, the loop continues. If it evaluates to FALSE, the loop ends.

  • increment: Mostly used to increment a counter (but can be any code to be executed at the end of the iteration)



Note: The init and increment parameters above can be empty or have multiple expressions (separated by commas).



We can then use this value in a revised version of the draw() function:

void draw() {
  for (diam=10;diam<=width;diam+=10) {
    makeCircle(diam, myGreyscale, myXPosition, myYPosition);
  }
}

In this version of the draw() function we've created a 'for' loop which uses the global variable called 'diam', increasing the value of diam with each loop by 10 until diam reaches the edge of the Processing window.



Conditionals:
According to wikipedia, conditional statements are 'features of a programming language which perform different computations or actions depending on whether a programmer-specified boolean condition evaluates to true or false.' We've already seen an example of a conditional statement in the 'for' loop: the middle parameter of a 'for' loop is always a condition that evaluates to true or false. Values that are always either true or false are very useful in programming and are known as booleans.



You can use conditional statements and booleans for all kinds of purposes in your code, and it's unlikely you'll write any code this semester that doesn't include at least one conditional statement.



One use for a conditional statement is to highlight objects that meet some criterion that you set. For example, we may want to highlight those circles whose ID number is divisible evenly by 3; we can do this with a slight modification of our makeCircle function.

void draw() {
  fill(150,15); //this creates a semi-transparent fill for each circle
  for (diam=10;diam<=width;diam+=10) {
    if ((diam%50) == 0) {
        myGreyscale = 200;
      } else {
        myGreyscale = 250;
      }
    println ("myGreyscale is "+myGreyscale);
    makeCircle(diam, myGreyscale, myXPosition, myYPosition);
  }
}

We've just added two lines of code; a conditional statement that checks whether this ID is evenly divisible by 3. We do this check using a built-in function called modulo which is represented with a '%': this is the remainder when two numbers are divided. This turns out to be a useful function for identifying patterns within a loop.



Using more functions you could also highlight circles based on whether it is odd or even, or whether it is a prime number.



Here's the full code:

/*
November 2014
 CD 1
 Mark Meagher and Adam Park
 makeCircle function
 */

int myXPosition; //X position of the circle
int myYPosition; //Y position of the circle
int myGreyscale = 200; //color of the circle
int diam;

void setup() {
  size(400, 400, P2D);
  background(240);
  frameRate(24);
  smooth();
  myXPosition = width/2;
  myYPosition = height/2;
//  stroke(0);
  strokeWeight(1);
  noFill();
  print("X-position is "+myXPosition);
}

/*
Function makeCircle
 parameters: circle radius, circle color, x-position, y-position
 purpose: creates a circle with the desired parameters
 */
void makeCircle(int myRadius, int myColor, int myX, int myY) {
  stroke (myColor);
  ellipse(myX, myY, myRadius, myRadius);
}

void draw() {
  fill(150,15); //this creates a semi-transparent fill for each circle
  for (diam=10;diam<=width;diam+=10) {
    if ((diam%50) == 0) {
        myGreyscale = 200;
      } else {
        myGreyscale = 250;
      }
      println ("myGreyscale is "+myGreyscale);
    makeCircle(diam, myGreyscale, myXPosition, myYPosition);
  }
}

Exercises:



1- Expand the Processing window and create a concentric set of 100 or more circles. How many circles can you draw before there's a noticeable lag in performance?



2- Create a row of 100 or more circles, highlighting only those circles whose ID is a prime number (you can use the function here to check for primes). How many circles can you draw now before there's a noticeable lag in performance?