Introduction

Workshop Synopsis:

This tutorial has been designed for a two-part full-day series of workshops at the University of Kent, which will provide students with an introduction to the Processing computer language. The first day you will be introduced to core programming terminologies, by coding basic programs, or sketches as they are referred to within Processing, demonstrating how programs are comprised of ‘syntax’, ‘functions’ and ‘data’ with a focus on how to draw 2D shapes. The first workshop will provide a foundation to move onto more advanced programming concepts.
In the second workshop we will move towards three dimensions and learn how to make previously inanimate objects on a screen, interact with one another, act on individual rules and group behaviours, thus developing autonomous agents which can produce emergent ‘architectural’ forms. We will also briefly cover interaction with external data sources.

What is Processing?

Processing is considered by many to be a flexible software sketchbook and language, targeted towards the electronic arts and visual design communities, purpose built for teaching non-programmers the fundamentals of computer programming in a visual context. However, Processing is not in fact a programming language but rather a library which extends and simplifies the Java language which Processing is built on top of.

Processing simplifies the processes of starting to code by removing some of the complexities of setting up a development environment which exist with traditional programming languages and tools. It accomplishes this by providing a ready-to-program integrated development environment (IDE) which has Java included.

Lets get a little more familiar with the Processing IDE:

Processing IDE with Theme
1
Run (compile) your sketch with this button
2
Stop your sketch with this button
3
Activate Processing’s debug mode
4
Used to change the IDE mode, add Processing libraries and IDE tools
5
Tabs, which show additional .PDE files which can hold further code, such as, functions, configurations or class.
6
Processing’s text editor (you write and edit code here)
7
Processing’s console used to display errors and for debuging your code.
8
Error log, only used when Processing is set to debug mode.
The Processing 3.4 IDE showing a comparison between the stock white theme and the Moria Dark theme made by Jeremy Paton.

Why learn Processing?

A good question, especially if you are an architecture student with little to no programming experience.

Traditionally architecture degree-courses have not embraced programming as a methodology towards design. However, we are seeing a shift to introduce more complex 3D modelling tools such as Rhino into undergraduate courses, where as before such tools have been limited to postgraduate. Along with Rhino and Revit come parametric modelling tools such as Grasshopper and Dynamo which provide an alternative to syntax (typed) programming in the form of a visual programming language. However, these tools are often highly complex and not particularly intuitive (despite their visual programming method) and fail to communicate the fundamental principles which are need to ‘code’ ones own program.

Processing provides a good middle ground, simple enough for students to begin learning yet, requires students to learn the basics firsts and extensible allowing development of highly complex projects. This is important as not everything can be accomplished with the native tools or plugins for Grasshopper and you may need to code your own bespoke competent.

However, Processing should not be considered an all-inclusive alternative to tools such as Grasshopper. Processing provides a platform for architects to explore topics such as; generative design, emergence, self-organisation or evolutionary systems, problems which often require computation to explore and can be used exclusivity or in tandem with tools such as Grasshopper.

Further more, this exploration is derived from an ongoing history of ideas within post-modern thought which found precedents in mathematics and computer science,
such as Cellular Automata, swarms, reaction diffusion systems and evolutionary algorithms. Such an approach to design provides an advantageous paradigm for architecture as it supplants the top-down explicit design methodology in favour of a bottom-up architecture which is the emergent outcome of a whole lot of interconnected feedback loops.[¹]

Another consideration is future academic studies, such as completing a MSc in Architectural Computation or Bio-Integrated Design. Having experience with coding will greatly aid in such an endeavour.

Projects using Processing:

Emergent Form Finding Application + Structural Optimisation

Stage 4 Project, Unit 4, MArch Kent, By Jeremy Paton

Data mining & visualisation northern lights photography in Iceland

Stage 4 Project, Unit 4, MArch Kent, By Jeremy Paton

Agent driven hypothetical emergent urban model

Stage 5 Project, Unit 5, MArch Kent, By Jeremy Paton

SpaceWires by Filamentrics

Bartlett BPro GAD/RC4, Team Filamentrics: Zeeshan Ahmed, Justin Yichao Chen, Nan Jiang,Yiwei Wang

Microstrata

Bartlett BPro GAD/RC4, Team Microstrata: Maho Akita , Fame Ornruja Boonyasit, Syazwan Rusdi, Wonil Son

1. Lines, Points & Shapes

The beginning… as good a place to start as any. Lesson one will start by introducing you to the syntax (notation) of Processing, and inherently a slimmed down version of the Java programming language. However, the core concepts covered in these exercises apply to almost all programming languages. We will start with a simple exercise to draw a line on the screen, this may seem trivial however, from here we can progress onto shapes, boxes, images, trees and a host of complex 3D forms.

Patience is key, getting to grips with the basics is essential before you can produce more complex sketches in Processing. Spend as much time as you can familiarising yourself with the syntax and built in functions of processing. A fantastic resource for this can be found at the Processing References page: https://processing.org/reference/

Key programming concepts:

Functions, data, parameters, types, declaration, assignment

1.1 Introduction

Essentially any Processing sketch is comprised of two elements: functions and data. At this point functions refer to the built in functions provided by Processing such as: line(x1, y1, x2, y2) or point(x, y) and by Java such as: loop() later we will see how to build our own functions. Most Processing sketches will be comprised of numerous functions. Often a function will do some of the work for us, such as producing some 2D/3D geometry, a cube or sphere. Followed by another function which rotates the object and a third which is used to draw the object to the canvas. Data refers to the information we provide (or pass) to a function, in the case of line(0, 0, 50, 50) we are providing the function with four required parameters (0,0,50,50) which tells the function the coordinates to begin drawing the line from and where the line ends. In this case we are providing a pair of coordinates. The StartX and StartY position {0,0} followed by the EndX and EndY position {50,50} . Almost all functions will require you to pass some number of parameters in order for the function to know what to do. In some cases a function will also return data.

1.2 Sketching using functions

Lets put into practise what we have learnt by coding our first Processing sketch. Type the following into the Processing IDE:


// This program draws a line
// Lines that begin with '//' are 'comments'
// Comments are ignored by the computer, however they help others (and you!) understand what the code does.

line(0,0,50,50);

Notice how the call to the function is structured: you write the function name ‘line‘ followed by an open bracket ‘(‘, then list the required parameters separated by commas, then add a close bracket ‘)’. Finally you declare the end of the line by adding a semicolon ‘;’.

1.3 2D Cartesian plane

Its important to quickly cover Processing’s 2D coordinate  system. Whilst Processing is set to 2D rendering, the upper-left corner has the coordinate {0,0} and the lower-right coordinate {width,height}. Thus if we have a canvas with the size of 200 width by 100 height, the lower-right coordinate will be {200,100}. The X and Y are increasing positively to the right and down respectively. See the following image to help visualise this:

2D Plane

1.4 Overriding The Canvas Size

As we can see in the sketch we’ve created the size of the window (canvas) was quite small and we have no influence over this. Lets change that by overriding the default size of the canvas. There is no set rule for what size the canvas should be, this will be determined by the nature of your sketch, sometimes a landscape (16:9) resolution works best or setting the canvas to full-screen (covered later!). For now lets set the canvas size to (200×200), in order to do this we need to call another function, to instruct the computer to set the new size of the canvas. The function to change the canvas size is called ‘size’ and requires two parameters, a width and height.


size(200,200);
line(0,0,50,50);

Notice how the sketch is starting to turn into a sort of recipe of functions. Starting with setting the canvas size to {200,200} followed by drawing a line from {0,0} to {50,50}.

1.5 Order Of Operations

Note that the order of these functions is very important. Programming operates in a linear fashion. To demonstrate this lets change the background colour of the sketch. To do this we need to use the function ‘background’, as follows:


size(200,200);
line(0,0,50,50);
background(175);

You should now have encountered your fist bug. The canvas is now pure white and the line has disappeared. See if you can solve this error your self based on the previous note about order of operations.

1.6 Drawing Other Shapes

We are not only limited to drawing lines, we can also draw shapes. Processing includes some built in functions which allow us to draw rectangles, and ellipses. Lets add a rectangle to the canvas above the the line. The rectangle function requires four parameters: rect(a, b, c, d) the pairs (a, b) determine the coordinate where the top left corner of the rectangle will be drawn and (c, d) determine the width and height of the rectangle. Thus rect(10, 10, 30, 30) will results in a square which a top corner at the coordinate {10,10} and a width and height of {30,30}. See the bellow sketch and try reproducing it:

