March, 2014

In the first tutorial we had a look at basics notions of programming such as syntax, types, variables, control flow, scope and functions. We are going to look at two more basic concept in this tutorial, which are Arrays and Classes, and illustrate them with a first example often used in generative design, as an agent or particle.

Our Particle.

First, I will introduce the code for the particle that we will use as an example. A particle represents a position in space and possibly other attributes such as velocity, direction or mass. At each iteration (for example at each call to draw()) the position of the particle will be updated. We are going to use a particle in 2D, which has a velocity vector . A vector is a geometric quantity having a magnitude and a direction. In this case, since it is a 2D vector, it will have an x and y component, which we are going to define through variables vx and vy.

float posx, posy; //position of particle
float vx, vy; //velocity vector
void setup(){
size(500,500);
//we use ellipseMode to draw the ellipses from
//the centre. Check reference if you want to know more.
ellipseMode(CENTER);
noFill(); //we don't want them filled
//here we use the random function to generate
//a random number within a range. We use also
//width and height to get the screen dimensions
posx=random(0,width);
posy=random(0,height);
vx=random(-2,2);
vy=random(-2,2);
}
void draw(){
background(255); //draw the background, white
stroke(0,100,255);
ellipse(posx, posy, 20,20);
stroke(0,0,0);
//draw vx and vy, from posx and posy, 10 times bigger
line(posx,posy,posx+vx*10,posy+vy*10);
//AND NOW WE UPDATE THE POSITION
posx += vx;
posy += vy;
//this is what it will do when it reaches an edge of the screen
bounceOnScreenEdges();
}
//here we reset the velocity
void bounceOnScreenEdges(){
if(posx>width || posx<0){
vx=-vx;
}
if(posy>height || posy<0){
vy=-vy;
}
}

Arrays.

This is all fine and fun, but what happens if we want to have many particles (or for that matter many things of the same type)? do we have to define a variable for each particle? luckily enough there are arrays for this. An array is similar to a variable, in that it has a type, but instead of only one instance of that variable it has many, which we can address independently through an index. The syntax of an array in processing (and Java) is this:

float[] numbers = new float[10];

This means that the type of “numbers” is an array of floats ( “float[]” ). Then we create the array with “new float[]”, with the size we want. The size of the array cannot be changed. The array above will have 10 elements, and their indexes will range from 0 to 9 (arrays in most languages always start with an index of 0). To access any element of the array we use its indices, like so:

float[] numbers = new float[10];
//this is how we can access each element by their index
numbers[1]=10;
numbers[2]=5;
numbers[0]=23.5;
numbers[7]=3789.54;
//this won't work, (no element 10) comment it off to see the what happens
//numbers[10] = 6.5;
println("the third element is: " + numbers[2]);
//and this is how we iterate through all elements of the array
for(int i=0; i< numbers.length; ++i){
println("element "+ i + " is " + numbers[i]);
}

Now we can rewrite our agent/particle code, so there are many of them:

As an exercise (exercise 1), you can try to do this: you may observe that some particles accelerate too much after a while…
Can you write a function similar to “bounceOnScreenEdges” that iterates through each velocity component (x and y), checks if it is larger than a certain maximum value, and if it is, that it makes it equal to that maximum value?

And (exercise 2): by knowing that the size of a vector is the square root of the sum of the square of its components (size=sqrt(vx*vx + vy*vy)), can you do the same test as in exercise 1 but for the size of the vector? (this requires you to know some basic vector algebra, specially how to normalise a vector).

Objects and Classes.

An important concept in processing, and indispensable in Java, are classes. Classes are the basis of what it is known as Object Oriented Programming (OOP). The Class mechanism can be described as a way of describing our own types, besides the basic ones (bool, int, char, float…) that we have seen before. Classes can include variables and functions. The details of OOP are two complex to explain in this tutorial, but if you are really interested in learning about inheritance, interfaces and other aspects of OOP you can follow the link above. We are however going to look at a way of defining a basic class in Processing, using our agent or particle example. First we need to define our new “type” or class. We do this by writing class followed by the name we want to give to our class, and its body (its code) being defined by and opening and closing curly brackets. We call this the class declaration. Inside the class we can have any types of variables (even other classes), generally referred as its “fields”, and functions, called “methods”. This declaration of our class is only a sort of template, a description of an eventual “variable” of our class. A “variable” of our class is called an object, and it is declared as any other variable, with its type first (the name of our class) and a name we want to give it. We can access its methods and fields with a “.” operator. See the code below:

