EARTH 801
Computation and Visualization in the Earth Sciences

Lesson 8: Arrays

PrintPrint

New syntax discussed: [], ., new

Arrays

Now we are ready to work with a new variable type called an array. An array is like a matrix. It is a variable that holds a bunch of the same type of data instead of just one piece of data. Arrays are useful for storing lists of similar things because it insulates you from having to declare so many variables. Declaring an array is similar to declaring other variables such as ints, floats, and strings, but you have to say what kind of data the array will store and use the square brackets [ ] so Processing knows that you want to make an array of that type of data.

For example, if you want to declare three integer variables called "x1", "x2", and "x3" and assign them the values 0, 25, and 6, here is one way to do it (hopefully this is old hat by now):

int x1 = 0;
int x2 = 25;
int x3 = 6;

But you could make an array of integers instead. Let's do that and call the array "x." There are a few different ways to do this. Here they are:

Way #1: declare, create, and assign in three different steps

int[] x; //declare it here. I'm telling Processing 
//to make an array of integers called "x"

void setup() {
   size(400, 400);
   x = new int[3]; // Creating it with the "new" command.
   x[0] = 0;       // Assigning values to each element.
   x[1] = 25;
   x[2] = 6;
}

void draw() {

// The rest of the program

}

In the program above, we first told Processing we wanted to make an array of integers called "x". Then inside the setup block we created the array using new and inside of the square brackets we tell Processing how big x will be, meaning how many integers it will hold. This allows your computer to allocate the right amount of memory to store the array. Then we assign values to each element in x. Remember that you always start counting at zero, not one in Processing! That means the first element of the array is denoted x[0], and the second element of the array is denoted x[1]. The number inside the square brackets tells you which element it is, not the value of that element. For example, x[2] = 6; means that the third element of the integer array x is assigned the value 6.

Way #2: declare, create, and assign in two steps

int[] x = new int[3]; //declare and create it here

void setup() {
   size(400, 400);
   x[0] = 0; //assigning here
   x[1] = 25;
   x[2] = 6;
}

void draw() {

//the rest of the program

}

In the above example, we declared the array of integers up at the top before the setup() block. When we declared it we also told Processing how many elements the array would have in it. So we saved a step compared to the first example. Since we did this up at the top of the program before setup(), the array x is available inside both setup() and draw(). We are filling up the array with values later on the program. It is important to note that there is a difference between an empty element in an array and an element that is assigned the value zero. When we wrote the command

int[] x = new int[3];

This told Processing to make an array that has room for three integers but we didn't tell it what those integers would be. Until we do, the array is empty, which means that there are no values assigned to it. When we wrote

x[0] = 0;

We assigned the value zero to the first spot in the array, which was previously nothing.

Way #3: declare, create, and assign all in one step

int[] x = {0, 25, 6};

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

void draw() {

//rest of the program

}

In the example above, you don't have to use new if you do the declaration, creation, and assignment all at the same time. And you don't have to tell Processing how big the array is going to be because you are assigning the spots in the array to numbers right away.

Using arrays to draw a shape

The examples above told you how to make an array, but those programs don't really do anything, do they? So here's an example of a program that uses an array to draw a shape:

//use two arrays to draw a star

int[] a= {20, 40, 20, 40, 50, 60, 80, 60, 80, 50};
int[] b = {20, 45, 60, 60, 80, 60, 60, 45, 20, 35};

void setup(){
  size(100,100);
  noLoop(); //just a static shape drawn once
}

void draw(){
  beginShape();
  for (int i = 0; i< a.length; i++){
    vertex(a[i], b[i]);
  }
  endShape(CLOSE);
}
output of star-drawing program
Display window output of the star-drawing program
E. Richardson
cartoon Eliza alerting you that instructions come next

In the program above, I declared, created, and assigned two arrays at the beginning of the program before setup() and draw(). Inside setup() I just set the size of the display window. Inside draw() I made a beginShape()/endShape() pair and in between them I wrote a for loop that loops through the arrays and sets the vertices one by one. This is the first time you have seen the dot operator . in a program. The dot operator in Processing is used to access some attribute of the variable and it is analogous to an apostrophe in English to designate possession. For instance, when I wrote a.length that means in English "the length of the array called a," or "a's length." For an array, its length is the number of elements in it, so a.length == 10 in the star-drawing program.

2. Use a for loop to assign elements to an array

It is also useful to use a for loop to fill up an array with numbers instead of assigning each element by hand. Here's an example of a program that does this:

//five balls, each ball is faster than the one above it
	int num = 5;
	float[] xpos = new float[num];
	float[] speed = new float[num];
	float dy = 60;

	void setup(){
	size(400,400);
	for (int i = 0; i<num; i++){
	  xpos[i] = i;
	  speed[i] = i+0.1;
	  }
	}

	void draw(){
	background(0);
	for (int i = 0; i<num; i++){
	  float y=(i+dy)*i;
	  ellipse(xpos[i],y,20,20);
	  xpos[i]+=speed[i];
	  if (xpos[i]>width-10){
	    xpos[i]=0;
      } 
   }

Here is a 12 second video demonstrating the code above (video is silent).

Quiz Yourself!

3. Store mouseX and mouseY history in arrays

Another useful thing to do with arrays is to use them store the history of mouseX and mouseY positions.

Here is an example of that:

//snake of circles follows the mouse

int num = 50;
int[] x = new int[num];
int[] y = new int[num];

void setup(){
   size(400, 400);
   noStroke();
   smooth();
   fill(2S5, 100);

}

void draw(){
   background(0);
   //go backwards through the loop
   //and shift all values to the right
   for (int i = num-1; i>0; i--){
      x[i] = x[i-1];
      y[i] = y[i-1];
   }
   //put current values of mouseX and mouseY at beginning
   x[0] = mousex;
   y[0] = mouseY;
   
   //draw circles
   for (int i = 0; i < num; i++){
	  ellipse(x[i],y[i], 20, 20);
   }
}
cartoon Eliza alerting you that instructions come next

In the program above, I declare and create two arrays before setup() and draw(). I use setup() for the usual things. Inside draw() there is a for loop that steps backwards through the two arrays and shifts all the array values to the right, then adds the current values of mouseX and mouseY to the beginning of each array. Think of this as a conveyer belt that runs from left to right. You are continuously adding a new value to the left side while the rightmost value falls off the other side and gets thrown away. Then I use another for loop that goes forwards through the array to draw all the circles. The whole effect is that a trail of however many circles assigned to the value "num" (in this case 50) follow the mouse around like a snake.