Your browser does not support the canvas tag.

For variation we can add an ellipse to this sketch, which we can place over the rectangle, so it appears within the rectangle. The ‘ellipse‘ function also requires four parameters, which operate in the same manner as the four parameters for the ‘rect‘ function. The ‘ellipse‘ function is called as follows: ellipse(a, b, c, d).

However, after adding an ellipse(10, 10, 30, 30) to the sketch you should notice that the position of the ellipse is being drawn based on its centre,  unlike how the rectangle is drawn from its top-right corner. This can be changed by using another function, which we need to include before the ‘ellipse’ function, this function can be called as follows: ellipseMode(CORNER) See if you can reproduce the sketch bellow:

Your browser does not support the canvas tag.

ellipseMode(CORNER) has multiple options including: ‘CENTER’, ‘RADIUS’ and ‘CORNERS’. How these change the method by which an ellipse is drawn can be read at the Processing reference page.

You can also change the method by which a rectangle is drawn by using: rectMode(CENTER) which has multiple options including: ‘CORNERS’, ‘RADIUS’ and ‘CORNER’. How these change the method by which a rectangle is drawn can be read at the Processing reference page.

1.7 Drawing Points

Lastly we can add two points to the sketch, one at the centre of the ellipse, placed above the line, rectangle and ellipse and another at the end of the line.

Whilst Processing is in 2D mode, a point has no defined size and will be drawn as a single pixel. As discussed in section 1.4 Overriding The Canvas Size we adjusted the canvas size to (200×200) this indicates that the canvas has exactly 200 pixels to the right (width) and 200 pixels downwards (height). The point function can be called as follows: point(x, y) and requires a simple x and y coordinates as its parameters. In order to draw two points, you will need to call the ‘point‘ function twice, one after the other. See the sketch bellow and try to reproduce it, without looking at the code:

Your browser does not support the canvas tag.

size(200,200);              // Set the canvas size to 200px by 200px
background(175);            // Set the background colour to grey (175)
line(0,0,50,50);            // Draw a line from {0,0} to {50,50}
rect(10,10,30,30);          // Draw a rectangle at {10,10} with a width of 30px and a height of 30px
ellipseMode(CORNER);        // Set the ellipse draw mode to draw from the upper-left corner of the ellipse
ellipse(10,10,30,30);       // Draw an ellipse at {10,10} with a width of 30px and a height of 30px
point(25,25);               // Draw a point at {25,25}
point(55,55);               // Draw a point at {55,55}

1.8 Advanced Data: Variables

Lets consider the following objective: to draw a row of ten boxes next to one another. A possible solution would be to call the rect(a, b, c, d) function 10 times to create such a row, however, this would involve unnecessary duplication. A fundamental part of learning to program is to learn to write short, efficient sketches (without code duplication) that can generate sets of geometry rather than tediously adding geometry a single line at a time. The first stage on the road to reducing duplication is to introduce placeholders called variables.

A variable is simply some know or unknown data (value) which you have associated to a symbolic-name (an identifier). Its advisable to give our data a name which is representative of what kind of data it stores, often when referring to coordinate data we will simply assign the x-coordinate with ‘x’ and the y-coordinate with ‘y’.  This is advisable as the more complex your project becomes the more challenging it will be to keep track of what each variable represents. Try keeping variable names short and succinct!

Many programming languages require you to tell the computer what type of data our variable will contain, such data-types (variable types) include, but are not limited to the following:

int a = 1;                      // Used to store integer (whole) numbers
float b = 1.123456;             // Used to store floating point (decimal) numbers
String c = "Some Text Here";    // Used to store text and requires double ""
char d = 'd';                   // Used to store a single character and requires single ''
boolean e = true;               // Used to store two special values: true or false (1 or 0)
As you can see above the type of the variable is written before the name of the variable, in most cases the type is all lower case with the exception of ‘String‘ which starts with a capital, as ‘String‘ is in fact a ‘Class‘ rather than a primitive type like ‘boolean‘. ‘String‘ has methods that can be called directly to it (like the famous ‘length()‘, ‘replace()‘ and ‘split()‘). None of the primitive types have these functions. Have a look on the Processing Reference page for more Primitive Data types and more Composite (Class) Data types.

Note that there is only space for a single number in each integer variable, therefore a variable cannot contain the number ‘2’ and ‘5’. However, it is possible to change the value which a variable stores, hence the name variable, the value is not considered static. This makes variables incredibly useful to stand in for real numbers when we do something repetitively. For example, where we want to draw our 10 boxes in row. If we have a variable to designate the position, we can simply alter the variable, to change the boxes position, without altering the ‘rect‘ function.

In order to achieve this we need to designate the position of the box using a variable. Lets use ‘x’ as the name of our variable and assign it the value 10. Next we need to pass our new variable ‘x’ into the ‘rect‘ function, in place of one of the parameters. In this case it is the first parameter which defines the x-coordinate of the ‘rect‘ function, as follows:

int x;              // Declare our variable name and assign it as an integer type
x = 10;             // Assign the value which our variable stores
rect(x,0,5,5);      // Draw a rectangle and pass our variable as the first parameter

The above code will result in a canvas with a 5px by 5px rectangle with its top left corner at the coordinate {x,0}. Since ‘x’ is set to 10 at the beginning of the sketch, the box is drawn with its top corner at {10,0}.

Now, try removing the line x = 10; and re-run the sketch. Processing will object to this and output an error in the console:

The local variable “x” may not have been initialized.

You will also notice that the ‘rect‘ function ‘x’ is underlined with red zig-zag. This indicates that Processing has no knowledge of what the value for ‘x’ should be. Effectively the integer variable ‘x’ is undefined and has no associated integer value. Processing can therefore not draw the box as it would be drawing the x-coordinate of the box to an undefined location. Fortunately, Processing is able to pick up the error in our code and present us with an error, which helps us to see which line the error occurred on and possibly what needs to be done to fix the error.

Rather than replacing the line, lets condense Line 1 and Line 2 in the above code into a single line, by declaring and assigning the variable in the same line.

int x = 10;         // Declare the variable name and assign it as an integer type and assign it a value of 10
rect(x,0,5,5);      // Draw a rectangle and pass our variable as the first parameter

1.9 Basic Operations

Before we can complete our objective in the above section 1.8 Advanced Data: Variables, to produce a row of boxes, we need to learn one more core feature of Processing: how to manipulate the values of variables. We will look at two methods to draw two boxes, firstly without a variable, and secondly, with a variable:

// v1 - Without a variable
rect(0,0,5,5);
rect(10,0,5,5);

The problem with the above code is that for each and every box we wish to draw, we need to write a new call to the function ‘rect‘. With a variable, the code would look as such:

// v2 - With a Variable
int x = 0;
rect(x,0,5,5);
x = 10;
rect(x,0,5,5);

At first the above code my look cumbersome as we have to reassign the variable value at Line 4 and we have increased the amount of code need to produce the same end result. However, we should start to see a pattern forming within the code, and this will be an essential point, which we will take advantage of when we come to draw out 10 boxes in a row as we learn about looping through code in the next section. For now lets investigate another method to change the variable, up till now we have simply assigned a variable with a static value. However, it is possible to perform an operation, for example, like so:

// v3 - With a Variable and Operation
int x = 0;
rect(x,0,5,5);
x = x + 10;
rect(x,0,5,5);

The above code performs an identical function to the last two examples. This tends to be an ongoing recurrence within programming as often there is more than a single solution to a problem. However, which is the better method will often depend on the context of what we are trying to accomplish, nevertheless, keep in mind that most of the time the goal is to produce succinct code, if you find you are duplicating code this may indicate that there is a better solution.

Though the above code achieves the same outcome as before, it does this in a slightly different manner. Rather than reassigning the variable ‘x’ with 10, this code reassigns the value of ‘x’ plus 10. Note the addition is performed first. ‘x’, currently 0, is added to 10, giving a result of 10. The addition is technically known as an operation, and the plus sign ‘+‘, is known as an operator. Other operators we encounter soon are ‘‘ (subtraction), ‘*‘ (multiply), ‘/‘ (divide) and ‘%‘ (modulo, or remainder after division). Note that ‘*‘ is used rather that  ‘ב as there is no dedicated multiplication symbol on the keyboard.

We could alternatively use multiplication to achieve the same outcome as the previous example by making some basic alterations to the the code as follows:

// v4 - With a Variable and Multiplication Operation
int x = 0;
rect(x*10,0,5,5);
x = x + 1;
rect(x*10,0,5,5);

Once again the result is the same, however, this time ‘x’ is assigned the value ‘0’, and then the value of ‘x’ plus ‘1’ (0 + 1). Each time when we call the ‘rect‘ function we multiply ‘x’ by 10, therefore the first time the box is drawn at 0 * 10 or 0 across, and the second time at 1 * 10 or 10 across.

In our quest to write the most concise code possible we can change the above code to use some shorthand methods for adding values within Processing, as this is something we often do in programming. The following lines all do the same thing:

// Addition shorthand
x = x + 1;
x += 1;
x++;

Each line above adds 1 to the existing value of ‘x’.

We are now in a position to progress to loops, to repeat the same piece of code with a set of different values for a variable. However, before we move on its probably important to quickly revise using operators such as ‘+‘. ‘*‘ and ‘/‘, but also especially the two short hand methods we have introduced: ‘+=‘ and ‘++‘ as well as you may have guest the inverse versions of these shorthand operators: ‘-=‘ and ‘‘. For example, you might write a more advanced script, something like:

Your browser does not support the canvas tag.

int x = 0;
int y = 1;   
rect(x*10, y*10,5,5);  // x = 0 and y = 10
x = x + 3;             // x = 3
rect(x*10, y*10,5,5);  // x = 30 and y = 10
y += 5;                // y = 6
rect(x*10, y*10,5,5);  // x = 30 and y = 60
x--;                   // x = 2
rect(x*10, y*10,5,5);  // x = 20 and y = 60

2. Loops, Conditions And Variation

Loops

Lesson two is a direct continuation from lesson one, specifically our goal in section 1.9 Basic Operations to achieve a row of 10 boxes. In order to achieve this, lesson two will introduce you to the programming concept of repetition (also known as loops). Within the lesson we will also attempt to generate some simple artworks by using the basic primitives of lines and rectangles combined and altered through the use of loops and conditions, which will create variation.

Key programming concepts:

Iteration, conditional statements, comparison operators, logical operators

2.1 Introduction

Thus far we’ve been not been able to do very much, only producing some arbitrary lines and rectangles on the canvas. How can we create try to imitate the diversity found in the natural world, within our own virtual environment? One answer is through the use of repetition, diversity and detail, and for these we can use loops, conditions and recursion.

A loop repeats many times. It may be used to generate many similar shapes. Or it might be used to iterate through many shapes to find the one you want to alter.

A conditional statement, by contrast, creates diversity. It changes the programs flow so that in one case, say one iteration of the loop, we might follow one path and create a box, and another iteration we might follow another path and create a sphere. Or we may use a condition to test which mouse button has been pressed, or which direction the mouse is moving, and respond accordingly. Think of conditional statements as gates which can be opened or shut if specific criteria are met.

2.2 Loops

Within Processing there are two types of loops, ‘for‘ loops and ‘while‘ loops. ‘For‘ loops are the more ubiquitous of the two, as they can, for the most part, achieve everything a ‘while‘ loop can achieve. The basic structure is as follows, the word ‘for‘ followed by some specific information about how many times to loop (or iterate) enclosed between rounded brackets ‘(‘ and ‘)‘ – think of these as parameters, yet slightly different. Then followed by the section of code that you want to repeat enclosed between squiggly brackets (braces) ‘{‘ and ‘}‘. Here is an example of a ‘for‘ loop:

for (int i = 0; i < 10; i++) {
  println(i);
}

Run this code and take a look at the console, you should see a list of numbers from (0 – 9).

Now lets examine the syntax (structure) of the ‘for‘ loop to determine how it printed these 10 numbers. Take a look at Line 1, specifically (int i = 0; i < 10; i++). This line is essentially comprised of three parts, all of which we’ve seen previously, but, now combined within a single function. Lets dissect each part:

int i = 0;      // Variable declaration and assignment: tells the loop to start counting from 0
i < 10;         // Conditional statement: tells the loop it should continue while i is less than 10
i++             // Each iteration of the loop will increase i by 1

If we walk through the ‘for‘ loop. the loop is set to start counting from 0, using the variable ‘i‘ to store the count value. The loop will now execute the code which is written between the ‘{‘ and ‘}‘. When the last line of the code is completed the loop will increase the count value ‘i‘ by 1, as it’s been set to by ‘i++‘. This process will be repeated until the count value ‘i‘ is 9, as when ‘i‘ reaches 10 it will not pass our conditional statement set by ‘i < 10‘, terminating the ‘for‘ loop. Thus the code contained within the ‘{‘ and ‘}‘ will occur a total of 10 times.

In the above example we used a built in function within Processing to print a line of text to the console, this is completed by: println(i);. The ‘println‘ (print line) function is highly useful for debugging your program, and like other functions it requires a parameter to be passed for the function to know what ‘data‘ it should print to the console. In the case of our simple ‘for‘ loop we are printing the value contained by the loops count variable ‘i‘. Each time the loop occurs the value of ‘i‘ is printed, which is being incremented by 1 each iteration, therefore, the numbers 0,1,2,3….9 are printed.

A few points to point out. Firstly, it is common practise to reserve the variable ‘i‘ for ‘for‘ loops. Secondly it is common practise to start counting from 0 in almost all programming languages, this becomes more important later on, but for now one reason for this is that if we take a passing glance at the line: for (int i = 0; i < 10; i++) we can quickly read that this code will occur a total of 10 times.

To demonstrate the linear nature by which code is read and how the loop affects this, we can add in two lines of code to the previous example:

println("--BEGIN--");
for (int i = 0; i < 10; i++) {
  println(i);
}
println("--END--");

Which should output the following:

--BEGIN--
0
1
2
3
4
5
6
7
8
9
--END--

We see now that the sketch starts by printing out “–BEGIN–“, then loops through ten times, printing the values of the counter (0 – 9), and finally prints out “–END–“.

One last note to make regards the parameters we can pass to the ‘println‘ function, notice how the function distinguishes between variables, such has ‘i‘ and constants such as “–BEGIN–“. The variable ‘i‘ is written without quotation marks, which indicates to Processing that we are referring to a variable which it needs to look up the value of. In the case of “–BEGIN–” we want Processing to print out the literal text (string) “–BEGIN–” and “–END–“. Thus we enclose the text within double quotations, as was shown in section 1.8 Advanced Data: Variables when declaring and assigning a value to a variable type ‘String‘. We can combine a constant and variable within the ‘println‘ function as follows:

println("--BEGIN--");
for (int i = 0; i < 10; i++) {
  println("Loop Number: "+i);
}
println("--END--");

2.3 A Row Of Rectangles

We are now finally ready to achieve our goal of a row of 10 boxes. This will kick off our exploration of adding interest to our sketches through repetition, then moving towards variation and then finally some simply artworks. Bellow is the code which combines everything we’ve learnt thus far to achieve a row of 10 boxes and avoids the unnecessary repetition of code:

Your browser does not support the canvas tag.

for (int i = 0; i < 10; i++) {      // Loop 10 times, with an increment of 1
  rect(i*10, 0, 5, 5);              // Draw a rectangle at {i*10,0} with a width and height of 5px 
}

Notice that the variable is not limited to simply the location of the boxes, yet can also be used to set the height of the boxes, or alternatively their width. An example could look as such:

Your browser does not support the canvas tag.

for (int i = 0; i < 10; i++) {      // Loop 10 times, with an increment of 1
  rect(i*10, 0, 5, 50-i*5);         // Draw a rectangle at {i*10,0} with a width of 5px and height of 50px - i*5 
}

Before we proceed its important you understand why this sketch does what it does. In particular, that 50-i*5 produces a box which is 50 pixels high only when ‘i‘ is 0, therefore the first iteration of the loop. And the final box will be 5px high as: 50-9*5 = 5. Don’t forget the last iteration of the loop ‘i‘ will be equal to 9 not 10.

2.4 Coloured lines and rectangles

Its possible to make our output look slightly prettier by changing the colour of the rectangles progressively. Firstly, let us introduce three new functions: ‘background‘, ‘stroke‘ and ‘fill‘. Below is an example which implements all three of these functions:

Your browser does not support the canvas tag.