As we have said, it is possible to have classes inside classes. In Java everything has to be classes (no functions or variables can be declared outside a class), so classes are always inside classes.If converted to Java, all Processing code will be included within a class, called the PApplet (you can check the Java code that your processing Sketch generates by exporting it (with the “Export Application” button, or in “File->Export Application” menu, that is, if you are in Java mode, which is the default), and checking the .java file it generates, which is inside a folder called “source”). It is possible to make arrays of objects as of any other type. The objects of the array need to be initialised, by iterating through the array and using the “new” operator and the constructor. For example, if we declare an array of Particle called myParticles, with:

So now, (exercise 3), can you re-write the array of particle to use objects of the class Particle?

Values and References.

A Final important notion in Processing, and also present in many programming languages, is that of references. In Processing and Java all basic types (bool, char, int, float…) are always passed by value. What does this mean? this means that every time that we assign a variable from another, or pass a value to a function, the value of this variable is copied. If you write something like this for any of the basic types:

int a=10;
int b;
b=a;
b++;
println("a: "+ a);
println("b: "+b);

The results will be:

a: 10
b: 11

As you see we have declared a variable a of type int, and we have set it to 10. We have created another variable b of type int, and we have set it to a, which means that it has copied the value stored in a, into b. If we increase b by one (through the ++ operator), it will change the value of b, but not of a. This seems obvious. But now lets do this instead:

This is strange, isn’t it? Actually any variable that we declare through “new”, such as objects or arrays, will have the same behaviour. What it is happening is that when we say “b=a;” we are not saying “copy the values of a into b”, but rather make b refer to a. a and b are actually the same object, but with two different names. This may sound problematic, but it is actually really useful. Here is an example:

Instead of copying the whole array when we pass “numbers” to “randomiseArray()” we copy a reference to it… the “float[] theArray” parameter in “randomiseArray()” is then a reference to “numbers”, and not a copy. You will see how this makes more sense as you use it while you program, in the rest of the course.

A swarm algorithm.

And to finish the tutorial, we are going to use our particle/agents to implement a classic example of self organisation: a swarm. The swarm or flocking algorithm we are going to use is based on the one first proposed by Craig Reynolds, called Boids. Reynolds’ algorithm is paradigmatic of the phenomena know as self-organisation and emergent behaviour, that is, the appearance of pattern, global organisation or form as the result of simple interactions between lower level components. The swarming of birds or schooling of fish, rather than explainable by some top-down rules, can be described as the result of the bottom-up coordination of the individual behaviour of each fish, bird, or agent. In the case of Boids, swarming is the outcome of 3 simple rules that each particle follows:

Alignment: try to go on the same direction as your closest neighbours.

In the code below, this is implemented in the function “swarm()”. The example also gives answer to exercise 3, since it uses an array of particles… the code of particles is slightly modified also (we don’t call “wiggle()”, so I have deleted it to make it clearer). And I have added a “wrapAroundUniverse()” method to the particles. It uses the % (modulo) operator, which is used to calculate the remainder of a division, to make that the particles that exit at one end of the screen, appear in another. For example, if the x position of a particle is the width of the screen + 10, its x will be set to 10, instead. We do a similar thing if its position is smaller than 0, so the screen “wraps around”.

Since code is getting a bit long now, you can download the Processing project from: SwarmCode.

We have cover quite a few concepts and a new algorithm. For next time you should go through the material we have looked at today, and check the exercises. You may need to go back and refresh some of the things we looked at in first tutorial. Try to understand the code. When you don’t know what something does, or you have any doubts about if something may be written differently, or if it is at all allowed, don’t think, just change the code and see what happens! it is the most effective way of understanding the concepts.

You can for example compare this code with the implementation of flocking here.

Addendum: using PVector.

If you have been struggling with the vector maths of the particle example, there is a PVector class in Processing for doing vector arithmetic (normalising the vector, adding and subtracting… ). It may be however a bit complicated to use, because even if the math bits are easier, the programming aspects, particularly the Object Oriented related code, may be more complicated. You can try to write the examples above, using PVector. Here is the last code for the swarm written using PVector instead, you can see how it compares: SwarmWithPVector. There is a tutorial about PVector at the processing site, here.

In general, there are also a number of tutorials around that can be quite interesting to follow, so you may get another explanation of the same concepts I explain here (sort of a second opinion…). The above linked PVector tutorial is at the Processing website, under tutorials. There is also an interesting one about Object Oriented Programming, among other things.