EARTH 801
Computation and Visualization in the Earth Sciences

Lesson 3: If Statements

PrintPrint

Syntax introduced: if width || *= && == != height frameRate

In the program on the previous page, the lightning bolt traveled off the screen, never to be seen from again, drawing itself in the ether outside of our window. That's not fun! Let's fix it.

0. If statements

An if statement is a way to change a program's behavior depending on some event. It reminds me a lot of the way natives of Pittsburgh use the word "whenever." (As in, "Whenever you are going to the store will you buy me some eggs?" Only western Pennsylvanians have this usage. I think it is weird.) You write an if statement like this:

if (thing you are testing) {

   do something

}

The test is enclosed in parentheses, and the commands to execute if the test turns out to be true are enclosed in curly braces. When Processing sees an if statement, it checks whether the test is true and if it is true, it executes the commands between the braces, then goes on with the rest of the program. If the test turns out not to be true, it ignores all the commands inside the curly braces and moves on to the rest of the program. Okay, back to our lightning bolt! In kind-of English, one way to fix the earlier program is to write something like,

if (the lightning bolt gets to the far right edge of the window) {

   start over again on the left side

}

We can do that! Here's how:

We add some lines of code to our program that say:

if (x == width) {

   x = 0;

}

That is the code translation of what we wrote in English up above. Now the lightning bolt will move along horizontally and when it gets to the right edge of the display window it will jump back to the left edge and start over.

1. The difference between = and ==

The == part is a logical operator that means equality. We are testing whether or not two values are equal to each other, in this case x and the width of window. We already set the width when we specified it using size(400,200), so Processing knows that the value of width is 400 already. Therefore you don't have to write "400" explicitly. It's almost always better to refer to a variable than to write an actual number because then if you change the size of the window, the program will still work the way you intended. Otherwise you'd have to hunt down all the places you wrote 400 and change them to the new width.

Below the line that says if (x==width){, I wrote x=0; I am not testing for equality, I am setting x equal to zero. That's the difference between one = sign and two of them. There are other logical operators, such as > (greater than), < (less than), >= (greater than or equal to), <= (less than or equal to), != (not equal to), && (and).

So basically, the if test we wrote won't kick in (Processing will evaluate it as false) until the lightning bolt gets to the far right of the display window. Until then, Processing will check whether or not the value of x is equal to the width of the display window. As long as it is not, then it will not reset the value of x to zero. It will ignore that command. Once the value of x reaches the value that is the width of the display window, Processing will reset the value of x to zero and go on with the program, incrementing x until it reaches the value of width again. It goes forever until you stop the program.

2. Other games you can play

What if we want to make the lightning bolt move faster? Change the line where we are incrementing the value of x to something like:

 

x = x + 5;

What if we want to make the lightning bolt move slower? Change the line where were are incrementing the value of x to something like:

x = x + 0.5;

3. Float variables

There's no rule that says we have to use whole numbers, except for the fact that when we first declared x in our program, we declared it as an integer. That means we cannot give it a fractional part. Therefore if you write x=x+0.5 like I suggested you try out, you will get an error telling you "cannot convert from float to int." What's that about?

If we want to be able to allow x to have a fractional part, we need x to be a floating point number instead of an integer. These are called "floats" in Processing. A float is a floating-point number, which is a number that is not an integer, such as 1.5 or PI (π). Why bother with the difference between ints and floats? Why not just call them all “numbers” or something? Well, one difference between a float and an int is the amount of memory your computer has to allocate to store it. Also, integers are precise and floats are not.  
Let’s say I have a cookie. I can declare int numCookie = 1 to tell Processing that I have exactly one cookie. If I’m going to share it with 6 other friends of mine I will break it into seven pieces. If I am really accurate at cookie-breaking we will all get exactly one seventh of the cookie. We can write this precisely as 1/7 on paper. However, if we wanted to express that in a Processing program, we’d probably declare something like

float cookiePortion0 = 0.14;
float cookiePortion1  = 0.14;
float cookiePortion2  = 0.14;
float cookiePortion3  = 0.14;
float cookiePortion4  = 0.14;
float cookiePortion5  = 0.14;
float myCookiePortion = 0.14;

If we add up all the floats we get 0.98, not 1. We could write out each number to more decimal places. 1/7 is actually 0.142857 . . .  but it is a repeating decimal. We can’t write an infinite number of digits past the decimal because we don’t want our entire computer’s memory taken up by deciding how much of a cookie each person is getting. The computer has to truncate the number at some point, and it will probably be good enough, but it is not perfect. That's the difference between an int and a float.

In our lightning bolt program, we'll change the declaration of the variable x up at the top to say

float x = 10;

and then we are all set to increment x by a float later on in the program.

We also don't have to make the lightning bolt move from right to left. It can go wherever we want, limited by imagination only.

To make it go down instead of sideways, increment y instead of x, like so:

y++;

if (y == height) {

   y = 0;

}

If you want the lightning bolt to move diagonally, change both x and y with each loop through draw.

If you want the lightning bolt to move back and forth, you have to find a way to use the if test to change the direction of motion in x or y or both. Try it yourself and then check my screencast below to see how I did it.

cartoon Eliza alerting you that instructions come nextHere's a screencast example of a program in which the lightning bolt moves back and forth horizontally across the screen.
Screencast of moving lightning bolt.
E. Richardson

4. Whether to put background() inside of setup() or draw()

Simply put, if you place a call to background() inside draw(), then it is the equivalent of erasing the screen with each run through draw(), which makes it look like the object is moving because the human eye can't refresh as fast as your computer display and Processing makes a run through draw() with each new frame your computer draws to its screen. On the other hand, if you put the call to background() inside setup(), you will draw over your previous iterations, without erasing them, essentially leaving a trail of an object's previous positions. Check out the program below. It draws a pink display window on which an orange circle is moving back and forth while a black line moves up and down.

float y = 0.0;
float x = 0.0;
float ell_direction = 1;
float line_direction = 1;

void setup() {
   size(200, 200);
}

void draw() {
   background(234, 128, 128);
   frameRate(60);
   stroke(51, 34, 45);
   line(0, y, width, y);
   y = y + (1 * line_direction);
   fill(245, 166, 47);
   ellipse(x, height / 2, 10, 10);
   x = x + (0.5 * ell_direction);
  
   if (x > width || x < 0) {
    ell_direction = ell_direction * (-1);
   }
  
   if (y > height || y < 0) {
     line_direction = -line_direction;
   }
}

Try cutting and pasting the line that says background(234, 128, 128); out of draw() and into setup() and run it again. What happens?

Exercises:

3.1 Write a program that moves a custom shape diagonally across the screen and changes direction if it encounters any of the sides of the display window.

3.2 Modify your program from Exercise 3.1 so that the shape also changes color if it hits any of the sides of the display window

Turning in your work:

Submit Exercise 3.2 to its appropriate assignment in the Lesson 3 module in Canvas. Name your file lastname3.2.pde

What I'm looking for:

Your program should demonstrate correct usage of an if statement to change the direction and fill and/or stroke color of your shape. Your shape should be a custom shape drawn using beginShape() and endShape(). Extra creativity such as using a for loop to set the vertices, or creating a composition with more than one shape is encouraged!