background(39,40,34);               // Set the background colour for the canvas
stroke(255);                        // Set the outline (stroke) colour
fill(125);                          // Set the internal (fill) colour
for (int i = 0; i < 10; i++) {      // Loop 10 times, with an increment of 1
  rect(i*10, 0, 5, 50-i*5);         // Draw a rectangle at {i*10,0} with a width of 5px and height of 50px - i*5 
}
Lets quickly go over the colour parameters which these three functions require. On line 1 we see that the ‘background‘ function has been provided three parameters, whereas on lines 2 and 3 the functions ‘stroke‘ and ‘fill‘ have only a single parameter. What is the reason for this? If you open the ‘colour selector‘ in Processing (Tools > Color Selector) a new window will open, showing a colour pallet and a set of values on the right, if you are familiar with Photoshop you will most likely have seen something like this before. Now to answer the previous question, all functions in Processing which accept a colour parameter can accept a single value which will define ‘grey‘ or monotones between the range of 0 and 255, where 0 is black and 255 is white. Hence the white outlines of our rectangles which we set to 255. However, if you want to display a colour you will need to provide the RGB values for that specific colour, see bellow for examples:
background(0);            // Black background
background(255);          // White background
background(255,0,0);      // Red background
background(0,255,0);      // Green background
background(0,0,255);      // Blue background
background(165,25,240);   // Purple background

Try adapting the example above to use some other colours. Using the Processing colour selector will help you to determine the RGB value for a specific colour.

Now lets make the colours of our boxes a little more dynamic, by moving the ‘fill‘ function from outside (before) the loop which draws the 10 boxes, to within the loop. Furthermore,  the ‘fill‘ function’s parameters also accept a variable like the ‘rect‘ function. Thus we can adjust the fill for the ten boxes to show gradation in grey-scales as so:

Your browser does not support the canvas tag.

background(39,40,34);               // Set the background colour for the canvas
stroke(255);                        // Set the outline (stroke) colour
for (int i = 0; i < 10; i++) {      // Loop 10 times, with an increment of 1
  fill(i*25);                       // Set the internal (fill) colour to i*25
  rect(i*10, 0, 5, 50-i*5);         // Draw a rectangle at {i*10,0} with a width of 5px and height of 50px - i*5 
}
Variable Scopes: Try moving Line 4 fill(i*25); to before the loop. You should notice that Processing now outputs an error:

The variable “i” does not exist.

The reason for this is due to what is known as Variable Scopes, in the case of our variable ‘i‘ it can only ever be referred to within the braces ‘{‘ and ‘}‘ of the for loop. This is because we declared the variable ‘i‘ within the construction of our for loop: int i = 0

2.5 Nested Loops

Now, rather than just a single row, perhaps we may desire a grid. One solution for creating ‘n‘ number of rows would be by nesting one loop inside of anther loop, this would created what is referred to as a nested loop. Lets take a look at the code to create such a grid:

Your browser does not support the canvas tag.

size(200,200);
background(39,40,34);               // Set the background colour for the canvas
stroke(255);                        // Set the outline (stroke) colour
noFill();                           // Set the fill colour to none (transparent)
int scale = 10;
for (int y = 0; y < height; y+=scale) {      // Outer Loop: Y - Rows
  for (int x = 0; x < width; x+=scale) {     // Inner Loop: X - Cols
    rect(x,y,scale,scale);                   // Draw a box at {x,y} with the size (scale)
  }
}

The above example presents a noticeable jump in the complexity of our code, thus lets analyse what we are telling Processing to do. Firstly on line 5 we declare a new variable called ‘scale‘ this variable will be used for two purposes, firstly it’s used to set the increment used within the loops and secondly its used to set the size of the rectangle, try adjusting the value of ‘scale‘ and running the sketch. On lines 6 and 7 you now see two ‘for‘ loops, we can consider the first loop (outer) our row position or ‘y‘ value and the second loop (inner) our column position or ‘x‘ value. On the first iteration of the first loop the second loop will be run until its counter ‘x‘ is less than the value of the width of the canvas (x < width), and so on until the outer loop meets its condition (y < height). This can be expressed more easily as follows:

for every row               // y value
↑   for every column        // x value
    ↑   draw a rectangle

And if we take a look at the values of ‘x‘ and ‘y‘ we can see the following happen:

y = 0
    x = 0
    x = 10
    x = 20
    .
    .
    x = 180
    x = 190
y = 10
    x = 0
    x = 10
    x = 20
    .
    .
    x = 180
    x = 190
... and so on until y = 190

And at each stage (iteration) of the inner loop we call the ‘rect‘ function to draw a rectangle, see line 8. If you look at line 4 you will notice we have called a new function called ‘noFill‘ this is a special function which requires no parameters and servers the opposite function of the ‘fill‘ function, by removing any fill colour, making any geometry called after this function to have a transparent fill. We also use the ‘scale‘ variable to set the width and height parameters of our rectangle. Try adjusting line 8 to the following: rect(x,y,scale/2,scale/2);

Its possible that instead of using the the ‘noFill‘ function we can fill each rectangle that comprises the grid with a unique colour. In order to do this we need to remove the ‘noFill‘ function and as was shown in section 2.4 Coloured Lines And Rectangles include the ‘fill‘ function within the loop, we will use the variable values of ‘x‘ and ‘y‘ and operators to alter the fill colour of our rectangle for each iteration of our nested loop, as follows:

Your browser does not support the canvas tag.

size(200,200);
background(39,40,34);               // Set the background colour for the canvas
stroke(255);                        // Set the outline (stroke) colour
int scale = 10;
for (int y = 0; y < height; y+=scale) {      // Outer Loop: Y - Rows
  for (int x = 0; x < width; x+=scale) {     // Inner Loop: X - Cols
    fill(y, 255 - x, y + x);                 // Fill using operations
    rect(x,y,scale,scale);                   // Draw a box at {x,y} with the size (scale)
  }
}

Have a go at altering this code, for example we could remove the white grid lines. To do this replace ‘line 3‘ with: noStroke();, this function works exactly like ‘noFill‘ however, instead of removing the fill colour, it will remove the stroke (border) line around each rectangle.

2.7 If Statements

Whilst repetition a is a powerful tool, which saves us time, the outputs can become a bit repetitive. Whilst we are starting to get more varied and charming outputs from our program, the general pattern is very regular. Regardless how we manipulate ‘i‘, be it through an operation such as ‘i * i + 10‘ or simply ‘i‘, it still follows a predictable pattern. Therefore, how do we add irregularity? An answer to this is through the use of conditional statements such as an ‘if‘ statement. Indeed, even if what we want to do is to follow some rules for the generation of a form, we will still need to specify the conditions for them to be obeyed, and this involves using ‘if‘.

To demonstrate a simple usage of the ‘if‘ statement lets draw a grid of rectangles with a single row and single column highlighted in colour. I’ve simplified the previous code to show how we might go about solving this challenge:

for (int y = 0; y < 10; y++) {       // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {     // Inner Loop: X - Cols
    if (y == 3) {                    // Check if the y value is equal to 3
      fill(128, 64, 255);            // Fill using a purple colour     
    }
    rect(x*10,y*10,5,5);             // Draw a box at {x plus 10,y plus 10} with the size 5px by 5px 
  }
}

The above code, still makes use of our nested loop to create a grid of rectangles, however, instead of increasing by a variable we increment ‘y‘ and ‘x‘ by 1, until each reaches 9. This will create a grid of 10 by 10 rectangles.

Notice on line 3  we’ve included an ‘if‘ statement. They syntax for an ‘if‘ statement is similar to that of a ‘for‘ loop. It begins with the keyword ‘if‘ and is followed by a condition which is between rounded brackets. Finally, it has the code to execute, if the condition is true, between braces ‘{‘ and ‘}‘. If the condition is not true, then Processing skips the code between the braces, and continues as per normal. In the above case we are saying if ‘y‘ is equal to 3, then perform the action(s) between the braces, else ignore them.

Furthermore, notice that the condition uses a double equals sign (==). This is to distinguish the comparison operation (“is ‘y’ equal to 3″) from the assignment operation (“set ‘y’ equal to 3″).

Now lets look at what our coding is actually doing: it draws three rows in the original colour (white) and then the remaining rows in a (purple) colour. However, we asked Processing when ‘y‘ is equal to 3 set the colour to purple, so why are all the rows from the third in purple and not only the fourth row, not forgetting we start counting at 0. This is due to the way in which the ‘fill‘ function operates, by changing the the state of Processing. Therefore, as soon as ‘y‘ is equal to 3, then Processing’s fill state is changed by ‘fill‘ to the new colour, and remains in this state forever, or until we change it back. Thus to correct this behaviour, we need to specify a default state for the fill colour, white, which is called when ever ‘y‘ is not equal to 3.

There are two methods to solve this, the first is commonly used but slightly less elegant. The first method sets the fill state of Processing, for every iteration of the loop to white, and if y = 3 the fill state is overridden to purple:

Your browser does not support the canvas tag.

for (int y = 0; y < 10; y++) {       // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {     // Inner Loop: X - Cols
    fill(255);                       // Set default fill colour
    if (y == 3) {                    // Check if the y value is equal to 3
      fill(128, 64, 255);            // Fill using a purple colour
    }
    rect(x*10,y*10,5,5);             // Draw a box at {x * 10,y * 10} with the size 5px by 5px
  }
}

2.7.1 Else

However, the above code will call the ‘fill‘ function twice when y = 3, first setting the colour fill to white and then overriding this setting if y = 3. There is a more elegant way to write this code, to avoid the double call of ‘fill‘, which can be achieved through the use of an ‘else‘ statement. When the condition is true, we perform that, else we perform the other action. As seen in the code bellow:

for (int y = 0; y < 10; y++) {       // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {     // Inner Loop: X - Cols
    if (y == 3) {                    // Check if the y value is equal to 3
      fill(128, 64, 255);            // Fill using a purple colour
    } else {
      fill(255);                     // Set default fill colour when y <> 3 
    }
    rect(x*10,y*10,5,5);             // Draw a box at {x * 10,y * 10} with the size 5px by 5px
  }
}

Notice the way we include the ‘else‘ statement, on line 5, which forms part of our ‘if‘ statement by including else directly after the closing ‘}‘ on the same line and then encasing the code we wish to execute for the else statement within its own braces ‘{‘ and  ‘}‘. Also pay attention to the spacing of the code achieved using the TAB key, this is a coding convention that helps us visually distinguish blocks of code that are encased within a preceding conditional statement, loop, custom function or class.

2.7.2 Or (||)

However, we’ve not completed our original problem which was to colour both a single row and a single column. To achieve this lets attempt to colour the eighth column (‘x== 7‘) and the fourth row (‘y == 3‘). The solution is through the use of the ‘or‘ operator, which is written as two vertical lines ‘||‘:

Your browser does not support the canvas tag.

for (int y = 0; y < 10; y++) {       // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {     // Inner Loop: X - Cols
    if (y == 3 || x == 7) {          // Check if the y value is 3 OR if the x value is 7
      fill(128, 64, 255);            // Fill using a purple colour
    } else {
      fill(255);                     // Set default fill colour when y <> 3
    }
    rect(x*10,y*10,5,5);             // Draw a box at {x * 10,y * 10} with the size 5px by 5px
  }
}

When using the ‘or‘ operator, line 3, if either the first half of the condition is true or the second half is true, the code within our braces will be executed. Don’t forget that our ‘if‘ function executes the code when the condition is true and the use of the ‘or‘ operator means that only one condition needs to be true for the conditional statement to read true. To illustrate this more easily lets define the left side of the condition (‘y == 3‘) as A and the right side of the condition (‘x == 7‘) as B. In this illustration think of A and B as variables, which can take one of two values, either ‘true‘ or ‘false‘. These are called ‘boolean‘ variables. The table bellow illustrates the use of the ‘or‘ operator within an if statement:

A

B

A || B

false false false
true false true
false true true
true true true

2.7.3 And (&&)

Lets now try work out how to only highlight the box at the intersection of the eighth column and fourth row. To achieve this we need to use another logical operator, ‘and‘. See the bellow table to see the difference between the ‘and‘ and ‘or‘ operator:

A

B

A && B

false false false
true false false
false true false
true true true

Notice that the logical ‘and‘ operation has a somewhat more obvious symbol in Processing, two ampersands. In our previous example, if we replace the ‘or‘ operator ‘||‘ with an ‘and‘ operator ‘&&‘, the if statement will only evaluate to true when both sides are true, hence both ‘y‘ is equal to 3 and  ‘x‘ is equal to 7. This will therefore highlight the box at the seventh column and fourth row. See bellow:

Your browser does not support the canvas tag.

for (int y = 0; y < 10; y++) {       // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {     // Inner Loop: X - Cols
    if (y == 3 && x == 7) {          // Check if the y value is 3 AND if the x value is 7
      fill(128, 64, 255);            // Fill using a purple colour
    } else {
      fill(255);                     // Set default fill colour when y <> 3
    }
    rect(x*10,y*10,5,5);             // Draw a box at {x * 10,y * 10} with the size 5px by 5px
  }
}

2.7.4 Not (!)

Is it possible to do the inverse of the above example and highlight the column and row, yet exclude the intersecting box? The answer is yes, and there is another handy operator we can use to achieve this, referred to as the ‘not‘ logical operator. Unlike ‘or‘ and ‘and‘, ‘not‘ requires only one parameter (typically referred to as an argument). Where ‘and‘ and ‘or‘ need an A and a B condition, ‘not‘ simply works with ‘A’, a single condition. The symbol for ‘not‘ in Processing is an exclamation mark ‘!‘. Another way to think of the ‘not‘ logical operator is that it inverses the condition requirement for our ‘if‘ code to execute, no longer must the condition resolve to true but rather false. The table bellow helps visualise this:

A

!A

false true
true false

2.7.5 Exclusive Or

Looking back at the the table for the ‘or‘ operator you will notice that there are three possibilities to produce a true outcome. Processing lacks what is referred to as an ‘exclusive or‘ operator which operates similarly to a standard ‘or‘ operator but exclusively resolves to true if either condition A or B is true, yet, in the event A and B are both true resolves false. We require an ‘exclusive or‘ operation to highlight the column and row, yet exclude the intersecting box, but as Processing lacks this we are required to code such conditional logic ourselves. The ‘not‘ operator will facilitate the creation of an ‘exclusive or‘.

First we construct the highlight condition for the column and row as before: ‘y == 3 || x == 7‘. Now we need the condition to be true for the row and column apart from when ‘ y == 3‘ and ‘x == 7‘, that is, apart from ‘y == 3 && x == 7′.  The logic for this would be its inverse,  written in Processing as:!(y == 3 && x == 7). Notice that the brackets define the statement to which we wish to apply the ‘not‘ condition. Now, we want both these conditions to be true at the same time in order to highlight the column and row, yet not their intersection. Hence, we want both ‘y == 3 || x == 7′ and ‘!(y == 3 && x == 7)’ to be true at the same. Or put a bit more straight forward: either one or the other and not both of them. The code to apply, such our ‘exclusive or‘ looks as follows:

Your browser does not support the canvas tag.

for (int y = 0; y < 10; y++) {                         // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {                       // Inner Loop: X - Cols
    if ((y == 3 || x == 7) && !(y == 3 && x == 7)) {   // Manual Exclusive OR operation 
      fill(128, 64, 255);                              // Fill using a purple colour
    } else {
      fill(255);                                       // Set default fill colour when y <> 3
    }
    rect(x*10,y*10,5,5);                               // Draw a box at {x * 10,y * 10} with the size 5px by 5px
  }
}

2.7.6 Regular Patterns

It’s also possible to use ‘if’s to generate regular patterns, such as recurring patterns of highlighted rows. There is a trick we can use to achieve this (and has a range of other uses), and it is the ‘%‘ operator. ‘%‘ or modulo is calculates (and returns) the remainder after division. With integer division, if we divide 14 by 4, the result is 3, with a remainder of 5. Modulo will return the value of 5 in this example. This could be expressed as ‘14%4 = 5.

With modulo can be used to highlight every fourth row. ‘0%4’ is 0, ‘1%4’ is 1, ‘2%4’ is 2, ‘3%4’ is 3, but, ‘4%4’ is 0 once again, ‘5%4’ is 1 and so forth. Thus, if we utilise the condition ‘y % 4 == 0‘, then all rows divisible by four will be highlighted, hence row 0, 4, 8 and so on, as so:

Your browser does not support the canvas tag.

for (int y = 0; y < 10; y++) {       // Outer Loop: Y - Rows
  for (int x = 0; x < 10; x++) {     // Inner Loop: X - Cols
    if (y % 4 == 0) {                // Is y divisible by 4? Then cont...
      fill(128, 64, 255);            // Fill using a purple colour
    } else {
      fill(255);                     // Set default fill colour when y <> 3
    }
    rect(x*10,y*10,5,5);             // Draw a box at {x * 10,y * 10} with the size 5px by 5px
  }
}

2.8 Closing Thoughts On Loops and Ifs

We’ve now covered almost all there is to know about implementing conditions, loops, and logical operators which make up what can be referred to as ‘program control’ — the ‘for‘s and ‘if‘s which alter the order by which a program executes its list of instructions — repeating certain instructions or all together ignoring others based on previous criteria (conditions). However, whilst we’ve covered how to use these programming constructs this should not be considered an exhaustive list of their uses and capabilities! You may not be presently aware of just how much programming knowledge you have just gained, but you are in fact ready to start exploring Processing on your own, experimenting with ideas and adapting code from others, which you will now be able to read and understand. From here on out we will be using this knowledge in new and inventive ways to produce novel outputs. If you’re feeling a little overwhelmed, that is perfectly normal, don’t forget that the Processing References page will aid you.

3. Translation and Animation

Lesson three starts with an introduction to coding our own bespoke functions, before diving into the more complex world of Processing’s translation, rotation and animation functions. We will explore how to translate a rectangle and progressively introduce a couple of functions so that we are able to animate and rotate boxes.

Key programming concepts:

functions, event loops, local and global variables (variable scope)

Key geometric concepts:

rotation, translation, local and global coordinate matrix

3.1 Introduction

In the previous section 2.2 Loops we discussed the concept of a loop in programming. Most programs in fact operate within a loop, with a set number of recursions or an undefined number. They wait for events, such as a user input (key press) and once revived they react to this input, drawing something on the canvas in response or altering the value of a variable. The program proceeds to loop round to wait for more events, draws on the canvas and so on. Processing distinguishes itself from native Java, or many other languages, as it is targeted towards visual designers and provided a ready to use canvas to draw animations onto. For Processing to do this, it fact needs to constantly loop, to facilitate the drawing of animations. Picture this as similar to a sketchbook animation, each alteration is a new frame, which can override or overlay the preceding frame. Processing in fact loops through the code you wish to display on the canvas 60 times per second (can be changed). Up till now we’ve not implemented this and our drawings are static, the code (excluding our own ‘for‘ loops) has been executed once.

3.2 Custom Functions To Draw (Shapes)

Thus far we have relied on Processing’s built in functions to do the hard work of drawing rectangles and other shapes for us. However, our handy ‘rect‘ function is actually comprised of smaller subsections which are combined to draw a rectangle. The simplest subsection within a Processing function is to draw a single pixel onto the canvas. The pixel requires a colour, and its possible to create a colour as a variable like we’ve done previously for an int variable, by making a variable of the colour type. Like this:

color magenta = color(255, 0, 255);    // Declare a new variable called magenta as type color and assign it magenta
set(10,10,magenta);                    // Set the pixel at coordinates {10,10} to the colour magenta

It’s important to notice how we create a colour variable, or in this case ‘constructed‘ it by typing color(255, 0, 255). You will hear more about ‘constructed‘ as we venture into classes later.

On Line 1, specifically the code ‘color(255, 0, 255)’ instructs Processing what colour the variable will store, like we earlier assigned an integer to be ‘contained‘ by an integer type variable. Line 2 shows how we can set a pixel using the ‘set‘ function which requires three parameters, an x and y coordinate followed by a colour, which can be a colour code or as we’ve done a colour variable.

The bellow code takes the same principle we established in the previous section to draw a grid, and pixels are pretty much just a grid of rectangles. But pay attention to how the border (white) pixels are produced using the ‘if‘ statement on line 6.

Now this is a rather large amount of code and if you were using Java as apposed to Processing this is more or less how you would go about creating a rectangle, as Java and most languages don’t come standard with built in functions to draw rectangles, though they do have libraries which can, such as Processing.

Now if you wanted to draw another rectangle maybe slightly different to the last, you would need to rewrite all this code again, and again. But that would be silly, we could use a loop, yes, but there is a better mechanism which allows us to encapsulate our new ‘redundant’ rectangle code into a single command, hence to write our very own function.

Now you have in fact already written your first function, however, you have not seen it up till now. the function being ‘setup‘. That is because if the ‘setup‘ function is left out Processing will automatically add it before you run (compile) your code. Your code won’t change, but the code Processing uses to run the sketch, the pure Java code will have this function. Take a look at the Java Code tab to see what the code look like once converted to Java, and see if you can find the missing ‘setup‘ function!
int boxSize = 20;                                    // Declare a new variable as type int and assign it 20
color magenta = color(255, 0, 255);                  // Declare a new variable as type color and assign it magenta
color white = color(255);                            // Declare a new variable as type color and assign it magenta
for(int y=0; y < boxSize; y++){                      // Outer Loop: Y - Pixels
  for(int x=0; x < boxSize; x++){                    // Inner Loop: X - Pixels
    if (y == 0 || x == 0 || y == boxSize-1 || x == boxSize-1) {    // Border pixels: If any of the following
      set(y,x,white);                                              // Set this pixel to white
    } else {                                         // Else
      set(y,x,magenta);                              // Set this pixel to magenta (inner pixels)
    }
  }
}
import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class temp extends PApplet {
  public void setup() {
    int boxSize = 20;                                   // Declare a new variable as type int and assign it 20
    int magenta = color(255, 0, 255);                   // Declare a new variable as type color and assign it magenta
    int white = color(255);                             // Declare a new variable as type color and assign it magenta
    for(int y=0; y < boxSize; y++){                     // Outer Loop: Y - Pixels
      for(int x=0; x < boxSize; x++){                   // Inner Loop: X - Pixels
        if (y == 0 || x == 0 || y == boxSize-1 || x == boxSize-1) {    // Border pixels: If any of the following
          set(y,x,white);                                              // Set this pixel to white
        } else {                                         // Else
          set(y,x,magenta);                              // Set this pixel to magenta (inner pixels)
        }
      }
    }
    noLoop();
  }

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "temp" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

As we progress towards more complex sketches with animations we will need this function, therefore, from now on we will include ‘setup‘ explicitly. All the code we currently have written needs to be encapsulated within the ‘setup‘ function’s braces ‘{‘ and ‘}‘, as follows:

void setup() {                                         // Call the setup function
  int boxSize = 20;                                    // Declare a new variable as type int and assign it 20
  color magenta = color(255, 0, 255);                  // Declare a new variable as type color and assign it magenta
  color white = color(255);                            // Declare a new variable as type color and assign it magenta
  for(int y=0; y < boxSize; y++){                      // Outer Loop: Y - Pixels
    for(int x=0; x < boxSize; x++){                    // Inner Loop: X - Pixels
      if (y == 0 || x == 0 || y == boxSize-1 || x == boxSize-1) {    // Border pixels: If any of the following
        set(y,x,white);                                              // Set this pixel to white
      } else {                                         // Else
        set(y,x,magenta);                              // Set this pixel to magenta (inner pixels)
      }
    }
  }
}

You won’t notice any change to the output of your sketch as we are simply doing something which Processing has previously done automatically for us. However, we need to start explicitly calling the ‘setup‘ function to encapsulate code we don’t wish to be part of Processing’s animation (draw) loop, hence code we need to be run once, at the start of our sketch. The format of the ‘setup‘ function is quite similar to an ‘if‘ or ‘for‘, however, it has an extra name added. The first word ‘void‘ means ‘nothing‘, as in the function we are writing will not return a result, this will be covered in more detail further on. For now when ever we wish to write our own function we first write the word ‘void‘, which is followed by the name of the function, in this case ‘setup‘. Processing will also set the word ‘setup‘ to bold, which indicates that this function is built into Processing. It’s important that we don’t use a name for our own function which is already associated with a built in Processing function. What we are telling Processing here is to ‘call‘ the function with the name ‘setup‘ which will not return any data. ‘Call‘ here means the same is it did earlier when for example we ‘call the function point’. Calling a function is simply a way to tell the computer to ‘lookup’ and execute a set of code which has been grouped and assigned a unique identification name. In the following example we have grouped the code we wrote to draw a box into its own custom function. Calling this function draws the box on the canvas.

We’ve already written a function, thus lets write another, simply by changing the name of our current function. Changing ‘setup‘ to ‘drawRect‘, as so:

void drawRect() {                                      // Define a custom function, with the name drawRect and enclose the following code
  int boxSize = 20;                                    // Declare a new variable as type int and assign it 20
  color magenta = color(255, 0, 255);                  // Declare a new variable as type color and assign it magenta
  color white = color(255);                            // Declare a new variable as type color and assign it magenta
  for(int y=0; y < boxSize; y++){                      // Outer Loop: Y - Pixels
    for(int x=0; x < boxSize; x++){                    // Inner Loop: X - Pixels
      if (y == 0 || x == 0 || y == boxSize-1 || x == boxSize-1) {    // Border pixels: If any of the following
        set(y,x,white);                                              // Set this pixel to white
      } else {                                         // Else
        set(y,x,magenta);                              // Set this pixel to magenta (inner pixels)
      }
    }
  }
}

When you run this sketch you will notice the canvas is empty. This is because though we have defined our custom rectangle drawing function we have not in fact told Processing to ever execute this code. Also note that we have used tabs to indent the code which is contained within our ‘drawRect‘ function between lines 1 and 14.

To tell Processing to execute our ‘drawRect‘ function we need to add a line of code which will call this function. To do this we need to re-add the previous function ‘setup‘ and within setup we will call our ‘drawRect‘ function, as so:

Your browser does not support the canvas tag.

void setup(){
   drawRect();                                         // Call our custom rectangle drawing function
}

void drawRect() {                                      // Define a custom function, with the name drawRect and enclose the following code
  int boxSize = 20;                                    // Declare a new variable as type int and assign it 20
  color magenta = color(255, 0, 255);                  // Declare a new variable as type color and assign it magenta
  color white = color(255);                            // Declare a new variable as type color and assign it magenta
  for(int y=0; y < boxSize; y++){                      // Outer Loop: Y - Pixels
    for(int x=0; x < boxSize; x++){                    // Inner Loop: X - Pixels
      if (y == 0 || x == 0 || y == boxSize-1 || x == boxSize-1) {    // Border pixels: If any of the following
        set(y,x,white);                                              // Set this pixel to white
      } else {                                         // Else
        set(y,x,magenta);                              // Set this pixel to magenta (inner pixels)
      }
    }
  }
}

The ‘call‘ to the ‘drawRect‘ function is similar to the call to the ‘rect‘ function, only our ‘drawRect‘ function has no parameters, to define the rectangles position, size, etc. Therefore, we only need to write: drawRect();, notice the inclusion of empty round brackets, which are required even though there are no parameters. Our ‘drawRect‘ function is rather useless without being able to set the size and position of our rectangle, so lets add this functionality to our ‘drawRect‘ function:

Your browser does not support the canvas tag.

void setup() {
  drawRect(width/2-25, height/2-25, 50, 50);             // Call our rectangle function passing its x and y position and, width and height
}

/*
   * FUNCTION: drawRect
 *
 * Description: A function which draws a magenta rectangle with a white border
 *
 * @param {int}     posX            - x position translation for rectangle
 * @param {int}     posY            - y position translation for rectangle
 * @param {int}     w               - width of rectangle
 * @param {int}     h               - height of rectangle
 */

void drawRect(int posX, int posY, int w, int h) { 
  color magenta = color(255, 0, 255);                    // Declare a new variable as type color and assign it magenta
  color white = color(255);                              // Declare a new variable as type color and assign it magenta
  for (int y=0; y < h; y++) {                            // Outer Loop: Y - Pixels while y is less than height (h)
    for (int x=0; x < w; x++) {                          // Inner Loop: X - Pixels while x is less than width (w)
      if (y == 0 || x == 0 || y == h-1 || x == w-1) {    // Border pixels: If any of the following
        set(x+posX, y+posY, white);                      // Set the pixel at (x plus the posX) and (y plus the posY) translation to white
      } else {                                           // Else
        set(x+posX, y+posY, magenta);                    // Set the pixel at (x plus the posX) and (y plus the posY) translation to magenta
      }
    }
  }
}

Lets take a look at the four parameters we’ve added to our ‘drawRect’ function, on line 16: (int posX, int posY, int w, int h). We’ve declared ‘posX‘ and ‘posY‘ as integer variables to pass the coordinates for our rectangle to be drawn at and we’ve declared ‘w‘ and ‘h‘ as integer variables to pass the width and height for our rectangle. Each of these parameters are required every time we call our ‘drawRect’, therefore we need to alter our call. As done on line 2: drawRect(width/2-25, height/2-25, 50, 50);, where we’ve set the x-coordinate equal to the ‘canvas width divided by 2 minus 25‘, the y-coordinate equal to the ‘canvas height divided by 2 minus 25‘ and both the width and height for our rectangle to 50 pixels.

For the above to take effect we need to make some changes to the code within our ‘drawRect’ function, which needs to use these values to alter the rectangle size and position. Lets start with the width and height parameters, ‘w‘ and ‘h‘. Our loop(s) needs to iterate as many times as the rectangles height and width, therefore these lines need to be changed so that the ‘for‘ loop uses the ‘w‘ and ‘h‘ parameters we’ve passed, thus we alter the loop’s condition statement to be: ‘y < h‘ and ‘x < w‘. Now our loop knows how many times to loop. Next our ‘if‘ statement needs to be updated to know when the loop(s) have reached the boundary of the rectangle. Therefore we change the condition statement to include the ‘w‘ and ‘h‘ parameters as such: ‘(y == 0 || x == 0 || y == h-1 || x == w-1)‘. Now the size of our rectangle is no longer defined by a static value.

Next we need to change our ‘drawRect’ function to know where to draw the rectangle, based on the ‘posX‘ and ‘posY‘ parameters. This can be achieved by adding these parameters to the ‘set‘ function, hence ‘x+posX‘ and ‘y+posY‘.

When this sketch is run Processing will start by executing the ‘setup‘ function, when it reaches line 4 Processing will skip to line 18, as we’ve told it to look for the function ‘drawRect’ and execute the code contained in this function, and will pass the ‘drawRect’ function values for the x-position, y-position, width and height.

Check that you understand exactly how this sketch works. In particular, the way ‘h – 1‘ and  ‘w – 1‘ have been used to draw the right-hand side and the bottom of the rectangle, and how the values of ‘width/2-25‘, ‘height/2-25‘, ‘50‘ and ‘50‘ are passed to the parameters of ‘posX‘, ‘posY‘, ‘w‘ and ‘h‘ within the ‘drawRect’ function. Also pay attention to how within (int posX, int posY, int w, int h) the variables must have their type, integer, declared, so that the function knows what type of data it is using. Hence if you were to call the function with values which are not integer types, such as, floats or strings, Processing would object.

Finally, we can demonstrate the benefit and flexibility of defining our own functions, as we could extend the ‘drawRect’ function to take and use more parameters such as a colour parameter. We can also use the ‘drawRect’ function multiple times which different parameters. As follows:

Your browser does not support the canvas tag.

void setup() {
  size(220,220);
  background(39,40,34);
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      drawRect(i*20, j*20, i*2, j*2);
      drawRect(i*20, j*20, j*2, i*2);
    }
  }
}
...

3.3 Translating (Shapes)

Before we can move onto animating shapes using functions, it would be beneficial to cover two more Processing functions which allow us to translate and rotate. Our goal by the end of this section will be to have successfully translated, rotated many rectangles and have animated them. In the following lessons we will take these ideas further allowing us to create more interesting and interactive sketches, which demonstrate the power of using Processing as a design tool.

Earlier we covered one method to translate rectangles across the canvas, which was through the use of a parameter, as follows:

Your browser does not support the canvas tag.

for (int i = 0; i < 10; i++) {      // Loop 10 times, with an increment of 1
  rect(i*10, 0, 5, 5);              // Draw a rectangle at {i*10,0} with a width and height of 5px 
}

However there is an alternative method to achieve the same thing, and this method will become incredibly important and powerful to use later:

Your browser does not support the canvas tag.

for (int i = 0; i < 10; i++) {      // Loop 10 times, with an increment of 1
  rect(0, 0, 5, 5);                 // Draw a rectangle at {0,0} with a width and height of 5px
  translate(10, 0);                 // Displace objects within the display window by 10px to right, cumulatively
}

As you can see the result of the above codes produce the same output, however, they are in fact achieving this through vastly different methods. In the new method we have used a function called ‘translate‘ on line 3, which can be used to displace objects within the display window by a set x and y value. However, ‘translate‘ does not in fact move the rectangle, but rather moves the set origin point within the Processing canvas. This translation or the origin is cumulative. Hence if we call ‘translate‘ twice with the parameters (‘10,0‘) we would have shifted the origin 20 pixels in the x direction, towards the right. Processing can have multiple origin points, each a child of the previous, and relative to its position, however, the first origin point is referred to as the global coordinate frame. In the above code we are instructing Processing to loop through a set of code 10 times. First drawing a rectangle at {0,0} (origin) followed by translating the global coordinate frame 10 pixels to the right. The following happens 10 times and on each loop our rectangle is drawn at the origin point, yet the origin has been successively shifted 10 pixels, thus it appears that each successive rectangle has been translated to the right.

2D Plane Translated

After our loop is finished if we wanted to draw a rectangle at the starting origin, we would have to write: <code class=” language-java”>rect(-100, 10, 5, 5);</code>, as the global coordinate frame has been shifted a total of 100 pixels to the right, meaning our starting origin is now 100 pixels to the left of the global coordinate frame.

You may be thinking this is a rather complicated way to move a shape, however it becomes necessary when we start to think about how we might rotate a shape, say a box.

3.4 Rotating (Shapes)

We will begin with the simplest of rotations. Lets draw a square in the middle of the screen and rotate it by 20 degrees. We will first need to work out what 20 degrees is within Processing’s units, which are radians.

Radians are based on the relationship of the circumference of a circle to its radius. If the radius of the circle is r (a mathematician’s variable, it could be anything, two, fifty, or nine thousand), then circumference is 2 x π x r, where π (is English, pronounced ‘pie’) is about 3.141. Mathematicians usually chop the multiplication signs and write 2πr. One radian is simply one radius of the circle round the circumference. Therefore to go 360° round the circumference, you have to move round 2π radii, so there are 2π radians to a full circle, or 360°. This leads to people talking of angles in terms of multiples of π — you will often hear ‘half pie’ (90°) and ‘two pie’ (360°). So often, that Processing has two special variables for them ‘HALF_PI‘ and ‘TWO_PI‘.

But that’s enough of radians, let us use them. Thus 20 degrees is about 0.35 radians. So, first draw a box rotated by 0.35 radians:

Your browser does not support the canvas tag.

rect(40, 40, 20, 20);    // Draw rect, with position at center and a size of 20 pixels
rotate(0.35);            // Rotate by 20 deg

This results in box at the centre of the screen, yet unrotated. The first mistake we have made is thinking of drawing a box and then rotating it. Yet, remember in Processing, the coordinate frame is rotated and then the box is drawn, not the other way around. Thus we need:

Your browser does not support the canvas tag.

rotate(0.35);            // Rotate by 20 deg
rect(40, 40, 20, 20);    // Draw rect, with position at center and a size of 20 pixels

However, this has resulted in a box shifted 20 degrees about the origin of the canvas {0,0}. It is a little difficult to visualise this in our head, with only a box, so to see it more easily we can draw a frame the size of the canvas which represents the canvas itself. To achieve this we can do the following:

Your browser does not support the canvas tag.

rotate(0.35);            // Rotate by 20 deg
noFill();                // Set fill state to empty
rect(0,0,width,height);  // Draw rect, with position at 0,0 and size equal to canvas
fill(255);               // Set fill state 'back' to white
rect(40, 40, 20, 20);    // Draw rect, with position at centre and a size of 20 pixels

To make this even easier to understand, and before moving on, it is probably best to visualise the rotation through rotating the canvas continually.

3.5 Continuous Rotation (introducing draw)

So that we can see exactly what is happening to the global coordinate frame in which we are drawing the rectangle, it is helpful to watch it move in action. To do this, we can implement another standard function in Processing, the ‘draw‘ function. In Processing, ‘draw‘ is called to draw the scene, then, once the scene has been drawn, it is called again, and again, and again.

The code bellow is my first attempt to make a continuously rotating rectangle. Notice that I have decided to make the rectangle rotate only a tiny amount, 0.0175 radians, or about 1 degree, every frame (that is, each time Processing draws my rectangle):

Your browser does not support the canvas tag.

void draw() {
  rotate(0.0175);          // Rotate by 1 deg  
  rect(40, 40, 20, 20);    // Draw rect, with position at center and a size of 20 pixels
}

Though, when you run this sketch it is evident that we don’t have a constantly rotating rectangle, as it is static. However, if you look closer at the rectangle you may be able to see that the rectangle has rotate approximately a single degree. Unlike the previous for loop, where each call to the ‘translate‘ function, translated the global frame cumulatively, the global coordinate frame is reset each time the code in the ‘draw‘ function is executed. Thus, we are in fact rotating the global coordinate frame a bit, drawing our rectangle, then Processing resets the global coordinate frame, we rotating the global coordinate frame a bit, and so on.

There is a method which allows us to remember the previous rotation, which makes use of a variable, which we will call ‘frame’ which will store the number of the frame we are displaying. Each time the ‘draw‘ function runs, we will increment ‘frame‘ by one, using the ‘++‘ operator. Then, we can multiple the amount of rotation we apply by the number stored by our ‘frame‘ variable. Thus frame one will be 1 x 0.0175 radians, frame two will be 2 x 0.0175 radians and so on:

Your browser does not support the canvas tag.

int frame = 0;             // Declare integer type variable and assign it the value 0
void draw() {
  frame++;                 // Increment our frame counting variable by 1
  rotate(0.0175 * frame);  // Rotate by 1 deg, each frame
  rect(40, 40, 20, 20);    // Draw rect, with position at center and a size of 20 pixels
}

It’s important to take note of two points before we continue. You will see we have declared and assigned the ‘frame‘ variable on line 1: int frame = 0; which has been written outside of the ‘draw‘ function.

This is referred to as creating a global variable which can be used by any and all functions throughout our sketch. Global variables are incredibly handy for storing settings for your entire project, which many functions need access to. However, it’s still recommended to only use global variables where you absolutely need them.

This is important, as if we had included the ‘frame‘ variable within the ‘draw‘ function we would be in the same situation as the previous example, with a static box, as every time draw runs we reset the value of ‘frame‘ to 0, instead of allowing it to increment for every iteration of ‘draw‘. Secondly we need to increment ‘frame‘ within the ‘draw‘ function, so that for every iteration of ‘draw‘ the value of ‘frame‘ increases, see line 3.

At last we have a moving box and if you wait a few seconds you will see the box return and complete the circle! However, we can only see a quarter of the circle formed by our boxes. But is this what we initially wanted? The answer is an emphatic no. Firstly we can see multiple boxes, one behind the last. The reason for this is that we are kind of drawing the frames of our animation on tracing paper, in such that our background is never reset. So lets first solve this by redrawing the background before our rectangle is drawn. This can be achieved as so:

int frame = 0;             // Declare integer type variable and assign it the value 0
void draw() {
  frame++;                 // Increment our frame counting variable by 1
  background(192);         // Redraw the background
  rotate(0.0175 * frame);  // Rotate by 1 deg, each frame
  rect(40, 40, 20, 20);    // Draw rect, with position at centre and a size of 20 pixels
}

Finally, our animation looks a little more like what we had initially intended, though we still need to address the fact that the box is spinning ‘off axis’ as we are not really rotating the box itself but rather the global coordinate frame which the box is drawn on, as discussed earlier in section 3.4 Rotating (Shapes). We will address this in the next section.

Now maybe our box is rotating a little to fast for our preferences. There is a simple solution to this that does not involve altering the ‘frame‘ variable or the rotation logic but rather by altering how many times per second Processing will try to execute the ‘draw‘ function. To do this we need to include a call to the function ‘frameRate‘ which accepts a single integer type parameter. Lets try altering the default frameRate which Processing automatically sets from 60 to 24, as follows:

Your browser does not support the canvas tag.

int frame = 0;                             // Declare integer type GLOBAL variable and assign it the value 0

void setup() {
  frameRate(24);                           // Set frame rate to 24
}

void draw() {
  frame++;                                  // Increment our frame counting variable by 1
  background(39,40,34);                     // Redraw the background
  rotate(0.0175 * frame);                   // Rotate by 1 deg, each frame  
  rect(width/2-10, height/2-10, 20, 20);    // Draw rect, with position at center and a size of 20 pixels
}

Notice that the declaration for our ‘frame‘ global variable remains outside of the ‘setup‘ function, since it is being used in the ‘draw‘ function, had we included it in setup the scope of the ‘frame‘ would have been limited to within setup, thus ‘frame‘ would not be a global variable.

3.6 Rotating A Rectangle On Its Axis

What is noticeable about all our previous attempts at rotating a box is that in each case the rotation occurs around the global origin {0,0}.

Jeremy Paton

Author Jeremy Paton

More posts by Jeremy Paton

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.