14.04.2014 Views

Hello Processing - Vula

Hello Processing - Vula

Hello Processing - Vula

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

An Introduction To Programming With <strong>Processing</strong><br />

This publication is released under a Creative Commons Attribution-<br />

NonCommercial-NoDerivs 3.0 License. CC BY-NC-ND 2011<br />

You are free to share, and redistribute this publication in whole, but not in part<br />

under the following conditions.<br />

The person identified as the author in the following terms is also known as<br />

Lyndon Daniels and is the owner of the domain name<br />

http://www.lyndondaniels.com<br />

“Classified works of the author” and “a classified work of the author” will include<br />

all content and redistributions of the content, that the author has created and is<br />

licensed to the author by de facto or de jure.<br />

“This publication” refers to the document you are currently reading in it's entirety<br />

and is also a classified work of the author.<br />

1. This publication and all redistributions of this publication must remain as<br />

is, and not in any way be modified.<br />

2. All redistributions of the source code and related material, including but<br />

not limited to the images associated with this publication, that are not<br />

licensed under other terms or are not classified works of the author, also<br />

fall under the same license of this publication.<br />

3. Attribution must be given to the author for all redistributions of the<br />

classified works of the author.<br />

4. Acceptable attribution for redistributions of this publication must associate<br />

the publication/s duplicated as being a classified work of the author.<br />

5. This publication is only to be redistributed digitally and not to be<br />

redistributed in any other format including, but not limited, to print.<br />

6. No capital or commercial profit, monetary or other, is to be gained from<br />

this publication or redistributions of this publication without the author's<br />

consent. This includes, but is not limited to selling and/or trading this<br />

publication or any redistributions.<br />

7. All redistributions of this publication are to be released under the same<br />

license that this publication is released under.<br />

8. The author solely reserves the right to change this agreement at any time.<br />

For additional information regrading this license please see<br />

http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode<br />

2


An Introduction To Programming With <strong>Processing</strong><br />

Table Of Contents<br />

About This Guide 7<br />

Hardware and Software Theory 7<br />

What is Programming? 7<br />

How does Programming relate to Hardware and Software? 8<br />

Abstraction 10<br />

Speed 11<br />

Efficiency 12<br />

Disambiguation 14<br />

The Unique Qualities of a Programming Language 17<br />

Lower Level Languages and Higher Level Languages 20<br />

An Analysis of a Computer Program 22<br />

Commands 23<br />

Expressions 23<br />

A Scalable Software Development Model 25<br />

Plan 25<br />

Research 26<br />

Mockup Designs 27<br />

Data Acquisition: Sourcing The Data Needed For Your Project 28<br />

Filter 29<br />

Clustering and Data Mining 29<br />

Parsing 32<br />

Determining Flow of Control Through Stepwise Refinement 32<br />

Implement, Test and Document. Repeat 34<br />

Deliver 35<br />

Why Learn Programming using <strong>Processing</strong>? 36<br />

Code For Artists 36<br />

Java Based 36<br />

Open Source 37<br />

PDE 38<br />

Source Code Editor 40<br />

Build Automation Tools 40<br />

Compiler and/or Interpreter 41<br />

Debugger 42<br />

Active Online Community 43<br />

Table Of Contents 3


An Introduction To Programming With <strong>Processing</strong><br />

<strong>Hello</strong> <strong>Processing</strong> 44<br />

Install <strong>Processing</strong> 44<br />

Sketches 44<br />

<strong>Hello</strong> World Program 1.0 45<br />

The println() Function 47<br />

Syntax And Syntax Errors 48<br />

Logical Errors 50<br />

Display Window 50<br />

Standardized Coding Practices 52<br />

Comments 52<br />

Whitespace 53<br />

Program Notes 54<br />

Cartesian Graph and the <strong>Processing</strong> Coordinate System 54<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 56<br />

text() 56<br />

Program Notes 57<br />

Formatting Text 58<br />

Color 59<br />

Drawing 62<br />

2D Primitives 62<br />

The Origin of an Ellipse 63<br />

Aliasing 66<br />

Smile 66<br />

Angles in <strong>Processing</strong> 66<br />

Editing the Smile 69<br />

Adding Eyes 72<br />

Drawing Irregular Shapes 73<br />

Order, Order! 78<br />

Finishing the Sketch 78<br />

Programming Paradigms 80<br />

Datatyping Categories 81<br />

Primitive Data Types 81<br />

<strong>Processing</strong> API Data Types 82<br />

User Defined Complex Data Types 83<br />

PImage 83<br />

The Design and Layout Program 86<br />

Program Notes for Interface01.pde 86<br />

Table Of Contents 4


An Introduction To Programming With <strong>Processing</strong><br />

The PDE Tools Menu 86<br />

Beyond Static Sketches and on to Active Mode 90<br />

Methods, Functions and their contexts 91<br />

The setup() function 92<br />

The draw() function 94<br />

Experimentation 96<br />

Datatyping 101<br />

Variables 102<br />

Variable Scope 104<br />

Interacting with Images 106<br />

Friction Simulation 109<br />

Variable Naming Conventions 111<br />

Planning and Pre-debugging 112<br />

Implementing a Programmatic Solution 114<br />

Constraining Values 116<br />

Branching 118<br />

The if() structure 120<br />

Relational Operators 121<br />

Comparison 121<br />

Extending the if() structure with else 124<br />

Extending the if() construct with if else if else 126<br />

Logical Operators 127<br />

Interface Controls Setting up a Slider 128<br />

User Defined Functions 130<br />

Creating a User Defined Function 134<br />

Datatyping a Function 134<br />

Determining a Range 134<br />

Returning Data from a Function 138<br />

Dragging the Slider Button 140<br />

Setting up Regional Constraints 142<br />

Finishing the Slider 144<br />

Mapping Values 144<br />

The Mystery Shape Maker 148<br />

Arrays 149<br />

Program Notes 153<br />

Dynamic Assignment for Elements in and Array 155<br />

Iterations 158<br />

Table Of Contents 5


An Introduction To Programming With <strong>Processing</strong><br />

Transforms 162<br />

An Introduction to 3D in <strong>Processing</strong> 176<br />

3D Primitives 177<br />

Guess My Number Game 179<br />

Object Oriented Programming 181<br />

The Concept of a Class 182<br />

The Blueprint Analogy 183<br />

Why Use Object Oriented Programming 185<br />

Creating a Class 185<br />

A Button Class 188<br />

Object Instantiation<br />

Working with External Data 193<br />

Attribution 197<br />

Images 197<br />

Table Of Contents 6


An Introduction To Programming With <strong>Processing</strong><br />

About this Guide<br />

Introduction to Programming with <strong>Processing</strong> is a guide to creating interactive<br />

software with the programming language, <strong>Processing</strong>. The main focus of the<br />

documentation is to give the reader an understanding of the programming<br />

language, <strong>Processing</strong> and also to give the reader the knowledge to apply an<br />

understanding gained from reading this documentation to learning other similar<br />

high level programming languages.<br />

Hardware and Software Theory<br />

What is programming?<br />

A software program is a set of instructions issued to a computer via source code.<br />

Source code is data that usually resembles a text document which is typed in a<br />

specific programming language that is somewhere between a language that<br />

computers can process efficiently and humans can understand. The task of<br />

creating source code is known as programming.<br />

Human readable source code on the left and machine code on the right.<br />

Although source code does not make sense at first glance to someone new to<br />

programming, when compared to it's equivalent in machine code it definitely looks more<br />

appealing.<br />

Hardware and Software Theory 7


An Introduction To Programming With <strong>Processing</strong><br />

How does programming relate to hardware and<br />

software?<br />

Before we get into the process of creating software programs, lets first examine<br />

the relationship between a software program and a computer.<br />

One of the fundamental functions of a computer is it's ability to control electrical<br />

energy and ultimately transform that energy into another form of energy such as<br />

light, sound or motion. We use software to communicate with a computer, which<br />

will determine the various paths that the electrical energy will take, in order to<br />

achieve the goal we have stipulated through programming.<br />

Computers are designed to react to electrical energy, this energy can be of a high<br />

or low voltage and forms the basic premise of all the complex interactions that<br />

exists between humans and computers. These high and low voltages of electrical<br />

energy are relayed within the circuitry of a computer in very short intervals that<br />

allow us to distinguish one from the other and will eventually be sequenced<br />

together to form a protocol for communicating with computers.<br />

This protocol of communication we represent with two numerical digits a 1 and a<br />

0, which to a computer equates to a high and a low voltage. We refer to this form<br />

of representation as Binary Code. Of course, this representation means nothing to<br />

a computer as it is only reacting to the electrical energy that is being relayed<br />

within it's circuitry. But to us using a 1 and 0 as a form of representation creates a<br />

means for every simple to complex interaction we have with computers through<br />

software.<br />

By combining various sequences of 1's and 0's (and ultimately sequences of high<br />

and low voltages) followed by more sequences of 1's and 0's arranged in similar<br />

or different patterns the effect of a continuous flow of energy is created that<br />

results in light or sound or one of the many other capabilities of a computer. The<br />

fact that this flow of electrical energy is broken up into smaller chunks means that<br />

each chunk can be made up of a different sequence of 1's and 0's which could be<br />

used to create the impression of a change or variation which could finally be<br />

perceived as an image moving in an animation or the diaphragm of a speaker<br />

vibrating at different amplitudes which, for example, we ultimately perceive as<br />

the sound of our favorite track.<br />

Hardware and Software Theory 8


An Introduction To Programming With <strong>Processing</strong><br />

Although useful, representing data in this way can become quite cumbersome and<br />

error prone. If developing software meant having to learn endless sequences of<br />

binary code, becoming a programmer would be a very daunting task. This is,<br />

however, not the case as we can use a 1 and a 0 to represent a high and a low<br />

voltage we can use a sequence of 1's and 0's to represent more complex ideas<br />

such as a larger number like 155 which can be translated into binary as 10011011.<br />

This form of representation can furthermore be extended to include typographic<br />

characters, which in themselves can be strung together in sequences to create<br />

words, which can in themselves be strung together to issue commands to a<br />

computer through programming. We refer to this process as abstraction.<br />

Programming in it's simplest form is the process of creating and modifying a<br />

series of 1's and 0's that influences the path of the electrical current, by means of<br />

abstraction.<br />

At some point everything that a computer processes (including our own<br />

interactions with it) has to exist in binary code representations. However, it's<br />

important to remember that binary code is simply just a human representation, for<br />

determining a sequence of high and low voltages, that we use to make the<br />

complexities that occur within a computer more understandable to us.<br />

As I mentioned earlier, a computer does not really care about what form of<br />

representation we use, however this process of representing data certainly does<br />

make it a lot easier to communicate with computers.<br />

We interface with computers via software which allows us to work in an individual<br />

capacity, whenever applicable, in fields that would previously have required teams of<br />

people working together.<br />

Hardware and Software Theory 9


An Introduction To Programming With <strong>Processing</strong><br />

Abstraction<br />

Representing the abstract concept of something like data in the form of high and<br />

low voltages with a series of 1's and 0's can be quite useful, but still very difficult<br />

to read and understand. Imagine having to memorize all of those sequences in<br />

order to be an efficient programmer. It would take exorbitant amounts of time to<br />

create the simplest of software programs. Fortunately the process of representing<br />

human-relevant concepts to a computer does not stop at binary code. Since we<br />

know that a certain sequence of 1's and 0's on a certain type of machine such as<br />

the sequence “00110101” can be used to represent the number “53” why not make<br />

the sequence “01001000” and “01101001” represent the characters “h” and “i”<br />

put together to make the word “hi”. This is exactly what software developers do,<br />

the process of taking a complex set of data and representing it in a more humanreadable<br />

format is known as abstraction. As you can image this makes it a lot<br />

simpler to communicate with a computer, so instead of typing “01001000<br />

01101001” we can simply type “hi” and thanks to the process of abstraction our<br />

computer knows what to display even though it's reading a sequence of high and<br />

low voltages at the simplest level.<br />

Abstraction is great because it makes the process of communicating with<br />

computers easier, so you might be thinking to yourself why then is programming<br />

and source code so cryptic and far removed from a common natural spoken<br />

human language such as English? Surely, if we can abstract complex data why<br />

not keep on abstracting concepts to computers until it can understand a human<br />

specific language like plain and simple English?<br />

For example if we wanted to draw a circle on a computer screen why can't we just<br />

say to a computer:<br />

“Computer, could you please draw a circle that has a diameter of<br />

55 pixels and who's center is somewhere close to the top left of<br />

my screen, thanks?”<br />

Instead we communicate with our computers like this:<br />

ellipse(56, 46, 55, 55);<br />

Abstraction 10


An Introduction To Programming With <strong>Processing</strong><br />

There are three main issues to consider here speed, efficiency and disambiguation.<br />

Speed<br />

One of the main reasons we cannot continue to abstract our communications with<br />

computers to the point where everyday English is used, is due to the speed at<br />

which data can be processed.<br />

As we abstract data in order to make it more human-readable that same data<br />

becomes less machine-readable, and in order for a machine to be able to make<br />

anything useful out of that data it must first convert that data into a machinereadable<br />

format.<br />

All of this abstracting and un-abstracting requires valuable system resources and<br />

energy, system resources and energy that could be used more effectively<br />

elsewhere. Subsequently as we move further away from machine code we require<br />

faster more powerful computers to process the data we create.<br />

It's estimated that under certain circumstances a consumer grade Intel Core i7 3.3<br />

GHz processor can preform 147,600 Million instructions per second, and if<br />

you've ever used one of these processors you'll probably also note that even with<br />

all of that processing power there are certain situations where your computer can<br />

still lag!<br />

This does not necessarily have anything to do with the processor specifically but<br />

simply due to the massive amounts of data that an average modern day computer<br />

is expected to cope with. To put this into perspective consider that 40 years ago in<br />

order to send a man to the moon computers with a clock speed of 0.043MHz and<br />

64Kbyte of RAM were required to run software ranging about 6MB in size, by<br />

today's standards a single modern day home computer could be about 77 million<br />

times more powerful than the computers used to launch a space shuttle, navigate<br />

it to the moon and safely return it to earth such as the Apollo Guidance Computer.<br />

In retrospect the modern day needs we place on our computers can be somewhat<br />

demanding.<br />

Abstraction 11


An Introduction To Programming With <strong>Processing</strong><br />

The Apollo Guidance Computer used on Apollo 11 on the left and the NASA Manned<br />

Spacecraft Center on the right. Technology from the 1960's.<br />

Efficiency<br />

Like any natural language, computer languages are built around their<br />

environments. Human cultures have developed languages as a means of<br />

communicating their perceptions of internal, conceptual and external<br />

environments. However what exists in one environment might not be a part of<br />

another. Subsequently, a string of words might be used to describe something that<br />

is uncommon to one environment, whereas in another culture where that thing is<br />

common a single word might be used to describe it.<br />

For example a visitor traveling to Japan in the late 1800's might describe a<br />

specific mode of transport as:<br />

“A human-powered two wheeled cart, that seats one or two people<br />

reserved for the social elite.”<br />

However a person familiar with this mode of transport might have a specific name<br />

for it, such as:<br />

Abstraction 12


An Introduction To Programming With <strong>Processing</strong><br />

“Rickshaw”<br />

Rickshaws are not a common sight in modern times but where a regular mode of<br />

transport in Japan, in the 1800's<br />

Obviously if you are living in an environment where such things are common<br />

using a single word that can effectively describe a whole sentence can be a more<br />

efficient means of communication.<br />

Computer languages are similar in this way, each language is developed to run<br />

efficiently under certain conditions and circumstances yet the same language may<br />

perform less efficiently under a different set of circumstances.<br />

What qualifies as an optimal environment for a computer's programming<br />

language is something that the developer of that language will have to define. An<br />

environment in this sense could be an operating system, the world wide web, a<br />

network, or a combination of these environments. This could also be a large<br />

contributing factor, possibly explaining why there are so many different computer<br />

languages currently in existence each with it's efficiency optimizations for<br />

specific “environments”.<br />

Currently Wikipedia lists approximately 661 popular computer languages and this<br />

number is constantly growing compared to it's listing of 540 currently spoken<br />

languages (not including their derivatives). Of course there have been many more<br />

Abstraction 13


An Introduction To Programming With <strong>Processing</strong><br />

spoken languages throughout human history, The Cambridge Encyclopaedia of<br />

Language estimates this number to be between 3000 to 10000, but then again<br />

what actually qualifies as a language is a whole other topic for discussion in itself.<br />

Computer languages share in this ambiguity. Throughout the comparatively short<br />

history of computer languages, which can arguably be traced as far back as the<br />

first programmable computer, the Z1 invented by Germany's Konrad Zuse in<br />

1938, programmers have seen languages raise to popularity and become virtually<br />

obsolete, one such language is LISP. LISP was in many ways synonymous with<br />

Artificial Intelligence (AI) from the mid 1950's till the early 1970's but gradually<br />

gave way to a dwindling numbers of devotees, who where lured by new<br />

programming paradigms such as object oriented programming and other higher<br />

level programming language concepts, which we will explore in greater detail<br />

later. Although this language never really died, some would say it became<br />

somewhat antiquated. Nonetheless, LISP started to regain popularity in the mid<br />

1990's in a new implementation currently known as Common LISP. Determining<br />

whether a programming language closely based on a previous programming<br />

language should be considered a new language that is able to stand on it's own,<br />

can be a difficult distinction to make and can add considerably to the ambiguity<br />

around what defines and distinguishes one computer language from another.<br />

<strong>Processing</strong> too, has been subject to this topic of debate as it's roots in the<br />

programming language Java have seen it referred to as a library for Java while<br />

others identify it as stand-alone programming language.<br />

Regardless of whether a programming language derived from another can stand<br />

on it's own or not one of the key factors that determine it's popularity, and<br />

ultimately contributes to a following of devotees that develop and maintain the<br />

language, is the language's ability to achieve a balance of being fast enough for a<br />

computer to process but easy enough for a human to read. It is this balance that<br />

currently determines the efficiency of a computer's programming language.<br />

Disambiguation<br />

Computers tend to be very literal. They accept specific instructions more readily<br />

than vague descriptions of what you are hoping to achieve with their help. Such<br />

that a statement like the above mentioned, and repeated below:<br />

“... draw a circle that has a diameter of 55 pixels and who's<br />

Abstraction 14


An Introduction To Programming With <strong>Processing</strong><br />

center is somewhere close to the top left of my screen...”<br />

would not be as effective as the statement:<br />

ellipse(56, 46, 55, 55);<br />

The first statement although a perfectly acceptable command issued in English,<br />

would fail dismally when translated directly into computer-speak for several<br />

reasons relating to the ambiguity associated with it.<br />

Firstly the longer a command tends to be the more prone it is to incorporating an<br />

erroneous syntax. Computers are very specific about the type of syntax you use to<br />

communicate with them. Syntax in terms of the English definition is the particular<br />

arrangements of words making up a sentence. In computer terms, syntax has a<br />

very similar meaning but is even more relevant and specific in it's<br />

implementation. Words must follow a particular sequence within the context of a<br />

command issued to a computer determined by the language you are currently<br />

programming in, and may not be rearranged into various discourses simply<br />

because you find them to be more meaningful.<br />

Computers have truly amazing mathematical capabilities and predictably<br />

congruent mediocre social skills. Subsequently concepts such as circles and<br />

squares which are simply mathematical concepts abstracted for human<br />

convenience have little or no relevance to a computer. For example if you were to<br />

consider that a circle, as per another description, could be an ellipse with<br />

equidistant radii to each point encompassing it's edge; or technically speaking a<br />

square is actually a rectangle with it's height equal to it's width. Descriptive<br />

abstractions such as these for human convenience are in fact very inconvenient<br />

for a computer, and as a result in <strong>Processing</strong> we refer to a “circle” and an “ellipse”<br />

using <strong>Processing</strong> specific syntax that removes the ambiguity and abstraction for<br />

the convenience of a spoken language and groups them into the same context.<br />

Subsequently if we want to describe a circle we refer to it as an ellipse with equal<br />

dimensions in height and width or more specifically:<br />

ellipse(56,46,55,55);<br />

Finally I'm sure that if computers had a sense of humour, they would find our<br />

former description of the location of our circle “ somewhere close to the top<br />

Abstraction 15


An Introduction To Programming With <strong>Processing</strong><br />

left of my screen” to be somewhat uninformed and laughable, not to mention<br />

words such as “somewhere” and “my” which might condition a response<br />

equivalent to that of an existential dilemma for a computer. If you supply a<br />

computer program with specific screen positions in terms of x, y and z and<br />

dimensions in terms of width, height and depth either communicated explicitly or<br />

implicitly through an expression (which is something we will discuss in more<br />

detail later) you will find your programs to have more predictable and efficient<br />

results and would help to remove ambiguities that could lead to errors. Screen<br />

space and dimensions are concepts we will be dealing with in more detail in later<br />

chapters. Of course there are times when randomness and unpredictability are<br />

desirable qualities in a program, in which case no other resources available to<br />

man can produce a series of unpredictable results more efficiently than<br />

computers. This is a testament to why people devotedly invest in computers to<br />

provide the sequence of random digits that could potentially make casinos loose<br />

millions upon millions to gambling patrons.<br />

Computers, and subsequently software are used in various fields of medical technologies<br />

where predictability is of the utmost importance. Gambling machines also use software<br />

but in contrast to medical software predictability in the application of the software, is an<br />

undesirable effect for the machine owners.<br />

Abstraction 16


An Introduction To Programming With <strong>Processing</strong><br />

The Unique Qualities of a Programming<br />

Language<br />

At the simplest level a programming language should be Turing complete. Turing<br />

complete refers to a set of data manipulation rules that, can simulate a Turing<br />

machine. This begs the question to be asked, who is Turing and what is his<br />

machine?<br />

Alan Turing was a British mathematician that is heralded as the father of<br />

computer science. He lived from 1912 to 1954 when he died at the age of 41.<br />

Turing is responsible for creating the Turing machine which is a theoretical<br />

device that operates with a strip of tape imprinted with an infinite array of<br />

symbols, the machine is able to read a symbol and alter the symbol and the<br />

symbol in turn affects the behaviour of the machine. The tape that the symbols are<br />

printed on represent memory and it can move back and fourth so that any symbol<br />

can be read by the machine and altered by it, additionally at any given time a<br />

symbol is affecting the state of that machine.<br />

Turing referred to this machine as an "a(utomatic)-machine" and it forms the<br />

fundamental logic of all computer algorithms. This principle is still used in<br />

modern computers. A programming language that is Turing complete complies<br />

with this logic, and will subsequently be able to run on all computers based on the<br />

Turing machine. What this simply means is that programming languages will<br />

need to be able to run on a basic computer system that at the very least has a<br />

Central <strong>Processing</strong> Unit (CPU) that is based on the Turing machine, which<br />

includes all known operational computer models.<br />

Quantum computing models are commonly based on the quantum Turing<br />

machine also known as the Universal Quantum Computer, and even these models<br />

can be related back to the classical Turing machine. Quantum computing models<br />

are theoretical models of how a quantum computer could work once the<br />

technology can be implemented, in much the same way that the Turing machine<br />

was a theoretical model of today's modern computer before it's current<br />

implementation.<br />

The Unique Qualities of a Programming Language 17


An Introduction To Programming With <strong>Processing</strong><br />

Alan Turing (1912 - 1954) is heralded as the father of computer science<br />

What about speed, efficiency and dis-ambiguity, are these not also amongst the<br />

unique qualities of a programming language?<br />

Simply put, no they are merely guidelines that programmers may or may not<br />

adapt into the computer languages they develop. However, most useful<br />

programming languages will in some form or another adapt these standards into<br />

their design. There is another form of computer language development that does<br />

not comply with these standards, but the languages that develop from this field do<br />

still comply with Turing completeness, as without this design implementation it<br />

would not be possible to run the language on a computer modern or old.<br />

This field of computer science is referred to as esoteric programming languages.<br />

Esoteric programming languages usually are not designed to be useful for realworld<br />

programming situations but are usually more popular among hackers that<br />

develop these language to test the boundaries of computer programming language<br />

design.<br />

A relatively well known example of an esoteric programming language is the<br />

language known as brainfuck . Brainfuck is known as a Turing-tarpit language as<br />

it still qualifies as a Turing complete language even though the entire language<br />

consists of only 8 commands and no operands. We'll be discussing what exactly a<br />

command is shortly and what an operand is a bit later, but needless to say this is a<br />

language that is still functional with a bare minimum of interfacing protocols. An<br />

example of a “hello world program” (yet another concept we will get to a bit<br />

later), which is a program that simply prints the words “hello world” to the screen<br />

in brainfuck code follows:<br />

The Unique Qualities of a Programming Language 18


An Introduction To Programming With <strong>Processing</strong><br />

++++++++++[>+++++++>++++++++++>+++>+.<br />

LOLCODE is another example of an esoteric programing language that is based<br />

on the text within lolcats images. Lolcats are images of cats that circulate the<br />

Internet, often in cute and whimsical representations. These images are<br />

accompanied with text that is generally idiosyncratic and grammatically incorrect<br />

with the intent to contribute humour to the image.<br />

An example of a typical lolcat image<br />

An example of a <strong>Hello</strong> World program in LOLCODE follows:<br />

HAI<br />

CAN HAS STDIO?<br />

VISIBLE "HAI WORLD!"<br />

KTHXBYE<br />

As you can see the language uses what is typically termed as “lol-speak” as an<br />

integral part of it's syntax and keywording.<br />

The Unique Qualities of a Programming Language 19


An Introduction To Programming With <strong>Processing</strong><br />

Lower Level Languages and Higher Level<br />

Languages<br />

Generally speaking higher level programming languages are closer to human<br />

spoken languages and lower level programming languages are closer to machine<br />

code, or binary. However this classification might not always be so clear. C++ is<br />

one language that some might argue challenge this programming language stereo<br />

type. C++ is a programming language that has all the features that one would<br />

expect from a higher level language such as an easy to read syntax, object<br />

oriented programming and extensive collections of libraries to add to the<br />

language's capabilities but also has other features that are not commonly found in<br />

higher level languages such as memory management, user defined operator<br />

overloading, six different integer datatypes and a plethora of compilers to choose<br />

from. As a result many refer to C++ as a mid-level programming language.<br />

For <strong>Processing</strong> this distinction is currently not so difficult to make. <strong>Processing</strong> is a<br />

high level language, meaning it has an easy to read syntax, supports modern day<br />

programming concepts such as Object Oriented Programming, has it's own IDE<br />

(Integrated Development Environment something we will become more familiar<br />

with throughout this guide) and fundamentally it abstracts a lot of machine<br />

specific interactions for us making the code more readable for humans.<br />

However, it's worth considering that the terms “higher” and “lower” level<br />

programming languages are relative to the time period in which they are used. For<br />

example when the programming language C (that C++ is based on) was first<br />

introduced in the early 1970's it was considered to be a high level language as it<br />

supported such features as expression evaluation and datatyping, both of which<br />

are programming concepts common to most modern day programming languages.<br />

As technology progresses, new concepts become common place and rapidly<br />

replace older more cumbersome programming designs, till we get to the point<br />

where there are far less people that would refer to an older language such as C as<br />

being a high level language and a lot more people that would refer to it as a low<br />

level language, lacking modern abstractions and less direct hardware interactions.<br />

<strong>Processing</strong> might one day, also be subjected to such a topic of discussion.<br />

Lower Level Languages and Higher Level Languages 20


An Introduction To Programming With <strong>Processing</strong><br />

Following is the C version of a “<strong>Hello</strong> World” Program:<br />

#include <br />

int main(void)<br />

{<br />

printf("hello, world\n");<br />

return 0;<br />

}<br />

The level of abstraction that is needed in order for a language to qualify as a<br />

higher level programming language does not come without it's penalties. Lower<br />

level languages, because they are conceptually closer to machine code are<br />

considered to produce more efficient machine readable code, of course this is<br />

largely dependent on the programmer creating the code. As mentioned before the<br />

greater the level of abstraction of the code, the more stress that is placed on the<br />

machine interpreting the code, and subsequently more system resources are<br />

required. As a result of this cycle higher level programming languages generally<br />

cannot run on systems where resources are limited. Initially, this might not seem<br />

like such a big issue to you, but have you ever considered the amount of<br />

technology running on limited resources like a television, fridge, GPS, mobile<br />

phone, remote-controlled air-conditioner, electronic toys, media players and the<br />

list goes on...? In fact if you were to think about it there are not many devices like<br />

computer workstations, laptops or computer servers that are designed to have<br />

their resources, available to the software that runs on these machines, extended.<br />

Yet, even these machines have their limitations.<br />

Ultimately software, whether it is designed with a high level or low level<br />

programming language, should always take into consideration the possible<br />

limitations of available system resources.<br />

Lower Level Languages and Higher Level Languages 21


An Introduction To Programming With <strong>Processing</strong><br />

An Analysis of a Computer Program<br />

As we are already aware Binary is a conceptual model that people have invented<br />

to represent the workings of a machine. Binary resultantly forms the basis of all<br />

software because as mentioned earlier no matter what programming language you<br />

use that code must be translated into a machine readable format before it can be<br />

interpreted by a machine, the product of this translation is usually represented as<br />

binary code.<br />

Computer Software is conceptual and intangible as opposed to hardware which is<br />

tangible such as a motherboard, a CPU, an optical drive or a monitor. As a result<br />

the word software is intentionally used to contrast the term hardware.<br />

Programming is a means of creating software and a computer program is a type of<br />

software. Specifically, a program is a set of instructions issued to a computer in a<br />

programming language, such as <strong>Processing</strong>. These instructions are usually made<br />

up of one or many statements. Depending on what language you are programming<br />

in statements can consist of several different parts, such as<br />

• expressions<br />

• commands<br />

• assignments<br />

• comparisons.<br />

Statements can also be made up of many other parts not mentioned here, but for<br />

now we are most interested in two of these components making up a statement,<br />

commands and expressions, the rest we will get to later.<br />

An Analysis of a Computer Program 22


An Introduction To Programming With <strong>Processing</strong><br />

Commands<br />

If you were to compare a statement in computer programming to a sentence in a<br />

natural language, a computer programming statement could be considered to be<br />

somewhat imperative. For example the following sentence in a natural language:<br />

“Run, as fast as you can!”<br />

This would be an imperative statement in English issued to the implied subject. In<br />

extending this comparison, a verb in an imperatively spoken sentence would have<br />

the same purpose as a command in a programming language. A command in a<br />

programming language usually implies a directive issued to a computer, in other<br />

words it's a means of telling a computer to do something. In <strong>Processing</strong> we often<br />

use functions to tell a computer what to do, a function in this sense is a type of<br />

command. Functions are the building blocks of <strong>Processing</strong> programs, as you will<br />

come to see. Additionally many functions in <strong>Processing</strong> accept parameters, which<br />

modify how the function is interpreted the program.<br />

If we were to extend on our previous example and apply this programmatically,<br />

the word “Run” in the sentence would be a function and “as fast as you can!”<br />

would be representative of a parameter.<br />

Expressions<br />

Expressions in computer programming languages can consist of single or multiple<br />

different types of data such as numbers, typographic characters and many other<br />

types of data that can be interpreted in various ways according to rules established<br />

by the language you are programming in. The process of how this expressional<br />

data is interpreted is known as evaluation and is similar to the term as it is used in<br />

mathematics. For example 3 + 2 is an expression that evaluates to 5.<br />

Mathematical operators such as +, -, *, etc. work in <strong>Processing</strong>, as you would<br />

probably expect them to. As the term implies the programmatic mathematical<br />

operator is often interchangeable with the standard classical mathematical<br />

operator in <strong>Processing</strong>. For example the statement in <strong>Processing</strong>:<br />

An Analysis of a Computer Program 23


An Introduction To Programming With <strong>Processing</strong><br />

println(5+3);<br />

Consists of two parts, first the function println() which accepts a parameter. In<br />

this case the second part of the statement, the parameter, is an expression and the<br />

expression is 5+3 which evaluates to 8.<br />

One of the basic features of <strong>Processing</strong> is it's ability to act as a calculator when<br />

computing values separated by mathematical operators such as + (plus), - (minus),<br />

* (multiply), / (divide) and % (modulus). But this inherent ability of <strong>Processing</strong><br />

extends a lot further than simply evaluating numerical expressions, as expressions<br />

amongst other types of data can also consist of other typographic characters that<br />

can be evaluated. For example the statement:<br />

println(“h” + “i”);<br />

This statement evaluates to “hi”. Using a mathematical operator in this way is<br />

known as operator overloading and is an inherent quality of <strong>Processing</strong> that<br />

comes from it being a C based programming language. Operator overloading is a<br />

common feature in higher level languages and simply refers to the level of<br />

abstraction built into a higher or mid level programming language that allows us<br />

to use the same operator in more ways than one. For example the plus sign can be<br />

used to add numbers or other typographic characters, but not numbers and<br />

characters at the same time without the use of a process known as typecasting<br />

(which we will cover in more detail later).<br />

What makes operator overloading so useful is that we often don't need to be<br />

aware of it, because the way that the operator is used will be determined by the<br />

context in which the programmer has used it and this is something that the<br />

program converting our human readable code into a version that is more machine<br />

readable will handle for us.<br />

An example of operator overloading and typecasting in <strong>Processing</strong>'s PDE<br />

An Analysis of a Computer Program 24


An Introduction To Programming With <strong>Processing</strong><br />

A Scalable Software Development Model<br />

Programming is only one of the steps required in the process of developing<br />

software. Establishing a scalable model for software development will help you<br />

determine what the requirements of the project are before programming begins.<br />

As you start developing larger programs this development model can be scaled to<br />

help you allocate your time appropriately to the various needs of your project, and<br />

ultimately contribute to more realistic deliverables within a predictable timeframe.<br />

The idea behind a scalable software development model is that it can be<br />

adapted to suit any project large or small. Although certain areas might require<br />

more focus than others dependent on the project you are working on, having an<br />

established software development model can contribute to a progressive workflow<br />

that does not stagnate when difficulties within a project are encountered.<br />

1. Plan<br />

• What are the goals for the project?<br />

• How would you ideally like to implement these goals?<br />

• Have there been similar projects undertaken by yourself or others, if so is<br />

it possible to obtain those implementations?<br />

Asking yourself similar questions following this line of thought can help you<br />

visualize the steps, leading to your goals, that need to be taken well before<br />

programming begins.<br />

This process of visualization contributes to creating a conceptual sketch of the<br />

project as a whole and in it's completed form. This idea can then serve as a means<br />

of deconstructing the main concept into smaller workable objectives.<br />

Planning your project through conceptual visualization should be supplemented<br />

with a few rough ideas jotted down on a piece of paper. It's not uncommon to<br />

spend days and sometimes longer periods of time conceptualizing a project before<br />

considering trying to implement any of these ideas.<br />

Depending on the complexity of your project, you may have to further refine the<br />

process of breaking down the smaller tasks into even smaller tasks until you reach<br />

a task or set of tasks that are achievable in the short term. Often these short-term<br />

objectives will not necessarily relate directly to programming but rather to a set of<br />

A Scalable Software Development Model 25


An Introduction To Programming With <strong>Processing</strong><br />

questions that need to be answered before the implementation of the project can<br />

begin. These questions that you derive from planning your project will form the<br />

basis for the research that follows planning.<br />

Examples of an abstraction, followed by a deconstruction and finally a technical<br />

overview of a project plan.<br />

2. Research<br />

Addressing the details of how you see your project being implemented should<br />

bring certain technical questions to your attention. Questions such as,<br />

• What is the target system you would like your software to run on?<br />

• Will my software require additional resources such as plug-ins?<br />

• Can the software also be distributed for both online and offline usage?<br />

These are amongst many questions that you might not be able to answer in your<br />

own capacity. The Internet is a seemingly endless resource of information and<br />

probably your best bet when it comes to answering these and many other<br />

technical questions you can think of.<br />

Research might also reveal that the code you are interested in creating might<br />

already exist. If the code is distributed under a license that permits you to reuse it,<br />

then by all means you are encouraged to do so. It is often said that up to 80<br />

percent of a programmers time is spent maintaining already developed code.<br />

What this means is that generally developers will spend a comparatively small<br />

amount of their time developing their own code from scratch and far more time<br />

A Scalable Software Development Model 26


An Introduction To Programming With <strong>Processing</strong><br />

adapting and modifying already existing code to suit the needs of their projects.<br />

Finally researching your project can also reveal useful sources for data<br />

acquisition, which will be particularly helpful in the fourth phase of your<br />

development model.<br />

The various sites on the Internet have vast resources of reusable code<br />

3. Mockup Designs<br />

Once you have answered the questions you had about implementing your project<br />

consider returning to the notes you created during the first phase of Project<br />

Planning. With the new information you have derived through your research,<br />

refine your ideas into graphical representations of your program.<br />

By now you should have a clearer idea of what your end product should look like.<br />

Avoid prematurely designing your project only to realize your goals where not<br />

realistic given a particular time-frame or some other design flaw, following this<br />

development model in the predetermined order will help avoid such a situation.<br />

Use the mockup design phase of software development to start drawing out<br />

conceptual sketches of your program, in the form of schematic diagrams that<br />

outline the program's flow of control (which we will discuss in more detail in Step<br />

8) and map out the user experience you hope to achieve.<br />

If your software is visually oriented you may wish to create more detailed and<br />

specific designs of your application, for example by designing an interface for a<br />

data visualization program or designing a theme for an online game. Consider<br />

how your designs can contribute to making the user's experience more immersive.<br />

The design phase of software development can also help to identify and even<br />

A Scalable Software Development Model 27


An Introduction To Programming With <strong>Processing</strong><br />

solve how programmatic implementations of visualizing data might be addressed<br />

through various programming methodologies.<br />

Mockup Designs should include some rudimentary visualizations of the final project and<br />

schematic diagrams detailing the program's flow of control.<br />

4. Data Acquisition: Sourcing the data needed<br />

for your project.<br />

Obtain all the data you need to create your software, this data could include<br />

statistical information from books, tabulated data from a website, printed lists of<br />

sales from business owners or even screen-scraped data.<br />

Screen-scraping data is a technique that has been in use for many years and is<br />

used to acquire data from new and old computers alike. In modern times one of<br />

it's most common implementations involves the process of acquiring data that is<br />

in no particular standardized format and commonly sourced from from an html<br />

page of a website. The idea of screen-scraping is that data exists remotely from<br />

the program you are creating, in a format that your program cannot process. As a<br />

result you may need to write another program that serves as an in between<br />

application converting the remote data from an undesirable format to the desired<br />

format of the main software program you are developing.<br />

Screen-scraping is a technique of data acquisition that is differentiated from<br />

parsing, as the data that is being acquired is not intended for another software<br />

program but often intended to be read by a human. Parsing data is something that<br />

happens much later in the software development process and relies on proper data<br />

acquisition. Parsing data is something we will discuss in more detail during the<br />

A Scalable Software Development Model 28


An Introduction To Programming With <strong>Processing</strong><br />

seventh phase of the software development model.<br />

Acquired data might be in the form of a spreadsheet, a text document, images and many<br />

other different formats that might not, even at this stage, be digital.<br />

5. Filter<br />

Filtering data is simply the process of removing all components of your data that<br />

are not necessary for the proper functioning of the main program. If your data is<br />

in a <strong>Processing</strong> friendly format such as tabulated data, a multi-line text file, a<br />

comma separated value text file or other similar format the process of filtering<br />

data could be as simple as selecting those components (including spaces and new<br />

line characters in a text file) and deleting them. However, if your data is not in a<br />

<strong>Processing</strong> friendly format you might have to spend quite a bit of time filtering<br />

out data that is not relevant to your program.<br />

6. Clustering and Data Mining<br />

Data mining is the process of identifying patterns within the data you have<br />

acquired. The purpose of doing this is to place the relationships that exist between<br />

the various aspects of your data in a more mathematical context that can<br />

ultimately be used programmatically (in the program you are developing).<br />

Data mining can be done manually or it could be automated. When dealing with a<br />

A Scalable Software Development Model 29


An Introduction To Programming With <strong>Processing</strong><br />

small data set with a high ratio of inconsistent data types, manual data mining<br />

could be more effective and save you some time.<br />

For example, lets take a hypothetical situation where the owner of a small café<br />

has asked you to determine what items a customer is likely to purchase together.<br />

The data set you have acquired consists of all the items customers have purchased<br />

in the store over the past year. From that data you could determine that goods can<br />

be divided up into food, drinks, magazines, stationary etc, and then into even<br />

smaller groups like fruit, vegetables, soft-drinks etc. Identifying these groups<br />

would be the first step of data mining and is a process also known as clustering. If<br />

the café has a large variety of items to choose from the clusters making up the<br />

data could resultantly be numerous, yet the data set as a whole is actually quite<br />

small, only consisting of a single year of purchased items.<br />

In contrast a more established café that has been operating for several years<br />

proposes the same question to you. In the case of the smaller café groupings of<br />

purchased items would yield a lower probability of repeating in a shorter period<br />

of time. In contrast the more established café has a better chance of the same<br />

groups of items being purchased together over a longer period of time.<br />

In the former case manually mining this data set could be more effective because<br />

of the lower probability of the same items being purchased together in a relatively<br />

short space of time. In this scenario the majority of your time would be spent on<br />

clustering and populating the resultant groups after eliminating the majority of<br />

items purchased in that year because they will not fall into any cluster.<br />

However in the case of the established café although there may be just as many<br />

clusters the values that these clusters are populated with have a higher probability<br />

of being repeated, it might therefore be more efficient to have a computer<br />

program count, cluster and mine the data.<br />

Regardless of whether you choose to manually mine your data or have a software<br />

program do the work for you, you should have a set of data at the end of the<br />

process that can be manipulated programmatically.<br />

A Scalable Software Development Model 30


An Introduction To Programming With <strong>Processing</strong><br />

Raw Data<br />

Manual Clustering<br />

Digital Results<br />

The process of getting external data into a program, via clustering and data mining.<br />

A Scalable Software Development Model 31


An Introduction To Programming With <strong>Processing</strong><br />

7. Parsing<br />

The process of transferring data from one computer program to another program<br />

that requires the data in a specific format that is different to the original format, is<br />

referred to as parsing data. The program that converts the original data to an<br />

acceptable format for the main software program to process is referred to as a<br />

parser. Parsing in <strong>Processing</strong> should return a set of data that your main program<br />

can read directly in a text file, a spreadsheet or other such data format that does<br />

not require any further levels of un-abstraction.<br />

Sometimes, the decision to write a parser might not be an easy choice to make.<br />

Weigh up the amount of time you think it will take to manually convert the data<br />

(as illustrated in the above diagram) compared to the amount of time it will take<br />

you to develop a parser, along with it's overall usefulness (as a parser can<br />

sometimes end up being specific to one application) and try to make an informed<br />

decision based on these factors before jumping head first into the task at hand.<br />

8. Determining Flow of Control through<br />

Stepwise Refinement<br />

A program's flow of control refers to the order in which statements are run within<br />

in a program. The results of these statements can ultimately determine how a user<br />

interacts with the program by means of various branches of code structures within<br />

your program that the program determines whether to execute or not based on the<br />

choices the user has made through interactions with the program.<br />

Branching is an important part of a programs flow of control as it allows your<br />

program to determine, through a logical decision, what path to take within your<br />

program's code based on various circumstances you have defined for the user.<br />

Planning the program's flow of control allows us to address what we would<br />

ultimately want our users experience of the program to be, and the best place to<br />

start with this process would be to write out a list. This list should contain a set of<br />

instructions that determine how you would like the program to work and<br />

ultimately describe a user's experience of interacting with the program. Once you<br />

have this information remove unnecessary clutter from the list and identify the<br />

key points, keep it concise and short. Once you have this list keep refining it until<br />

you have something resembling a step by step process of the tasks the program<br />

will eventually perform.<br />

A Scalable Software Development Model 32


An Introduction To Programming With <strong>Processing</strong><br />

An example of such a list for a guess my number game follows:<br />

1. Start the game and generate a random number.<br />

2. Render the space scene interface including a slider,<br />

spaceship and a panel to show user's guesses which are<br />

either too high or too low.<br />

3. Click and drag the slider and a number is displayed<br />

indicating the users current guess.<br />

4. When the slider is released the user's guess is made<br />

5. If the guess is the same as the random generated number,<br />

show the “win screen”.<br />

6. If the guess is too high, tell the user the guess is too<br />

high and increment the number of user's guesses.<br />

7. If the guess is too low, tell the user the guess is too low<br />

and increment the number of user's guesses.<br />

8. If the user has not guessed the number within five tries,<br />

show the “lose screen”.<br />

Your list at this stage should start to read more like a program rather than a<br />

paragraph written in a natural language. This resemblance is no coincidence and<br />

forms the basis for the process programmers use for developing what is known as<br />

pseudo code. Pseudo Code is somewhere between a programming language and a<br />

natural language and forms the basis for stepwise refinement. During stepwise<br />

refinement rewrite your list so that it resembles something closer to the code of<br />

your program each time the pseudo code is refined.<br />

A Pseudo code example for a guess my number game might look something like<br />

this:<br />

choose a random number between 1 and 100<br />

set the number of user guesses to 1<br />

get the user's guess<br />

while the user's guess is not equal to the random number and less<br />

than 5 guesses<br />

if the guess is too high<br />

tell user “guess too high”<br />

increment user guesses<br />

else if the guess is too low<br />

tell the user “guess too low”<br />

increment user guesses<br />

if the number of guesses is 5 or greater user has lost<br />

else if the guess is equal to the random number<br />

user has won<br />

A Scalable Software Development Model 33


An Introduction To Programming With <strong>Processing</strong><br />

9. Implement, Test and Document. Repeat.<br />

Implementation is the phase of software development where the actual source<br />

code is created, by means of programming.<br />

As the code is created it should be constantly tested. This helps to identify bugs in<br />

the program during current implementation or that could occur in the future<br />

development of the software.<br />

While implementing and testing a program it is important to document the steps<br />

taken to achieve the goals of the project. This could either be done in a<br />

comprehensive form of external documentation but should always include<br />

documentation within the code itself in the form of comments and multi-line<br />

comments.<br />

This phase is repeatable and should be constantly updated by the recursive nature<br />

of it's design which should eventually lead to a erroneous free implementation of<br />

the software.<br />

Comments in <strong>Processing</strong> start with the // characters and multi-line comments in<br />

<strong>Processing</strong> start with the /* characters and end with the characters */<br />

A Scalable Software Development Model 34


An Introduction To Programming With <strong>Processing</strong><br />

10. Deliver<br />

Once the software has been thoroughly tested it should be delivered. Delivery<br />

could involve something as simple as uploading the software to a website, or as<br />

complex a task as marketing and selling the software. However you deliver your<br />

software, you should always accommodate for the delivery phase of the project<br />

uncovering unforeseen bugs and errors in the software as users test it on systems<br />

that differentiate substantially from that of the systems it was tested and<br />

developed on. As a result maintenance is a crucial part of delivery and an<br />

appropriate time-frame should always be allocated for it within software<br />

development. In some dire situations an entire redesign of the software might be<br />

deemed necessary during the delivery phase, in this case allocating a specific<br />

time-frame for software maintenance might not be adequate to accommodate the<br />

requirements of the development of the software.<br />

There are various options for publishing your software, once it is complete.<br />

A Scalable Software Development Model 35


An Introduction To Programming With <strong>Processing</strong><br />

Why Learn Programming using <strong>Processing</strong>?<br />

<strong>Processing</strong> covers a lot of ground as it is a great way to learn programming for the<br />

novice and for the experienced programmer provides a fast and efficient approach<br />

to developing advanced applications.<br />

Code for Artists<br />

<strong>Processing</strong> is built with the intent to be a tool for creating visual and interactive<br />

representations of code. This means that it is not as generic in it's application such<br />

as a programming language like C++ which can be used for engineering,<br />

mathematics, scientific applications and even games development but which also<br />

has it's limitations as it is generally not used to create online applications that<br />

might appear on a website. <strong>Processing</strong> is built for specific fields of interest and as<br />

a result less coding is needed in <strong>Processing</strong> than might be required in more<br />

generic programming languages when developing programs that are suited for the<br />

<strong>Processing</strong> environment, such as data visualization, interactive online<br />

applications, animation and many other similar fields. This is not to say that<br />

<strong>Processing</strong> is limited to one particular genre of application, but merely to say that<br />

<strong>Processing</strong> provides a set of tools that make the process of creating certain types<br />

of applications easier.<br />

<strong>Processing</strong> has developed since 2001 initially as an extension to a programming<br />

language, then to a prototyping tool and to it's current implementation of being a<br />

fully developed programming language that continues to develop in fields such as<br />

microprocessor programming and physical computing where it has gained much<br />

recognition.<br />

Java Based<br />

<strong>Processing</strong> was originally developed as an extension to the Programming<br />

language, Java and it's roots in Java are still evident today even though <strong>Processing</strong><br />

is a language on it's own. <strong>Processing</strong>'s relationship with Java has many benefits,<br />

the two languages share a similar syntax except that <strong>Processing</strong> can make visual<br />

representations of your code easier to create than Java can (which is more generic<br />

in it's scope of application). Java shares a lot of similarities with the programming<br />

Why Learn Programming using <strong>Processing</strong>? 36


An Introduction To Programming With <strong>Processing</strong><br />

language C (from which it was originally developed) and Java is also one of the<br />

most popular languages currently in use. If you are familiar with Java or C++<br />

(which is closely based on C) learning <strong>Processing</strong> should come quite naturally to<br />

you.<br />

The Java programming language is a popular language for software development<br />

and is almost entirely open source.<br />

C++ is a widely implemented language, as it is available on many popular platforms<br />

Open Source<br />

The <strong>Processing</strong> PDE (which is used to develop <strong>Processing</strong> code and is something<br />

we will discuss in more detail later) is Open Source Software and it is released<br />

under the GNU General Public License.<br />

You've probably heard the term “open source” before and are aware that it relates<br />

to something “free”, but are you aware that the term “free” as it is used in the<br />

context of open source does not necessarily have anything to do with money or<br />

the absence thereof?<br />

The term “free” within the context of open source refers more to a philosophy or<br />

methodology rather than a monetary reference and as such is akin to the term<br />

“freedom”. However as the idea of open source has expanded in modern day<br />

society it is often come to be synonymous with something that is also free of<br />

monetarily related costs. <strong>Processing</strong> is no exception to this, it does not require a<br />

costly software license such as proprietary software vendors require for the usage<br />

Why Learn Programming using <strong>Processing</strong>? 37


An Introduction To Programming With <strong>Processing</strong><br />

of their products. Anybody can use <strong>Processing</strong> and the PDE, modify it,<br />

redistribute it and the GNU General Public License ensures that the <strong>Processing</strong><br />

PDE will always remain free.<br />

So because <strong>Processing</strong> is free what about the content you create with <strong>Processing</strong><br />

does that also have to be “free” and open source?<br />

The answer to this question is and will remain to be, no. The content you create<br />

with <strong>Processing</strong> belongs to you, the creator, and you are free to do with it<br />

whatever you please. If you wish to sell the software or code that you produce<br />

with <strong>Processing</strong> it is your right to do so. If, however, you do not wish to sell your<br />

work and subsequently do not choose to copyright your work there are various<br />

options available to you to protect you and your work. Amongst these licences is<br />

the GNU General Public Licence which protects the rights of developers of<br />

computer programs that wish to ensure that the software they develop remains<br />

free, including all derivatives that are made from the original software program.<br />

Another such licence is the Creative Commons Licence, this licence allows<br />

creators of media to reserve some rights of their work (if they choose to) and still<br />

legally allows the copying, redistribution and modification of such media if the<br />

author chooses to exercise these rights. Wikipedia is an example of a large scale<br />

organization that licenses it's contents under a Creative Commons Licence and<br />

Linux is an example of popular software that is licensed under the GNU General<br />

Public Licence.<br />

The GNU GPL 3 logo as started by the Free Software Foundation on the left and a<br />

Creative Commons logo on the right both of these trademarks have become synonymous<br />

with the term “copyleft”.<br />

PDE<br />

An IDE is an acronym for Integrated Development Environment, it refers to a<br />

software application that is used to develop code for a computer programming<br />

Why Learn Programming using <strong>Processing</strong>? 38


An Introduction To Programming With <strong>Processing</strong><br />

language. <strong>Processing</strong> has it's own IDE called the PDE or <strong>Processing</strong> Development<br />

Environment.<br />

The PDE is a popular tool for developing <strong>Processing</strong> Sketches but the popular IDE<br />

Ellipse is also quite readily used too.<br />

Of course all code is simply text, so why can't we call any text editor an IDE? An<br />

IDE such as the PDE generally has several special characteristics that separate it<br />

from other software applications.<br />

1. Source Code Editor<br />

2. Build Automation Tools<br />

3. Compiler and/or Interpreter<br />

4. Debugger<br />

Why Learn Programming using <strong>Processing</strong>? 39


An Introduction To Programming With <strong>Processing</strong><br />

Source Code Editor<br />

A source code editor is a textual editor within an IDE. The Source Code editor in<br />

an IDE is designed specifically for programming purposes and not for wordprocessing,<br />

so generally text formatting capabilities such as bold, italicising<br />

characters or directly editing characters colors is not permitted within source code<br />

editors.<br />

The source code editor within the PDE allows you to type code, and access <strong>Processing</strong>'s<br />

API.<br />

Modern day source code editors use color codes to distinguish different types of<br />

data, this is referred to as syntax highlighting and it helps to make code more<br />

human-readable.<br />

Build Automation Tools<br />

Programming can involve many repetitive tasks, build automation tools help<br />

programmers perform these repetitive tasks by use of tools built into the IDE.<br />

They might include the IDE's ability to convert source code to machine readable<br />

code with the click of a single button (the button being the build automation tool)<br />

or the ability to export your source code to multiple platforms with a menu<br />

Why Learn Programming using <strong>Processing</strong>? 40


An Introduction To Programming With <strong>Processing</strong><br />

selection. In the PDE several build automation tools for creating <strong>Processing</strong><br />

applications can be found under the Tools and Sketch menus more generic build<br />

automation tools can also be found in the other menu's in the PDE.<br />

Some of <strong>Processing</strong>'s build automation tools. <strong>Processing</strong>'s build automation toolset can<br />

also be extended by downloading tools from processing.org/reference/tools/<br />

Compiler and /or Interpreter<br />

Most modern day IDE's have a compiler and/or interpreter, as this is the feature<br />

within IDE's that enable the conversion of source code to machine readable code.<br />

It is in this feature that our code is given a “meaning” for a computer to<br />

implement and for us to observe, interact with and experience in what ever it's<br />

intended form of implementation.<br />

You might be wondering at this point what exactly is the difference between a<br />

compiler and an interpreter?<br />

The truth is that there is actually not much of a difference between what a<br />

compiler does and what an interpreter does. The terms stem from a “Compiled<br />

Language” and an “Interpreted Language”. As mentioned before in order for a<br />

computer to make any sense of our code it needs to convert this code into a<br />

machine readable format, this process of conversion is referred to as compiling.<br />

The process is specific because the code must be fed into a compiler in a specific<br />

language and then be compiled into another “language” which is no longer<br />

human-readable but machine readable and specific to a particular platform. A<br />

compiler is said to perform this task on the entirety of the source code once so<br />

that when the program is compiled there is no more conversion or compilation<br />

that needs to be performed there after.<br />

An interpreter differs in the sense that the source code is not compiled into a<br />

specific machine readable format. So how does the code run on a machine? The<br />

code is passed to an interpreter (which is another software application) that runs<br />

the code. The interpreter then determines how the code should be run<br />

continuously translating the code from a higher level to a machine readable level<br />

Why Learn Programming using <strong>Processing</strong>? 41


An Introduction To Programming With <strong>Processing</strong><br />

each time the code needs to be executed.<br />

Of course at some point in order for the code to be run on a computer it has to<br />

exist in a machine readable format regardless of whether it's compiled or<br />

interpreted, so theoretically the difference between the two methods is not<br />

inherently specific to the language you are creating the code with but rather more<br />

to do with how a language is implemented. What this means is that any language<br />

could be interpreted or compiled, it's how the code that you create is implemented<br />

that determines whether that code will be compiled or interpreted.<br />

<strong>Processing</strong> compiles to Java bytecode, and can subsequently run on any Java<br />

enabled machine it is estimated that there are currently over 4.5 billion Javaenabled<br />

machines. Java is said to be an interpreted language.<br />

<strong>Processing</strong> compiles your Sketches to Java Bytecode and uses the Display Window<br />

(foreground) for testing and development.<br />

Debugger<br />

A debugger in the context of an IDE is software that examines code either as a<br />

part of the compilation process or before compilation or interpretation in order to<br />

reduce the number of bugs within a program. The term bug in relation to<br />

computer programming is used to describe an error, fault or some means of a<br />

computer program acting in an unexpected or unintended way. The process of<br />

Why Learn Programming using <strong>Processing</strong>? 42


An Introduction To Programming With <strong>Processing</strong><br />

debugging a program is intended to identify these bugs and in some cases assist<br />

the programmer in rectifying them. In the PDE the debugger console can be found<br />

below the text editor and is used generally for debugging one's own program or<br />

allowing the PDE to determine bugs within a program.<br />

The Debugger console (also known as Message and Text area) can be used to identify<br />

bugs and track program variables which can be useful in identifying logical errors.<br />

Active Online Community<br />

<strong>Processing</strong> is not a stagnant language it is very much alive and growing. The<br />

Language's development is rapid but not so rapid that it becomes difficult to keep<br />

up with. A lot of this development can be attributed to the active community that<br />

support the project.<br />

If you are in need of any help with programming in processing, want to keep up to<br />

date with it's development or just simply want to play around with programs made<br />

with <strong>Processing</strong> online then I recommend you visit http://www.processing.org<br />

The forums are really easy to use and you are encouraged to ask questions, as<br />

there seems to be many people out there that are keen on helping you develop<br />

your software.<br />

The latest version of <strong>Processing</strong> can be downloaded at http://processing.org/<br />

download<br />

The <strong>Processing</strong> logo is a trademark of processing.org<br />

Why Learn Programming using <strong>Processing</strong>? 43


An Introduction To Programming With <strong>Processing</strong><br />

<strong>Hello</strong> <strong>Processing</strong><br />

Now that we have an idea of what programming is and how we will be using the<br />

PDE to create our own code in <strong>Processing</strong> lets start coding!<br />

Install <strong>Processing</strong><br />

Once you have downloaded <strong>Processing</strong>, depending on your platform you might<br />

need to install it or just simply uncompress/unzip the package to a location on<br />

your hard disk drive and run it from there. Open the processing root folder inside<br />

which you will find an executable file called processing, double click this file to<br />

start the PDE and you are ready to start programming with <strong>Processing</strong>.<br />

If however you are unable to run the PDE check that you have permission to<br />

execute/run the processing file and that Java or more specifically the JRE (Java<br />

Runtime Environment) is properly installed.<br />

It is recommended that you use the Java version that is available from Sun<br />

Microsystems (a subsidiary of Oracle), alternative open source versions of the<br />

JRE and Java Development Kit (JDK) such as OpenJDK do exist but are currently<br />

not recommended with <strong>Processing</strong>, however this might change at some point in<br />

the future, see the <strong>Processing</strong> website for updates.<br />

You can get the latest version of Java from http://www.java.com/getjava<br />

Sketches<br />

A program created in <strong>Processing</strong> is known as a Sketch. <strong>Processing</strong> Sketches are<br />

stored in a folder called the sketchbook folder. Being able to identify the location<br />

of this folder will be useful particularly when adding external data to a sketch. To<br />

identify the location of the sketchbook folder within the PDE click:<br />

File → Preferences → “Sketchbook location”<br />

In the Preferences dialogue box the sketchbook folder can be identified under the<br />

heading “Sketchbook location” or changed by clicking the “Browse” button and<br />

navigating to and choosing a new location under the same heading.<br />

All Sketches you create should be stored within your sketchbook folder.<br />

<strong>Hello</strong> <strong>Processing</strong> 44


An Introduction To Programming With <strong>Processing</strong><br />

<strong>Hello</strong> World Program 1.0<br />

Programming can be simple or very complex depending on what you are hoping<br />

to achieve. Since this is our introduction to programming we'll be following<br />

programming tradition and starting with a simple <strong>Hello</strong> World program. A <strong>Hello</strong><br />

World program is a program that simply prints the words “hello world” to a<br />

display, that display in our case in the “<strong>Hello</strong> World 1.0” program is going to be<br />

the debugging console in the PDE. The purpose of the <strong>Hello</strong> World program is<br />

not as much to impress but rather to get a firm grasp on the key points that make a<br />

successful program and then to later expand on this understanding.<br />

If you have not already done so open the PDE and start a new sketch. You can do<br />

this by clicking<br />

File → New<br />

Save the sketch in your sketchbook folder<br />

File → Save As...<br />

Give the sketch a unique name that you will remember.<br />

In the text editor of the PDE create the <strong>Hello</strong> World 1.0 program by typing<br />

println("<strong>Hello</strong> World");<br />

Press the “Run” button in the PDE which looks like a play button, or ctrl-r on<br />

your keyboard. The PDE checks, compiles and executes your your program. If all<br />

has gone well you should get a result similar the following image.<br />

<strong>Hello</strong> World Program 1.0 45


An Introduction To Programming With <strong>Processing</strong><br />

The typical “<strong>Hello</strong> World” program is many a programmers first attempt at coding.<br />

If your console window has the phrase “<strong>Hello</strong> World” printed in it,<br />

congratulations you've successfully completed the <strong>Hello</strong> World 1.0 program!<br />

Like I said earlier, don't expect to be impressed right away, building a more useful<br />

program is going to take a little more practice. Nonetheless let's have a look at<br />

what is going on here.<br />

Firstly you'll notice that the text editor has formatted the text we input in different<br />

colors.<br />

The colors denote specific meanings in <strong>Processing</strong>, for example in our <strong>Hello</strong><br />

World 1.0 program:<br />

Orange<br />

Orange is used to identify a command.<br />

Black<br />

Black identifies syntax formatting characters such as parenthesis and a statement<br />

terminator.<br />

Blue<br />

Blue identifies a string of data.<br />

<strong>Hello</strong> World Program 1.0 46


An Introduction To Programming With <strong>Processing</strong><br />

IDE's such as the PDE that use syntax highlighting make reading code easier to<br />

decipher and once you get familiar with what the colors represent you'll find<br />

yourself separating the code you are reading into smaller manageable chunks by<br />

identifying the colors that serve specific functions.<br />

We refer to the sentence typed in the text editor as a statement. Statements are<br />

easy to identify because they always end with a semi-colon and not with a period<br />

(like in English). Our entire <strong>Hello</strong> World 1.0 program consists of only one<br />

statement which in itself consists of only one command.<br />

<strong>Processing</strong> is a case sensitive language so it is very important that when you type<br />

a command you do not mix it's casing because println() and printLn() will not<br />

yield the same results, in fact the latter will cause an error.<br />

The println() function<br />

println() is a special type of command called a function.<br />

Sometimes a function is also referred to as a subroutine so how the term is used<br />

from one language to another may vary but regardless of what you call it the<br />

purpose of a function is generally the same in any programming language, a<br />

portion of code (usually a single word followed immediately with parenthesis)<br />

that exists within a larger body of code (in our case this could be the sketch we<br />

are creating) and performs a specific task within the context of the program but is<br />

also independent of the program.<br />

As you are aware, we have not defined the function println() we are just simply<br />

using it as it has been defined by the people that developed <strong>Processing</strong>, in other<br />

words we have not told the computer what to do when it comes across println() in<br />

our <strong>Hello</strong> World 1.0 program. This means that the main body defining how<br />

println() acts in our program is not defined within our program but exists<br />

independently of our program, probably somewhere else on your hard disk drive<br />

where you installed <strong>Processing</strong>. If we were to take another look at the <strong>Hello</strong><br />

World 1.0 program, we can see the function println() is telling the machine, that<br />

the sketch is running on, to print whatever is inside the parenthesis. We call data<br />

we input to a function through parenthesis, parameters and some other higher<br />

level languages might refer to parameters as arguments. The parameters our<br />

println() function accepts in this case is the string of characters that spell out the<br />

words “<strong>Hello</strong> World”.<br />

<strong>Hello</strong> World Program 1.0 47


An Introduction To Programming With <strong>Processing</strong><br />

There are two points worth noting here, firstly we have input data into the<br />

println() function and secondly it has returned data back to us, that being what it<br />

has printed to the debugger console. When a function is used in this way we are<br />

said to be calling a function. Functions are the building blocks of <strong>Processing</strong> and<br />

we will be using them regularly and even creating our own.<br />

The process of calling a function visualized.<br />

Syntax and syntax errors<br />

The arrangement of components within a statement is exceptionally important in<br />

programming. Unlike in natural languages, where sentences can be structured in<br />

several different configurations and still have the same meaning. In programming<br />

a specific syntax exists for all languages and must be adhered to or your compiler/<br />

interpreter might throw an exception or a syntax error. Syntax errors are generally<br />

quite common when you first start programming, it is easy to forget to place a<br />

semi-colon at the end of a statement or close parenthesis that have been left<br />

hanging open. Errors like these are often easy to debug, particularly when using<br />

the PDE. For example if we were to make a mistake in our <strong>Hello</strong> World 1.0<br />

program and forget to close the open parenthesis, when trying to run the sketch<br />

we could get an error looking something like this...<br />

<strong>Hello</strong> World Program 1.0 48


An Introduction To Programming With <strong>Processing</strong><br />

Syntax errors are common when one first starts programming, but with the help of the<br />

debugging console they can be relatively easy to identify.<br />

As you can see debugging the program in this case is really quite simple, in fact<br />

the PDE tells us exactly where the error is. In larger programs however it might<br />

not be so obvious where the problem lies, although the PDE will try to help you in<br />

tracking down a bug where ever it can.<br />

Some pointers to remember when constructing statements in <strong>Processing</strong><br />

• Always end statements with a semi-colon<br />

• All parenthesis (), brackets [] and braces {} that are opened with their<br />

corresponding left characters must be closed with the right version of the<br />

same character. None of these sets are interchangeable, but some of these<br />

sets are nestable.<br />

• A String of literal characters (such as “hello world”) must exist between<br />

double quotes. Single quotes are reserved for the char data type (discussed<br />

later).<br />

• If you have any uncertainties about your program, such as how to use a<br />

function or it's syntax, look it up in the <strong>Processing</strong> reference which can be<br />

accessed online at http://processing.org/reference/ or from the PDE ,for<br />

offline viewing, click :<br />

Help → Reference<br />

Of course there are many other points worth noting on syntax and program<br />

structure but we will get to these in due time, for now there's no need to get ahead<br />

of ourselves.<br />

<strong>Hello</strong> World Program 1.0 49


An Introduction To Programming With <strong>Processing</strong><br />

Logical Errors<br />

Logical errors are errors that do not cause the program to halt, crash or throw an<br />

error but will cause the program to act in an unexpected manner or produce<br />

unintended results. Logical errors can therefore be difficult to track down and<br />

rectify because the PDE does not indicate the specific location of an error.<br />

Keeping track of your data through documentation and organizing it into small<br />

manageable chunks can be one method of avoiding logical errors. If your program<br />

seems to have a logical error you might have to use the println() function to track<br />

the values you were hoping to have your program return to you.<br />

Display Window<br />

In our <strong>Hello</strong> World 1.0 program after pressing the Run button you will notice that<br />

a new smaller window was created. This is the Display Window and because<br />

<strong>Processing</strong> is a visually oriented language it automatically creates this window<br />

which you will usually use to draw to.<br />

The default Display window has dimensions 100 pixels in width by 100 pixels in height.<br />

<strong>Hello</strong> World Program 1.0 50


An Introduction To Programming With <strong>Processing</strong><br />

Lets take a look at how we can control the Display window with the size()<br />

function.<br />

The size() function allows you to specify the dimensions of the Display window<br />

in pixels. You use the size() function by supplying two parameters to it, an x<br />

value which defines the horizontal dimension of the Display window and a y<br />

value which defines the vertical dimension of the Display window. Just like the<br />

println() function, parameters for the size() function are entered between the<br />

function's parenthesis. For example if we wanted the dimension of the Display<br />

window to be 640 pixels across by 480 pixels down we would type:<br />

size(640,480);<br />

Note that because we have just entered a statement telling <strong>Processing</strong> how big we<br />

want the Display window to be we must terminate this statement with a semicolon.<br />

You will also note that the two values 640 and 480 are separated with a comma.<br />

Do not try to separate values with a semi-colon because the statement is<br />

incomplete at that point and you are therefore attempting to terminate it<br />

prematurely. This will most commonly result in a syntax error or even worse in a<br />

logical error in some cases.<br />

Parenthesis following a function's name is usually reserved for parameters<br />

relating to the function and these parameters are most commonly separated by<br />

commas. This is pretty easy to remember because in English you generally list<br />

items by separating them with a comma in <strong>Processing</strong> and many other higher<br />

level languages you separate parameter values for a function with a comma.<br />

The two values 640 and 480 have been “listed” in this particular order because<br />

when <strong>Processing</strong> accepts parameters of dimensional type like x and y (in 2<br />

dimensions) or x, y and z (in 3 dimensions) it will generally accept values in the<br />

order x first, y second and z third. This is with the exception of a trigonometric<br />

function called atan2() in which y is read first followed by x due to the special<br />

circumstances of how this function works.<br />

Add the second statement to your <strong>Hello</strong> World 1.0 program<br />

Below the first statement type the second statement so that your code reads:<br />

println("<strong>Hello</strong> World");<br />

size(640,480);<br />

<strong>Hello</strong> World Program 1.0 51


An Introduction To Programming With <strong>Processing</strong><br />

Standardized Coding Practices<br />

Comments and white space form a part of standardized coding practices.<br />

Standardized coding practices establish a consistency between different software<br />

languages. If you do not use them your software may or may not throw an<br />

exception or an error, but you can be certain that there are many people that might<br />

read your code who will find it non-user-friendly when you do not use<br />

standardized coding practices and try to invent your own.<br />

Comments<br />

Comments are lines of information inserted between code that informs a person<br />

reading the code of it's purpose and intent. Comments are completely ignored by<br />

the software executing the code such as the PDE and they should be written in<br />

plain and simple English or, what ever your chosen language. Consider that the<br />

comments you write might not always be for your personal understanding but for<br />

another person reading your code and therefore should reflect a clear and<br />

impartial explanation of your code.<br />

Commenting your code becomes particularly useful for code that you have not<br />

revisited over a long period of time. Regardless of whether you wrote the code or<br />

not, trying to understand what revisited code is supposed to do after long periods<br />

of time becomes a cumbersome process when it is not commented properly.<br />

Comments in <strong>Processing</strong> and many other higher level languages are indicated<br />

with two forward slashes:<br />

// for a single line comment, that is a comment that is<br />

// only one line long,<br />

// but can also have one comment following another.<br />

Comments that are more than one line long are called multi-line comments in<br />

some programming languages and documentation comments in <strong>Processing</strong>. They<br />

are indicated by starting the comment with:<br />

/** typing the multi-line comment<br />

...<br />

...<br />

and ending it with */<br />

<strong>Hello</strong> World Program 1.0 52


An Introduction To Programming With <strong>Processing</strong><br />

White space<br />

White space is also sometimes referred to as negative space and is the space<br />

between the characters of text that make up the lines of your source code text file.<br />

For example a space, tab or enter/break are all referred to as white space.<br />

<strong>Processing</strong> unlike other programming languages (such as Python) completely<br />

ignores white space, just like it ignores comments. However just because<br />

<strong>Processing</strong> ignores white space doesn't mean you should. Using a consistent<br />

spacing and formatting of your code will make it easier to read. For example:<br />

println("<strong>Hello</strong> World");size(640,480);<br />

is valid code but less readable than the same program with white space:<br />

println("<strong>Hello</strong> World");<br />

size(640,480);<br />

You can probably imagine how unreadable code could quickly become when<br />

creating more complex programs with hundreds of statements.<br />

Let's revisit our <strong>Hello</strong> World 1.0 program and retype it taking standardized coding<br />

practices into consideration.<br />

/**<br />

* <strong>Hello</strong> World 1.0 Program<br />

* by Lyndon Daniels.<br />

* 11/01/2011<br />

* This example program demonstrates how to<br />

* create a <strong>Hello</strong> World Program in <strong>Processing</strong>.<br />

*/<br />

//Determine the size of the Display window<br />

size(640,480);<br />

//Print characters to the console<br />

println("<strong>Hello</strong> World");<br />

<strong>Hello</strong> World Program 1.0 53


An Introduction To Programming With <strong>Processing</strong><br />

Program Notes<br />

Firstly you'll notice that every line in the documentation comment except the first<br />

and last lines of this comment is started with an asterisk “*”. This is not necessary<br />

but, it does make the code look somewhat nicer and many programmers adopt this<br />

fashion of multi-line commenting so I've included it in this program. As<br />

mentioned earlier to <strong>Processing</strong> it makes absolutely no difference, but to us it<br />

makes the code easier to read.<br />

It is standardized coding practice to include the following information in the<br />

documentation comment.<br />

• Name of the program,<br />

• The programmers name,<br />

• The date on which the program was released,<br />

• A brief description of what the program does.<br />

Secondly you'll also note that I've changed the order in which the statements are<br />

executed (or run). Code written in this way resembles a procedural programming<br />

style meaning that the code is executed one line after the next starting at the top of<br />

the document and working down. Subsequently it makes more sense to define the<br />

size of the Display window before any other code is run. At a later stage you will<br />

see that when using the setup() function starting with the size() function, before<br />

any other functions following setup(), is mandatory.<br />

Cartesian Graph and the <strong>Processing</strong><br />

Coordinate System<br />

As mentioned earlier the Display Window's dimensions are determined within the<br />

size() function via the parameters that it accepts. Those dimensions are measured<br />

in pixels. When we start drawing to the Display Window we need to tell<br />

<strong>Processing</strong> where exactly we are attempting to draw to within the Display<br />

Window, this information we supply to <strong>Processing</strong> in the form of x and y<br />

coordinates when dealing with a 2D sketch and x, y and z coordinates when<br />

dealing with a 3D sketch. As a result you can think of the Display window as<br />

being a piece of graph paper with invisible lines.<br />

Cartesian Graph and the <strong>Processing</strong> Coordinate System 54


An Introduction To Programming With <strong>Processing</strong><br />

The Display Window can be divided up into a grid.<br />

The origin of the Display window is in the top left hand corner, being the origin<br />

it's coordinates will be (0,0) meaning 0 x and 0 y respectively. This type of layout<br />

might look familiar to you, that's because it's based on the Cartesian graph<br />

system. This is the name for the type of graph layout we use in <strong>Processing</strong> and<br />

many other programming languages that allow us to create and place components<br />

of a sketch within an area such as the Display Window. The main difference<br />

between the programmatic version of the Cartesian graph and the mathematical<br />

version of the Cartesian graph is that in the programmatic version the positive y<br />

axis runs downwards not upwards as is usually the case in the mathematical<br />

representation of this graph. This actually does not change anything about how<br />

the graph system is used, if you find this to be a bit odd you can think of it as if<br />

we were looking at a piece of graph paper rotated 180 degrees around the x axis<br />

so we're looking at the back of the graph paper and everything drawn on the paper<br />

now appears upside down. As you can imagine nothing drawn on the graph paper<br />

has changed just the way we are looking at it is different. Understanding how the<br />

Cartesian graph system is applied in programming is a lot easier when we have an<br />

example to work with, so lets add to our <strong>Hello</strong> World 1.0 program.<br />

Cartesian Graph and the <strong>Processing</strong> Coordinate System 55


An Introduction To Programming With <strong>Processing</strong><br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1<br />

In the revised version of our <strong>Hello</strong> World Program we will start using the Display<br />

Window, firstly to display the original character set “<strong>Hello</strong> World” then to display<br />

a few shapes too.<br />

text()<br />

The text() function is the first function we will use to make <strong>Processing</strong> draw<br />

something to the Display Window for us. The text() function accepts parameters<br />

in various formats of which the simplest format is:<br />

text(data, x, y);<br />

The data parameter in this case will be the string of characters that spell the<br />

phrase “<strong>Hello</strong> World” and as you've probably already guessed the x and y<br />

parameters tells <strong>Processing</strong> where in the Display Window we would like to draw<br />

the text in terms of x and y coordinates.<br />

So let's give it a try, add the following line to the bottom your <strong>Hello</strong> World 1.0<br />

sketch:<br />

text(“<strong>Hello</strong> World”, width/2, height/2);<br />

Using the Display Window gives you immediate feedback for testing your code.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 56


An Introduction To Programming With <strong>Processing</strong><br />

Program Notes<br />

You'll notice that your sketch is now making use of the Display Window, which<br />

is the first step towards creating visual representations of your code. We used the<br />

string of text “<strong>Hello</strong> World” in the data parameter, but the x and y parameters are<br />

looking a little different particularly if you were expecting them to be numbers. In<br />

fact they are numbers, instead of inputting a specific number for the x and y<br />

parameters we used an expression and in this case the expression evaluates to a<br />

number. It is this number that <strong>Processing</strong> reads and accepts as the parameter. But<br />

what exactly do the expressions mean?<br />

Amongst the many things that <strong>Processing</strong> is, it is also a very sophisticated<br />

calculator. It has the ability to calculate very complex mathematical formulae and<br />

also is able to do very simple math too. The expression:<br />

width/2<br />

is asking <strong>Processing</strong> to get the width of the Display Window and divide (/) it by 2.<br />

The keyword width is a type of data known as a system variable. Basically the<br />

width system variable stores information set by the first parameter in the size()<br />

function, and as you are aware the first parameter in the size() function<br />

determines the width of the Display window. In our program we set the size()<br />

function to read:<br />

size(640,480);<br />

How this relates to the width system variable is that every time <strong>Processing</strong> sees<br />

the keyword width it replaces it with whatever we set the width value to be in the<br />

size() function. In this case since we set the width to 640 the text statement as<br />

<strong>Processing</strong> reads it looks something like this:<br />

text(“<strong>Hello</strong> World”, 640/2, 480/2);<br />

The height system variable has the same effect but relates to the second parameter<br />

of the size() function.<br />

So the question is why did we not just simply type the values 640 and 480 instead<br />

of using the keywords width and height respectively? Even further still why didn't<br />

we just type the values 320 for the x parameter and 240 for the y parameter of the<br />

text() function, so that it looks like this:<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 57


An Introduction To Programming With <strong>Processing</strong><br />

text(“<strong>Hello</strong> World”, 320, 240);<br />

Although this is a perfectly valid methodology, it is not very versatile. Currently<br />

there is not too much maintenance involved in updating the code if we were to<br />

decide that the Display Window needs to be smaller, however when it comes to<br />

creating the rest of the sketch which is going to involve drawing shapes to the<br />

Display Window of which each shape will need to have it's own set of<br />

coordinates, if we had typed in a specific value for each x and y position, updating<br />

the code to reflect the change of dimensions of our Display Window would mean<br />

changing each statement where we input specific x and y values. That could mean<br />

a lot of extra and unnecessary work. By using an expression with the keywords<br />

width and height we can place whatever we are drawing relative to a position<br />

determined by the size() function. So all we need to do now is update the size()<br />

function and every place that we have used the keywords (width and height)<br />

relating to the size() function updates without us having to change anything more<br />

than a single statement. This is a programming methodology that is used often<br />

and referred to as implicit programming, and although it might not seem entirely<br />

obvious to you at this point why it is a recommended methodology it should<br />

become more clear as you delve deeper into the <strong>Hello</strong> World 1.2 program.<br />

Formatting Text<br />

You might have noticed that the text is supposed to be in the center of the Display<br />

Window but looks more like it's leaning to the right hand side of the window.<br />

<strong>Processing</strong> allows us to align text relative to the coordinates we specified for the<br />

text() function's x and y parameters. The relative positions are LEFT, RIGHT or<br />

CENTER. I have typed them in upper case because that is the format that<br />

<strong>Processing</strong> accepts them as, when entered as a parameter for the textAlign()<br />

function.<br />

Lets fix the text alignment so that it is in the center of the Display Window, add<br />

the following line of code directly above the text statement:<br />

textAlign(CENTER);<br />

If you were to re-run the sketch your updated version should have the text directly<br />

in the center of the Display Window. As we are using a procedural programming<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 58


An Introduction To Programming With <strong>Processing</strong><br />

style to create this sketch, <strong>Processing</strong> needs statements input in a particular order.<br />

We'll discuss procedural programming and other programming paradigms in more<br />

detail a bit later, but for now it's very important to note the order that statements<br />

are placed in. Placing the textAlign() function before the text() function ensures<br />

that the textAlign() function is run before the text() function thereby ensuring that<br />

by the time <strong>Processing</strong> gets to drawing the text in the Display Window it already<br />

knows that the coordinates within the text() function refer to the CENTER of the<br />

text.<br />

Next we'll have a look at the size of the text. Currently the sketch looks like it's<br />

drowning the text in a sea of greyness, so lets make the text a little bigger. The<br />

textSize() function allows us to set the size of text in pixels. The size number is<br />

input as a parameter of the textSize() function. Add the following statement<br />

before the text statement:<br />

textSize(24);<br />

Now we're starting to get somewhere, although white text on a grey background<br />

does not exactly jump out at you. So in keeping with the old <strong>Processing</strong>.org color<br />

scheme we're going to use a black background with light blue text.<br />

Color<br />

Color in <strong>Processing</strong> can be input in several different formats such as RGB (Red,<br />

Green, Blue), HSB (Hue, Saturation, Brightness) or Hexadecimal code. RGB is<br />

the default color mode but this can be changed with the colorMode() function.<br />

Lets have a look at how to change the background color. Add the following<br />

statement to your sketch directly after the size() function:<br />

background(0,0,0);<br />

The background() function accepts up to three parameters, in our case the first<br />

parameter is the Red value followed by the Green value and finally by the Blue<br />

value. As we want a black background all of these values are set to 0 the<br />

minimum value for the current color mode of RGB, the maximum value for these<br />

parameters is 255, this gives you a total of 256 different color values for each<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 59


An Introduction To Programming With <strong>Processing</strong><br />

color (remember 0 is also a value). If we wanted a white background we would<br />

have to enter 255 for each of the three parameters of the background() function.<br />

Back to the color of the text. The textAlign() and textSize() functions set<br />

parameters not just for the text currently displayed but for all text that is created<br />

thereafter. Until these functions are used again to change these parameters they<br />

will remain in <strong>Processing</strong>'s memory and effect all text that is drawn to the Display<br />

Window following their execution.<br />

The fill() function acts in a similar fashion, it accepts color values and will effect<br />

everything that is drawn to the Display window that has a fill after the function is<br />

evoked. We will have a look at how to modify this behaviour a bit later, for now<br />

lets focus on getting the text to display in a light blue.<br />

In the PDE click:<br />

Tools → Color Selector<br />

The Color Selector is a build automation tool accessible within the PDE<br />

The Color Selector dialogue box is useful for finding the specific HSB, RGB or<br />

Hexidecimal color values of a color. In our case the RGB values for the light blue<br />

I'm looking for are R 191, G 233 and B 255. I can now use these values in my<br />

sketch.<br />

Before the text() function type the following statement:<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 60


An Introduction To Programming With <strong>Processing</strong><br />

fill(191, 233, 255);<br />

This statement sets the color of the text to light blue color.<br />

Before we continue drawing shapes, lets make a few adjustments to the horizontal<br />

position of the text so that we can have some space to draw a smiley face in the<br />

center of the Display Window. Once again we're not going to input a specific<br />

number into the y parameter of the text() function, we're instead going to use an<br />

expression so that we can have <strong>Processing</strong> do the work for us just in case we feel<br />

like changing the dimensions of the sketch once it's complete.<br />

Basically we want to keep the text as is but just place it closer towards the bottom<br />

of the sketch about three quarters of the way down. Since we know that the height<br />

system variable contains the y dimension of our sketch and that dividing it by 2<br />

will return a value that is half the size of the y dimension of our sketch. Dividing<br />

the height value by 4 will give us a value that is a quarter of the height of our<br />

sketch. If we then multiply this value by 3 we will have a value that is three<br />

quarters the length of the y dimension of our sketch. So our expression would<br />

look like this:<br />

(height/4)*3<br />

What this reads as is “height divided by four then multiplied by three”. Just like in<br />

mathematics anything within parenthesis is evaluated before that which is outside<br />

of parenthesis. So the expression height/4 is first evaluated, the answer of this<br />

expression is then multiplied by 3.<br />

Modify your text statement to look like this:<br />

text("<strong>Hello</strong> World", width/2, (height/4)*3);<br />

Now we can ensure that whatever the y dimension of our Sketch may be,<br />

<strong>Processing</strong> will always place our text three quarters of the length down the y axis<br />

of the Display Window.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 61


An Introduction To Programming With <strong>Processing</strong><br />

Drawing<br />

The new <strong>Hello</strong> World Program in <strong>Processing</strong>.<br />

<strong>Processing</strong> is a language that was made to create visual representations of your<br />

code really easily, and as a result the developers of <strong>Processing</strong> have provided us<br />

with pre-configured functions for drawing primitive shapes much like you would<br />

expect in a drawing program. Shapes such as rectangles, ellipses and triangles<br />

amongst others are known as 2D primitives and can easily be drawn to the<br />

Display Window with a simple keyword. We'll start by drawing an ellipse.<br />

2D Primitives<br />

Drawing an ellipse in <strong>Processing</strong> is easy you just use the ellipse() function that<br />

accepts parameters in the following order:<br />

ellipse(x, y, width, height);<br />

As you might have already guessed the x and y parameters indicate where the<br />

ellipse is to be drawn on the coordinate system, and the width and height<br />

parameters indicate the width and height of the ellipse. Please note that the terms<br />

width and height in this context have nothing to do with the system variables<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 62


An Introduction To Programming With <strong>Processing</strong><br />

width and height which store the information relating to the x and y dimensions of<br />

the Display Window. To draw an ellipse in the Display Window add the<br />

following statement to the end of your program:<br />

ellipse(width/2, height/2, 100, 100);<br />

Once again to find the center of the Display Window I have used the expressions<br />

width/2 and height/2 this gives me the x and y coordinates respectively that will<br />

be the center of the ellipse. Technically a circle is an ellipse with an equal width<br />

and height, which is why I have input 100 for both the width and height<br />

parameters of the ellipse() function. I've also chosen to enter explicit values for<br />

the ellipse's width and height parameters, as I don't want the dimensions of the<br />

ellipse to change even if I do decide to change the dimensions of the Sketch itself.<br />

Using this hybrid style of mixing implicit programming and explicit programming<br />

can sometimes lead to logical errors, so you should always be certain of what you<br />

are doing when using this approach to programming.<br />

The Origin of an ellipse<br />

<strong>Processing</strong> provides several different ways to draw an ellipse which modify what<br />

the x and y parameters of the ellipse() function refer to. These parameters of<br />

ellipse() define what is known as the origin of the ellipse, the function<br />

ellipseMode() is used to change where the origin of the ellipse is with regards to<br />

the x and y parameters of the ellipse() function. This relationship will determine<br />

where the ellipse is drawn within the Sketch.<br />

We use the function ellipseMode() which accepts the parameters CENTER,<br />

RADIUS, CORNER, or CORNERS to determine how the circle is to be created.<br />

Using the CENTER parameter tells <strong>Processing</strong> to use the x and y parameters of<br />

the ellipse() function to determine the center of the ellipse as it's origin. The<br />

CENTER parameter for ellipseMode() is the default mode, and is subsequently<br />

why we did not add the statement to our sketch. If you did want to use the<br />

CENTER creation mode for drawing ellipses after having overridden this setting<br />

with one of the other modes, to reactivate the CENTER mode parameter you<br />

would add the following statement to your sketch before using the ellipse()<br />

function:<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 63


An Introduction To Programming With <strong>Processing</strong><br />

ellipseMode(CENTER);<br />

Remember <strong>Processing</strong> is case sensitive so don't forget to type this parameter in<br />

upper-case.<br />

Drawing an ellipse with the CENTER parameter of ellipseMode()<br />

The CORNER parameter for ellipseMode() function allows you to create an<br />

ellipse by specifying the x and y coordinates as the corner of an imaginary<br />

bounding box that surrounds the ellipse. The x and y parameters are used to<br />

determine the top left-hand corner of the bounding box from where the width and<br />

height parameters are used to extend to the maximum width and height values of<br />

the ellipse.<br />

Drawing and ellipse with the CORNER parameter of ellipseMode()<br />

To use this creation method for ellipses type the following code:<br />

ellipseMode(CORNER);<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 64


An Introduction To Programming With <strong>Processing</strong><br />

It's time to save your sketch if you haven't already done so. In the PDE click<br />

File → Save As...<br />

Change the name of your sketch and save it. <strong>Processing</strong> will create a new folder<br />

in your sketchbook folder with the new name of your sketch, it's also worth<br />

noting that if you have added any additional files to your sketch such as images or<br />

other files processing will also copy the data folder that it created automatically<br />

when you added external content to a sketch to the new sketch location. This is<br />

something to be aware of as you can inadvertently duplicate the amount of data<br />

on your hard disk drive if you are unaware of this feature in <strong>Processing</strong>. Adding<br />

external content to a sketch is something we will get into a bit later when we start<br />

adding images to our sketch.<br />

Your sketch should read something like this:<br />

/**<br />

*<strong>Hello</strong> World 1.2 Program<br />

*by Lyndon Daniels.<br />

*<br />

*This example program demonstrates how to<br />

*create a <strong>Hello</strong> World Program in <strong>Processing</strong>.<br />

*/<br />

//Determine the size of the display window<br />

size(640,480);<br />

background(0,0,0);<br />

//Print characters to the console<br />

println("<strong>Hello</strong> World");<br />

//Render and format text<br />

textAlign(CENTER);<br />

textSize(24);<br />

fill(191,233,255);<br />

text("<strong>Hello</strong> World", width/2, (height/4)*3);<br />

//Drawing the face<br />

ellipse(width/2, height/2, 100, 100);<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 65


An Introduction To Programming With <strong>Processing</strong><br />

Aliasing<br />

You might have noticed that the ellipse is looking a bit pixelated and not very<br />

smooth this effect is known as aliasing and is often counteracted with the effect<br />

of anti-aliasing which creates the impression of the data (such as an ellipse)<br />

drawn to the display of a computer screen as appearing to look smoother.<br />

Fortunately in <strong>Processing</strong> we have a function that is made exactly for the purpose<br />

of making the contents of a sketch look smoother. Add the following statement to<br />

the first part of the sketch just after the size() function:<br />

smooth();<br />

The smooth() function does not accept any parameters but still requires<br />

parenthesis, it's also worth noting that although using the smooth() function will<br />

make your geometry appear smoother it might come at the expense of slowing<br />

down the rate at which your sketch runs. By default a <strong>Processing</strong> sketch will try to<br />

update itself 60 times in one second (if a program loop such as draw() is used),<br />

this allows for smooth looking motion in a <strong>Processing</strong> sketch and almost<br />

instantaneous interactivity. We are creating what is known as a static sketch<br />

which does not involve any interactivity or animation, so using the smooth()<br />

function in this situation should not greatly influence the sketches performance.<br />

Smile<br />

The ellipse needs a smile in order to make it into a smiley face. We will use an arc<br />

to draw the smile, the main reason we are using an arc is firstly to introduce the<br />

arc() function but more importantly it's an opportunity to explore working with<br />

angles in <strong>Processing</strong>.<br />

Angles in <strong>Processing</strong><br />

In mathematics angles are usually measured in either degrees or radians,<br />

<strong>Processing</strong> and many other programming languages generally accept and/or prefer<br />

the latter. One of the main reasons most programming languages accept a unit of<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 66


An Introduction To Programming With <strong>Processing</strong><br />

measuring angles in radians is because it allows us to work with the value known<br />

as PI (pronounced py rhymes with “try”) and represented mathematically as π. PI<br />

is a number that has the approximate value 3.1415927 (calculated to seven<br />

decimal places). The actual number that PI represents, in programming, is not<br />

quite as important as it's mathematical equivalent subsequently we will generally<br />

never need to remember what this number is in programming but rather what the<br />

language we are choosing to use it in, represents it as. In <strong>Processing</strong> the value of π<br />

is represented by the mathematical constant PI. To <strong>Processing</strong> and many other<br />

programming languages a constant is a value that does not change, as a result it<br />

makes sense for the <strong>Processing</strong> representation of pi to be a constant. Pi has always<br />

been the same value long before Archimedes approximated it's value in the 200's<br />

BC as it's implication in the construction of many architectural wonders of human<br />

ingenuity from as far back as the Egyptian pyramids and even further back in<br />

human history suggests, and it's highly unlikely that pi could be used to represent<br />

any other value. So what does it mean?<br />

Pi is the ratio of the circumference of a circle to it's diameter, and pi radians is<br />

also equal to approximately 180 degrees. Pi can be expressed mathematically as:<br />

π = C/d<br />

Where C is the circumference of a circle and d is the diameter of a circle.<br />

So how do we use this information about pi to work with radians and degrees?<br />

Well we already know that pi radians is equal to 180 degrees so that means twice<br />

pi radians (or you might be more familiar with the mathematical notation 2πr) is<br />

equal to a full revolution or 360 degrees, or as the value is referred to in<br />

<strong>Processing</strong> TWO_PI. <strong>Processing</strong> also has other mathematical constants to<br />

represent pi in other useful quantities such as HALF_PI which is the<br />

approximately equivalent to 90 degrees and finally QUARTER_PI. But what<br />

about all the other infinite angles how do we reference these values in <strong>Processing</strong>?<br />

You could either type them out explicitly as radians or if you know their<br />

approximate equivalent in degrees you can use a formula to convert the value<br />

from degrees to radians:<br />

radians = (π/180)*angle in degrees<br />

For example if we had the angle 270 degrees and we needed this in radians so that<br />

we could use it in our <strong>Processing</strong> sketch we could either use the mathematical<br />

constants <strong>Processing</strong> provides us with and type the following expression:<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 67


An Introduction To Programming With <strong>Processing</strong><br />

PI + HALF_PI<br />

This expression would return the equivalent of 270 degrees in radians. Or we<br />

could use the above mentioned formula and type the following expression in<br />

<strong>Processing</strong>, which would also return the equivalent of 270 degrees in radians:<br />

(PI/180)270<br />

Remember that because there is no mathematical operator between 270 and<br />

parenthesis the value of what is in parenthesis must be multiplied by 270, this will<br />

return the equivalent of 270 degrees in radians.<br />

One of the simplest methods of converting degrees to radians in <strong>Processing</strong> is to<br />

use the radians() function. If you know the value of the angle in degrees you can<br />

simply use the value in degrees as a parameter of the radians() functions. For<br />

example:<br />

radians(270);<br />

This will convert 270 degrees to it's equivalent in radians. It is important that<br />

angles in <strong>Processing</strong> are converted to radians because all trigonometric functions<br />

that require angles accept this value in radians.<br />

Getting the hang of working with radians at first might be a little tricky if you are used to<br />

degrees, but if you think of them in terms of pi they can be a lot easier to work with.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 68


An Introduction To Programming With <strong>Processing</strong><br />

The arc() function in processing accepts six parameters in the format x, y, width,<br />

height, start, stop. You are already familiar with the first four parameters x and y<br />

determine the point of origin of the arc and this can be further controlled with the<br />

ellipseMode() function. width and height represent the dimensions of the arc in<br />

much the same way that these parameters, determine the dimensions of an ellipse.<br />

The last two parameters you might not be familiar with start and stop determine<br />

the starting and ending values of the angle of the arc, so for example we are going<br />

to draw a half circle which you know has an angular value of 180 degrees,<br />

secondly because we want our smile to be straight we will start it at 0 and end it at<br />

PI (which is approximately 180 degrees). Add the following statement to your<br />

sketch following the ellipse statement:<br />

arc(width/2, height/2, 50, 50, 0, PI);<br />

A Smile on the “<strong>Hello</strong> World” Program.<br />

Editing the smile<br />

Our smile drawn with the arc() function looks fine but needs a bit of work. Firstly<br />

although you cannot see it the arc actually has a fill. In order to see the fill we will<br />

first have to remove or hide the ellipse, but we're happy with the way the ellipse<br />

looks so instead of deleting the statement or cutting it to the clipboard we'll<br />

comment it out. Commenting out a statement or a group of statements is the<br />

process of adding comment tokens to the statements that cause the statements to<br />

be ignored by the compiler. Comment tokens in <strong>Processing</strong> are two forward<br />

slashes “//” as mentioned previously. The easiest way to comment out the ellipse<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 69


An Introduction To Programming With <strong>Processing</strong><br />

statement is simply to place the comment tokens at the start of the statement so it<br />

looks like this:<br />

//ellipse(width/2, height/2, 100, 100);<br />

you will notice that when you comment out a statement, syntax highlighting<br />

causes the statement to turn grey. This means we can now run the program and<br />

<strong>Processing</strong> will no longer draw our ellipse, until we uncomment the statement by<br />

deleting the comment tokens. Another way of commenting out a whole block of<br />

code is to select the lines of code you wish to comment out in the PDE click:<br />

Edit → Comment/Uncomment<br />

This will toggle your selection between a commented state and a standard block<br />

of non-commented code. Commenting and uncommenting is just simply a<br />

convenient and easy way of testing a program by including and excluding<br />

statements easily without having to retype out a statement that has been deleted or<br />

using our operating system's clipboard.<br />

Commenting out the ellipse statement reveals that the arc is drawn with a fill.<br />

To remove the fill we will use the noFill() function. So between the ellipse<br />

commented statement and before the arc statement add the following code:<br />

noFill();<br />

The order in which commands are issued to <strong>Processing</strong> is very important.<br />

Functions such as rectMode() and noFill() not only effect the command that<br />

directly follows them (such as the arc statement being effected by the noFill()<br />

function) but they also effect all statements that follow there after that rely on<br />

these special functions. So what that means is that if we were to place the noFill()<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 70


An Introduction To Programming With <strong>Processing</strong><br />

function before an uncommented ellipse statement followed by the arc statement<br />

both the ellipse and the arc would have no fill. This is obviously not what we<br />

want, we only want the arc to be without a fill and subsequently run the ellipse()<br />

function before noFill().<br />

If you were to run the sketch at this point it might look as though the noFill()<br />

command has removed the arc completely from the Display Window, but this is<br />

not the case. In <strong>Processing</strong> 2D primitives such as triangles, arcs, quads, ellipses<br />

and rectangles are actually made up of both a fill and a stroke. We've already seen<br />

that the fill can be controlled with the noFill() function, the fill() function and that<br />

the default in <strong>Processing</strong> is that all 2D primitives have a fill.<br />

The stroke is the outline that surrounds all 2D primitives and looks like a line.<br />

The stroke can also be turned off by a function similar to the noFill() function, as<br />

you might have guessed it's noStroke().<br />

To turn the stroke or fill back on or to simply edit an existing stroke or fill we use<br />

the stroke() or fill() functions. Both of these functions accept parameters in the<br />

form of a grayscale color, an RGB value or a RGBA value by default. You can<br />

also control how <strong>Processing</strong> accepts parameters for these two functions with the<br />

colorMode() function. We'll be changing our black stroke (which is why it seems<br />

to have disappeared, because it's camouflaged into the black background) to a red<br />

smile. Add the following statement after the noFill statement:<br />

stroke(255,0,0);<br />

The stroke() function can be used in a similar way fill() is used but for editing the color<br />

of lines.<br />

Now we have a smile floating above our text, so we're going to uncomment the<br />

ellipse statement and when we run the sketch our smile is restored to it's elliptical<br />

face.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 71


An Introduction To Programming With <strong>Processing</strong><br />

The smile is looking a little too high up on the face so we're going to move it<br />

down, this is easy enough as we already have the style of the smile we are looking<br />

for we just need to offset it's y position. To do this we are going to edit the arc()<br />

function once more to the following state:<br />

arc(width/2, height/2 + 10, 50, 50, 0, PI);<br />

Notice that because we are using an inverted Cartesian graph adding 10 to the<br />

arc's current y value actually moves the arc down, inversely if we subtracted 10<br />

we would move the smile up. At first getting used to this system might be a little<br />

tricky.<br />

Adding Eyes<br />

What's a smiley face without eyes. Add the following code to your sketch after<br />

the previous arc statement:<br />

stroke(0,0,0);<br />

fill(0,255,0);<br />

ellipse(width/2-15, height/2-15, 20, 30);<br />

ellipse(width/2+15, height/2-15, 20, 30);<br />

As we changed the stroke to red in our previous statement to draw the smile, we<br />

need to change it back to black so we add the second stroke statement to our<br />

program to change the stroke color back to black. Having also turned the fill off<br />

for the arc statement we need to turn it back on and set it to green, we can<br />

conveniently achieve both of these tasks with one function in the form of our fill<br />

statement. The x and y parameters of the ellipse functions that actually draw the<br />

eyes have had their expressions added to. For the eye on the left's x parameter I've<br />

subtracted 15 and for the eye on the right' x parameter I've added 15. When<br />

working with expressions like this it's important to remember that certain<br />

mathematical operators have precedence over others. For example * and / have<br />

precedence over + and -, this means that the expression width/2-15 is actually<br />

being evaluated like so (width/2)-15. This effect is known as operator<br />

precedence. Finally I offset the y position of the ellipses by subtracting 15 and<br />

drew them as more oval shaped by making their height's greater than their widths.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 72


An Introduction To Programming With <strong>Processing</strong><br />

Drawing Irregular Shapes<br />

Fortunately we are not limited to drawing only 2D primitives in <strong>Processing</strong>, but<br />

we can in fact draw any shape that we can imagine. We use two main functions in<br />

conjunction with several calls to another function in order to achieve this, and the<br />

main functions are beginShape() and endShape() issued in that particular order.<br />

We're going to start off by experimenting with this feature by drawing a speech<br />

bubble surrounding the “<strong>Hello</strong> World” text in our sketch.<br />

The beginShape() function tells <strong>Processing</strong> to start recording the following set of<br />

points that are given to it and the endShape() function tells <strong>Processing</strong> to stop<br />

recording, between these two functions we are going to supply <strong>Processing</strong> with a<br />

set of special coordinates in the form of the vertex() function. Since we are using<br />

the vertex() function to determine where the points of our irregularly shaped<br />

object will be drawn we cannot use any other function other than vertex() between<br />

beginShape() and endShape(). The vertex() function accepts parameters in the<br />

form of x and y, which determine where in terms of x and y the point (or vertex)<br />

is in the Display window. By adding the following statements in this particular<br />

order we will be able to draw our speech bubble:<br />

beginShape();<br />

//Start the shape in the middle of<br />

//the Display Window's x axis<br />

vertex(width/2, (height/4)*3-35);<br />

vertex(width/2-70, (height/4)*3-35);<br />

vertex(width/2-80, (height/4)*3-25);<br />

vertex(width/2-80, (height/4)*3+5);<br />

vertex(width/2-70, (height/4)*3+15);<br />

//The following statement marks the point<br />

//where the shape starts to mirror itself<br />

vertex(width/2, (height/4)*3+15);<br />

//The Previous statement marks the point<br />

//where the shape starts to mirror itself<br />

vertex(width/2+70, (height/4)*3+15);<br />

vertex(width/2+80, (height/4)*3+5);<br />

vertex(width/2+80, (height/4)*3-25);<br />

vertex(width/2+70, (height/4)*3-35);<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 73


An Introduction To Programming With <strong>Processing</strong><br />

//this is the arrowhead that points out of the<br />

//speech bubble towards the smiley face<br />

vertex(width/2 + 50, (height/4)*3-35);<br />

vertex(width/2 + 40, (height/4)*3-55);<br />

vertex(width/2 + 30, (height/4)*3-35);<br />

//the end of the shape is the same as<br />

//the beginning<br />

vertex(width/2,<br />

(height/4)*3-35);<br />

endShape();<br />

Although at first this might appear to be a lot of typing, upon further inspection<br />

you will notice that it is in fact very repetitious and more of copy, pasted and<br />

modified code. So lets have a look at what's going on here.<br />

Each vertex position can be mapped to a vertex() in the code.<br />

In the above illustration we can see that beginShape() has started recording the<br />

various points that make up the irregular shape of the speech bubble, which we<br />

subsequently define for the beginShape() and endShape() functions one vertex at<br />

a time. The first vertex is located along the center of the Display Window's x axis<br />

followed by the y parameter for this vertex which is 35 pixels above the center of<br />

the text that says “<strong>Hello</strong> World”. Of course we could just have easily typed in the<br />

values explicitly such as:<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 74


An Introduction To Programming With <strong>Processing</strong><br />

vertex(320, 325);<br />

But using this method of explicit programming does not leave much room for<br />

changes and could subsequently lead to the extremely time consuming task of<br />

changing each explicitly determined point in your program manually, if it is<br />

deemed that such a change is necessary at a later stage.<br />

From the next vertex on we can use the Display Windows width and height<br />

system variables and the text's x and y position as a starting point from which we<br />

can place every vertex that follows relative to the position of the previous one and<br />

in relation to the other elements making up our program.<br />

Using this method of implicit programming also makes it easier for us to “mirror”<br />

the coordinates of the irregularly shaped speech bubble across the center of it's<br />

own Y axis. As you will notice once we get to the vertex marked as “the point<br />

where the shape starts to mirror itself” it's just a simple question of copying and<br />

pasting the previous code excluding the first vertex statement, changing the<br />

negative values associated with the vertices' x parameters to positive values, and<br />

reversing the order of the statements in a mirrored fashion.<br />

Using an implicit style of programming can also make patterns in your code easier to<br />

identify.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 75


An Introduction To Programming With <strong>Processing</strong><br />

This can save us quite a bit of work as we don't have to work out the specific<br />

coordinate of each vertex individually all we need to work out is half of the<br />

coordinates that make up the shape and since we are mirroring the shape on the x<br />

axis we simply change the negative values associated with x to positive. Once we<br />

have all the vertices mirrored on the right hand side (excluding the last vertex) we<br />

can then start to plot the points of the arrow head of the speech bubble that points<br />

to the smiley face implying that it's saying “<strong>Hello</strong> World”.<br />

This part of the shape is pretty straight forward because we already know that we<br />

will need three points to make the triangular shape of the arrowhead and two of<br />

these points we already know the y positions of because they will be at the same<br />

height of the first and last vertices. So it's just a case of simple trail and error to<br />

determine what looks best in adding the remaining parameters to the next three<br />

vertex() functions. Once that's complete we can close the shape by placing the last<br />

vertex at the same location of the first vertex.<br />

Finally to end the shape you must use the endShape() function.<br />

You might have noticed that the image of my sketch has a speech bubble with a<br />

thick blue outline around it. This is the strokeWeight() function, and it controls<br />

how thick or thin the stroke is rendered and accepts a number as a parameter, I<br />

don't recommend setting this number too high as you might find it causing<br />

undesirable effects on your sketch. The higher the number input the thicker the<br />

line. Add the following statement before the statements that draw the speech<br />

bubble:<br />

strokeWeight(8);<br />

You might remember that in order to have a black outline around the face's eyes<br />

we set the stroke to an RGB value of 0,0,0 (or black), so although the<br />

strokeWeight() function has done it's job the effects of it might not be so obvious.<br />

Changing the stroke and fill colors are functions that you might need to run<br />

several times within a single sketch to achieve the desired result. Add the<br />

following statement before the previous statement:<br />

stroke(50,127,255);<br />

This changes the stroke color for the speech bubble to a little bit of red, about 50<br />

percent green and full blue. The fill color of my speech bubble is white and if you<br />

want to change the fill color of your speech bubble you must add the fill()<br />

function before the drawing of the speech bubble. Your statement would look<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 76


An Introduction To Programming With <strong>Processing</strong><br />

something like this:<br />

fill(255,255,255);<br />

or<br />

fill(255);<br />

Either option is perfectly acceptable, the latter is used for determining a gray scale<br />

value from 0 which is black to 255 which is white.<br />

The Stroke Caps are over lapping on the first and last vertex of the speech bubble in the<br />

current version of the Sketch.<br />

The section of the speech bubble where the first and last points of the shape<br />

overlap has an unsightly blemish caused by stroke caps. Stroke Caps determine<br />

how the end of a stroke is drawn and fortunately we have a function in <strong>Processing</strong><br />

for controlling this feature, as you might have guessed the function is called<br />

strokeCaps() and it accepts the parameters ROUND, SQUARE or PROJECT.<br />

Different types of stroke caps in <strong>Processing</strong>, which are very similar in effect to that of a<br />

vector illustration package.<br />

Remember that <strong>Processing</strong> is case sensitive so you must type the parameters name<br />

with the correct casing. ROUND is the default parameter that causes strokes in<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 77


An Introduction To Programming With <strong>Processing</strong><br />

<strong>Processing</strong> to have a beveled end, SQUARE will end the stroke with a flat end<br />

and PROJECT will tend to render the end of the stroke slightly past it's destined<br />

coordinates. We are going to use SQUARE to fix the speech bubble blemish. Add<br />

the following statement after the strokeWeight() function call:<br />

strokeCap(SQUARE);<br />

Order, order!<br />

That's great we now have a speech bubble, but where's our text gone to? If you<br />

added the statement to draw the irregular shape to the end of your sketch,<br />

<strong>Processing</strong> would have drawn the speech bubble over your text. Your text is still<br />

there just underneath the speech bubble, obviously this is not the desired effect.<br />

So we are going to reorder things in our sketch, with some simple cut and paste<br />

commands. Cut the three statements that relate to rendering text to the Display<br />

window textAlign(), textSize() and text() to the end of the sketch so that they are<br />

run after the speech bubble is drawn. If you were to run the sketch now your text<br />

will still appear to be missing, but in fact is still there it's just that because it's<br />

been drawn after the speech bubble it's also been effected by the fill() function<br />

issued to change the speech bubble's fill to white. White text on a white<br />

background isn't very legible so we'll change the text to another color, I'm going<br />

to make my text the same color as the speech bubble outline by adding the<br />

following statement before the text is drawn to the display and after the speech<br />

bubble is rendered:<br />

fill(50,127,255);<br />

Finishing the sketch<br />

To add the final touches to the <strong>Hello</strong> World 1.2 Program we're going to get<br />

<strong>Processing</strong> to display an image for the sketches background instead of the black<br />

background. This exercise will also be our first introduction to the programming<br />

paradigm Object Oriented Programming and the concept of data typing.<br />

The first thing we need to do is set our sketch up to accept external data in the<br />

form of an image. With the PDE open, open a file browser via your operating<br />

system and locate the file named “smileBkg.png”. From your file browser click<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 78


An Introduction To Programming With <strong>Processing</strong><br />

and drag the file into the sketch you would like to use the image in.<br />

Adding an Image to a Sketch in <strong>Processing</strong> is easy, you just click and drag it into the<br />

PDE.<br />

When you have dropped the file to the sketch <strong>Processing</strong>, will confirm this in the<br />

debugging area by printing the phrase “One file added to the sketch”. If you get<br />

this message you are ready to start using the image in your sketch. In order for<br />

you to use external data such as an image in your <strong>Processing</strong> sketch the data has<br />

to exist in a folder called “data”, which must be a subdirectory of the location<br />

where your sketch is saved. For example, we set up <strong>Processing</strong> at the start to store<br />

all sketches in a single folder which I've called “Sketchbook”, within this folder<br />

will be located the sketches we create with the PDE. I've called my <strong>Hello</strong> World<br />

1.2 Program “smile” so within the Sketchbook folder is another folder called<br />

“smile” and within the smile folder is the file smile.pde (which is my <strong>Hello</strong> World<br />

sketch) and another folder called “data”. When we dropped the image into the<br />

PDE <strong>Processing</strong> automatically created the data folder, and placed a copy of the<br />

smileBkg.png file in it. If you would like to view the contents of this folder you<br />

can access it quite easily from the PDE by clicking<br />

Sketch → Show Sketch Folder<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 79


An Introduction To Programming With <strong>Processing</strong><br />

When transporting your <strong>Processing</strong> sketches from one computer to another you<br />

must always retain this directory structure of having your data folder as a<br />

subdirectory of the location where you saved your processing sketch which<br />

should always have the extension .pde.<br />

Programming Paradigms<br />

A programming paradigm is a fundamental style of programming, the term is<br />

often confused with programming methodology which is a style of addressing a<br />

problem within a program. But perhaps a better way to understand what a<br />

programming paradigm is would be to look at some examples of it.<br />

Many modern day software languages offer at least two fundamental<br />

programming paradigms, most commonly amongst these two choices are the<br />

Objected Oriented Programming Model and Procedural Programming Model.<br />

Procedural programming is also sometimes referred to as imperative<br />

programming. Like the name implies imperative programming is a programing<br />

paradigm that is used to determine a set of commands and/or steps a computer<br />

program must take in order to reach a desired state. It's worth knowing that the<br />

Object oriented programming model is often contrasted to the procedural<br />

programming model because of the fundamental differences that separate these<br />

programming paradigms.<br />

Procedural Programming can be summarized as a style of programming where the<br />

program is tailored to suite the data as opposed to Object oriented programming<br />

which is more akin to a style of programming where the data is tailored to suite<br />

the program.<br />

So what exactly does that mean?<br />

As mentioned earlier, programs are made up of statements and one of the things<br />

statements are made up of is commands. As you might recall a command in<br />

programming, much like in a natural language, is used to communicate a<br />

directive. In this way procedural programming is a list of statements telling a<br />

computer what to do. At this point you could be thinking “Isn't that the purpose of<br />

all programming i.e. telling a computer what to do, so how then does procedural<br />

programming differ from any other programming paradigm?”<br />

In one way or another we use programming to represent data, whatever that data<br />

may be for example the amount of tea compared to the amount of coffee<br />

consumed over the past ten years world wide, or it could be determining the<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 80


An Introduction To Programming With <strong>Processing</strong><br />

choices a character has in a game then choosing to act on those choices or it could<br />

even be something as simple as representing a set of alpha numeric characters on<br />

the screen that spell your name. Whatever way you look at it creating a program<br />

requires data. In procedural programming we use the tools provided to us by the<br />

language we are programming in to break down that data into smaller data types<br />

that the language predetermines for us and then use those representations to create<br />

a program that ultimately represents the larger original data set programmatically.<br />

This can be contrasted to object oriented programming where we use the tools<br />

provided to us by the language we are programming in to create our own data<br />

types for which we determine their meanings and use these new data types to<br />

create a program that ultimately represents our original data set.<br />

Datatyping Categories<br />

Organizing the data that we represent in a program can be a difficult task unless<br />

you have some sort of system that can be applied at a higher level to abstract the<br />

complex interactions that a machine must facilitate in order to make the data we<br />

interact with more accessible to us. Datatypes make the process of organizing the<br />

various forms of data that exist in our programs more accessible and categorically<br />

meaningful to us. What qualifies as a data type varies from one programming<br />

language to another and also forms the basis of what differentiates the two main<br />

programming paradigms we are dealing with Procedural Programming and Object<br />

Oriented Programming.<br />

In <strong>Processing</strong> there are three main categories of data types that we will be dealing<br />

with Primitive data types, <strong>Processing</strong>'s API data types and User Defined Complex<br />

data types.<br />

Primitive Data Types<br />

Primitive Data Types form the building blocks of all the other mentioned forms of<br />

data types, and as a result are immutable, meaning that what defines them cannot<br />

be modified by use of <strong>Processing</strong>.<br />

Numbers can be represented as Primitive data types and most commonly fall into<br />

the primitive data type definition of int or float. An int data type is an<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 81


An Introduction To Programming With <strong>Processing</strong><br />

abbreviation of the word integer and is used to create categories of numbers<br />

within a program that represent whole values such as 0, 1, -58, 6000000 and so<br />

on. In <strong>Processing</strong> these values can range anywhere between 2,147,483,647 to<br />

-2,147,483,648. A float (or floating point number) is a data type used to<br />

categorize numbers that have a decimal point. Numbers such as 1.5, 3.0, -56.91<br />

and even numbers such as 3.40282347E+38 in SI (the International System of<br />

Units) notation qualify to be a float primitive data type. Typographic characters<br />

such as 'A', 'b', '5', '@' etc can also be stored as primitive data types by use of the<br />

char data type which is an abbreviation for the term character. However, storing a<br />

sequence of typographic characters as a single unit requires a different data type<br />

that is more complex than a primitive.<br />

<strong>Processing</strong>'s API Data Types<br />

In order to make languages fit more specifically to an environment certain<br />

repetitive tasks are often automated by the developers of the language's API. The<br />

acronym API stands for Application Programming Interface and it refers to the<br />

means by which you communicate with a program. Although you are creating<br />

programs (known as sketches) with <strong>Processing</strong>, <strong>Processing</strong> in itself is also a<br />

software program. We have been communicating with <strong>Processing</strong> through the<br />

PDE, and within the PDE we have been typing statements instructing <strong>Processing</strong><br />

what we would like it to do with the data we have supplied it with. Those<br />

instructions such as functions, tokens, arithmetic operators etc that we are using to<br />

communicate with <strong>Processing</strong> are all defined within <strong>Processing</strong>'s API.<br />

<strong>Processing</strong>'s API Data Types are special data types defined within the <strong>Processing</strong><br />

API that may or may not be found in other languages, but will make fulfilling the<br />

requirements of creating sketches (including data visualizations, end-user<br />

interactions and many other features commonly found in sketches) easier and less<br />

repetitive for the programmer by abstracting base-level computational<br />

interactions. The PImage data type is an example of a <strong>Processing</strong> specific API<br />

Data Type that makes the task of dealing with images much simpler for the<br />

programmer. The String data type is a <strong>Processing</strong> non-specific API Data Type,<br />

meaning that although this data type is common to many different programming<br />

languages it is not a primitive data type as it uses characteristics of both int and<br />

char primitive data types in it's implementation. <strong>Processing</strong>'s API Data Types are<br />

usually quite easy to identify as the keyword used to invoke them usually starts<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 82


An Introduction To Programming With <strong>Processing</strong><br />

with an upper-case character, this is a common standardized programming<br />

practice that is used to identify Classes which are the fundamental building blocks<br />

of Object Oriented Programming and are an inherent quality of <strong>Processing</strong>'s API<br />

Data Types.<br />

User Defined Complex Data Types<br />

In procedural based programming languages the programmer is supplied with a<br />

predetermined set of keywords that can be issued during the course of the<br />

program to communicate with the languages API, as a result no matter what the<br />

data that you are representing with your program is, that data must be tailored to<br />

fit those keywords. This means that your data will need to be fragmented,<br />

categorized and associated with the predetermined data types of the procedurally<br />

based language. This differs substantially from an object oriented approach to<br />

programming, in that you tailor the program you are creating to suit the data you<br />

are representing. In Object Oriented Programming you define your own data<br />

types by combining various Primitive data types and predetermined complex data<br />

types of the programming language's API into your own User Defined Complex<br />

Data Types that are referred to as Classes. These data types can then be<br />

instantiated throughout your program as often as necessary and used in a manner<br />

that is akin to how any other data type is used. The invocation or instantiation of a<br />

Class data type is known as a Software Object, and this is how the Object<br />

Oriented Programming (or OOP for short) paradigm evolved. Objects that are<br />

instantiated from the classes that make up an OOP program fall into the category<br />

of being user defined complex data types.<br />

PImage<br />

We are going to create a new software object from the PImage class, and we will<br />

give this new object a name. It is important that the name that we assign to the<br />

new object is unique so that when ever we want to use that object we can refer to<br />

it by it's name and <strong>Processing</strong> will know exactly which object we are referring to.<br />

The PImage Class contains useful information about the image we are loading<br />

into our sketch and allows us access to this information without having to<br />

understand how it has extracted this information from the image, such as it's<br />

width, height or how many pixels make up the image and what color each pixel is.<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 83


An Introduction To Programming With <strong>Processing</strong><br />

This is one of the benefits of object oriented programming, being able to abstract<br />

complex code by referencing it with a single keyword, the name of the object.<br />

Amongst the prerequisites of using an image file as a background in <strong>Processing</strong> is<br />

that the image must be in either gif, jpg, png or tga format and must have the<br />

same dimensions as the sketch in which it will be displayed. If you have had a<br />

look at the smileBkg.png file you might have noticed that the dimensions do not<br />

match that of our current sketch. However, we are in luck because we have been<br />

using an implicit style of programming to specify the x and y parameters within<br />

our sketch so changing the dimensions of our sketch at this late point in the<br />

programming process is actually not going to cause a problem. If on the other<br />

hand we had used an explicit style of programming we would have a problem as<br />

all of our had work to keep the graphical components of our sketch in the center<br />

of the display window would now be lost and fixing it would mean having to go<br />

through every statement where x and y coordinates where used and changing<br />

them to accommodate for the new sketch size.<br />

Since we are loading our image as a background we are going to add the<br />

following statements before the background statement near the top of the sketch.<br />

To create a new object from the PImage class add the following statement before<br />

the background statement:<br />

PImage img;<br />

This statement tells <strong>Processing</strong> that we want to create a new software object<br />

which has all the properties of the PImage data type and we would like to call this<br />

new object “img”. Our new software object has inherited the properties of the<br />

PImage data type which allow us to access information about the image we would<br />

like to store within the object without us having to know how exactly it goes<br />

about accessing this information. However, what our new object does not know<br />

yet is what image exactly we would like to use in our sketch and refer to as img.<br />

Add the following statement after the previous PImage statement:<br />

img = loadImage("smileBkg.png");<br />

This statement tells <strong>Processing</strong> the name and location of the image file we would<br />

like to use and refer to as img throughout the rest of our sketch. Because the<br />

image file has already been dropped into our sketch <strong>Processing</strong> has already placed<br />

a copy of the file in our data folder. <strong>Processing</strong> will expect to find whatever image<br />

files we are using in our sketch in this folder. The loadImage() function can also<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 84


An Introduction To Programming With <strong>Processing</strong><br />

accept a URL as a parameter if you wanted to load an image that is not located<br />

locally on the same station that your sketch is running from.<br />

So now that we have the image loaded into our sketch we need to tell <strong>Processing</strong><br />

what we would like to do with and, where we want to place it and finally to draw<br />

the image to the Display Window.<br />

To display the image in our sketch we're going to modify the background<br />

statement and <strong>Processing</strong> will now draw the image to the Display Window when<br />

we run the sketch. Modify the background statement to read:<br />

background(img);<br />

This statement simply tells <strong>Processing</strong> that we would like to use the object which<br />

has the properties of an image, which we have called img, as a background. Later<br />

we will have a look at compositing images on top of each other in addition to<br />

using them as backgrounds.<br />

To briefly recap on the steps we took to load an image into our sketch<br />

1. Drop the image into the PDE<br />

2. Create a new software object from the PImage Class<br />

3. Load the image file into the new software object<br />

4. Instruct <strong>Processing</strong> to display the image through it's identifier<br />

The completed “<strong>Hello</strong> World 1.2” Program<br />

<strong>Hello</strong> Display Window: <strong>Hello</strong> World 1.1 85


An Introduction To Programming With <strong>Processing</strong><br />

The Design and Layout Program<br />

Using what we've learned thus far from this guide, I've constructed a program that<br />

“sketches” a prototype for an interface to an online portfolio.<br />

The Completed Design and Layout Program<br />

Program Notes for Interface01.pde<br />

The PDE Tools menu<br />

Under the Tools menu in the PDE are additional build automation tools that<br />

members of the community have contributed to <strong>Processing</strong>. More tools can be<br />

downloaded to add to the functionality of <strong>Processing</strong> by downloading and<br />

installing the necessary files from http://www.processing.org/reference/tools/<br />

A useful tool that comes with the PDE is the Create Font tool. This tool allows<br />

you to package any font you'd like to use in your sketch so that users accessing<br />

your sketch do not have to have that font installed on their computers in order for<br />

the sketch to display properly. To use the Create Font tool in the PDE click:<br />

Tools → Create Font..<br />

The Design and Layout Program 86


An Introduction To Programming With <strong>Processing</strong><br />

The Create Font build automation tool can be used to ensure that users do not have to<br />

have the fonts you have installed on your computer in order for your sketch to display<br />

properly on their computers.<br />

The Create font dialogue box appears in which you can scroll down to and select<br />

the font you would like to package with your sketch, choose a size you would like<br />

to have the font displayed at by specifying a value in the size field (values are in<br />

pixels). The size value determines size of the characters of the font that will be<br />

exported as bitmaps, and although you can change what size you would like to<br />

display a font as in your sketch even after it's been exported it is recommended<br />

that you use the font in your sketch at the same size that you exported it as for<br />

best results. Up-scaling a font is definitely not recommended and as a result if you<br />

do plan on using the font in different sizes it is best to use the Create Font tool to<br />

export the font at the largest size and use <strong>Processing</strong> font() function to down-scale<br />

the font only.<br />

When you are happy with your selection click “ok” and <strong>Processing</strong> will create a<br />

file with the extension .vlw in your sketch's data folder, it is important that you<br />

know the exact name of this font as you will need to load it just like you loaded<br />

an image into <strong>Processing</strong>.<br />

To use the font in your sketch, you will need to follow a procedure very similar to<br />

The Design and Layout Program 87


An Introduction To Programming With <strong>Processing</strong><br />

that of loading and displaying images. Start by creating a new object that will<br />

serve as the container for your font, by adding the following statement:<br />

PFont myFont;<br />

PFont is a special data type in <strong>Processing</strong> used for storing fonts, in a similar way<br />

that PImage works with images. myfont is the name we have chosen to create an<br />

object that inherits the unique qualities of PFont. Next you will need to load the<br />

font into your sketch, to do so add the following statement:<br />

myFont = loadFont("FancyFont-Bold-42.vlw");<br />

The loadFont() function accepts one parameter that is the name of the font,<br />

including it's extension, enclosed within double quotes. We will then need to<br />

specify what font we would like to use to display text in our sketch, because you<br />

are permitted to use more than one type of font in a sketch the next statement tells<br />

<strong>Processing</strong> which font it is you would like to render the text that follows with:<br />

textFont(myFont,42);<br />

The textFont() function accepts two parameters, the name of the PFont object you<br />

have created (which is myFont in this case) and the size at which you would like<br />

the text that follows to be rendered at. All the calls to the text() function that<br />

follow this statement will use the parameters set in textFont() until textFont() is<br />

called again with a different set of parameters. Finally you can draw the text to<br />

the Display Window with the text() function:<br />

text("Welcome to my\n<strong>Processing</strong> Portfolio", width/2, height/2);<br />

You might notice something strange about the literal string parameter for the<br />

text() function. Between the characters “my” and “<strong>Processing</strong>” are the characters \<br />

n. This is known as an escape character and is not rendered with the literal string.<br />

Escape characters are used to format text before they are drawn to the screen. In<br />

my Interface01 sketch there is a break between “Welcome to my” and<br />

“<strong>Processing</strong> Portfolio”, this is because the \n is known as a new line escape<br />

character and has the function of inserting a break between characters. This saves<br />

me having to use the text() function twice, first to render the text “Welcome to<br />

The Design and Layout Program 88


An Introduction To Programming With <strong>Processing</strong><br />

my” and adjust the y parameter in the next call to text() to render the rest of the<br />

sentence. Using a short-cut like this can save your program some overhead, but<br />

also comes with the expense of making your code look a little less readable,<br />

particularly if you have never seen an escape character before.<br />

Another place where I've used a short-cut in my Interface01 Program is in the<br />

statement where I create the objects for storing the images that I will use in the<br />

rest of the sketch. The following statement demonstrates this:<br />

PImage mGoat, banner, bkg, button;<br />

The long version of this code would look like this:<br />

PImage mGoat;<br />

PImage banner;<br />

PImage bkg;<br />

PImage button;<br />

As you can see using a shortcut in this way can save you quite a bit of typing and<br />

can actually make your code even easier to read.<br />

The Design and Layout Program 89


An Introduction To Programming With <strong>Processing</strong><br />

Beyond Static Sketches and on to Active<br />

mode<br />

Static sketches are mainly used for testing basic programs that do not incorporate<br />

interactivity or are used to output and image file such as a .png or .pdf. The<br />

majority of programs produced with <strong>Processing</strong> are made using active mode.<br />

Active mode requires two fundamental additions to a sketch, the setup() and<br />

draw() functions.<br />

setup() and draw() provide a new structure to sketches and allow for the<br />

initialization of a code block within setup() and the repetition of the code block<br />

within the draw() structure. Code blocks within the setup() and draw() functions<br />

are always cradled between braces, so they are easy to identify. The structure of<br />

an active mode sketch generally follows the pattern identified in the example<br />

below:<br />

void setup(){<br />

code...// This code block will run only once,<br />

… // at the start of the sketch.<br />

...<br />

}<br />

void draw(){<br />

code..// This code block with run repeatedly,<br />

… // throughout the duration of the sketch.<br />

…<br />

}<br />

A typical active mode sketch structure with the setup() and draw() code blocks<br />

highlighted<br />

90


An Introduction To Programming With <strong>Processing</strong><br />

Up until now our sketches have not been interactive or included any animation.<br />

The use of the active mode structure, including the addition of the setup() and<br />

draw() functions, allows us to truly access the powerful features that<br />

programming offers to developers and extend our sketches with interactivity,<br />

animation, logic and a host of other features that we shall explore.<br />

We'll start by having a look at how setup() and draw() change our sketches and<br />

make them more dynamic.<br />

Methods, functions and their contexts<br />

The setup() and draw functions() are also sometimes, less accurately, referred to<br />

as methods. A method is simply another way of saying function, but more<br />

specifically it refers to the function of a class. As you might remember, classes<br />

form the building blocks of object oriented programming and can be packaged<br />

into groups consisting of many classes which we refer to as Libraries. From<br />

Libraries we can access classes, from which we can instantiate objects that we use<br />

in our programs. But before using a particular library we would first need to tell<br />

<strong>Processing</strong> to import that library for usage within our sketch, by using the import<br />

keyword. This differs from using a class built into <strong>Processing</strong>'s API where we do<br />

not need to use the import keyword, for example we could instantiate an object<br />

from the PImage class and call it img like in our <strong>Hello</strong> World program, without<br />

using the import keyword within the PDE, like in the following code fragment:<br />

PImage img;<br />

One of the methods (that works, in a sense, just like a typical function would of<br />

our main program) of img could be to resize the width and height of the image<br />

that we have associated with it for example:<br />

img.resize(50,100);<br />

This statement would resize the width and height of the image associated with the<br />

img object to 50 and 100 respectively. In this sense the resize() keyword used in<br />

relation to the img object would be a method of the img object. Just like a<br />

function, a method's definition can also exist independently of the main program.<br />

91


An Introduction To Programming With <strong>Processing</strong><br />

So as you can see the term method is very similar to that of function in terms of<br />

the purpose they both serve. However, it is important that the terms are not used<br />

interchangeably as they can lead to ambiguity and confusion.<br />

As I have mentioned before <strong>Processing</strong> is a language on it's own and not just a<br />

library consisting of classes for Java. If it was, referring to setup() and draw() as<br />

methods would be perfectly acceptable because they would be methods of a class<br />

defined within the <strong>Processing</strong> library for Java. Although <strong>Processing</strong> can be used<br />

in this context we are not using <strong>Processing</strong> as a library for Java we are using<br />

<strong>Processing</strong> as a language that is independent of Java until implementation, this is<br />

relevant because although <strong>Processing</strong> relies on Java currently for it's<br />

implementation theoretically there is nothing stopping <strong>Processing</strong> from being<br />

implemented within other environments. Within this context <strong>Processing</strong> is a<br />

language and not exclusively a library for Java. What that means is that, setup()<br />

and draw() within this definition should not be recognized as methods of a class<br />

that has been instantiated but rather as functions of a programing language. This<br />

concept can be extended even further because setup() and draw() are such<br />

fundamentally important functions within <strong>Processing</strong>, that they could be placed in<br />

a category of their own and described as structural defining functions, because<br />

they alter the structure of a program so dramatically.<br />

The setup() function<br />

Let's have a look at how the setup() function works and how it alters the structure<br />

of a program. Code that is cradled between the braces{} of the setup() function<br />

forms the code block of the setup() function and determines it's structure. This<br />

code will run only once, throughout the duration of the sketches life-cycle.<br />

Meaning that from the time the sketch is started to the point when you close the<br />

Display Window, exit the web page the sketch was running on, close the<br />

application the sketch was running through or do whatever is needed to end the<br />

sketch, the code block within the setup() function is never repeated until that<br />

sketch is run again. So how does that make the sketch more dynamic? Well in<br />

fact, when compared to the draw() function the setup() function does not<br />

contribute to significantly making the sketch more dynamic, but it does contribute<br />

to allowing the sketch to become dynamic.<br />

In programming the term dynamic is often used to describe the changing effects<br />

of a program. If we where to contrast this definition with our previous example of<br />

The setup() function 92


An Introduction To Programming With <strong>Processing</strong><br />

the interface01 program, we would see that this program is not dynamic as from<br />

the time that the sketch starts to the point when the sketch is terminated, the<br />

program does not change. However if we where to add animation to the images,<br />

or make the “buttons” of the interface clickable, then the program would be<br />

dynamic.<br />

So how does the setup() function contribute to this?<br />

One of setup()'s main forms of contribution to active mode sketches is in<br />

something we call assignment. Assignment is actually not a new concept to us as<br />

we have already used it several times in our previous sketches and is often<br />

invoked in most programming languages with an equals sign “=” which, in<br />

programming, is called an assignment operator. For example we have previously<br />

used assignment in the following context, when loading an image into a sketch in<br />

preparation for it to be rendered:<br />

img = loadImage(“myBitmap.png”);<br />

The purpose of assignment is to make whatever the value on the left side of the<br />

operator, equal the value that is on the right side of the assignment operator. In<br />

this way assignment can be a relatively straight forward or complex procedure.<br />

For example if we have a simple value such as a number or typographic character<br />

on the right of the assignment operator, the assignment of that value to whatever<br />

exists on the left is relatively straightforward because we're just simply telling<br />

<strong>Processing</strong> to make whatever is on the left of the assignment operator be the same<br />

as that which is on the right and then store those values in the computer's<br />

memory. However if we have an expression, a command or both on the right of<br />

the assignment operator the task of assignment can become more complex not<br />

only for <strong>Processing</strong> but also for us to keep track of.<br />

In the previous example we are assigning the value of the bitmap image that<br />

exists in our data folder called myBitmap.png to img, by using the loadImage()<br />

function.<br />

But, what exactly is going on in this assignment statement, as the computer that is<br />

running the sketch sees it?<br />

Firstly the computer running the sketch must process the call to the function<br />

loadImage() this requires processing power, and secondly the computer having<br />

realized what the loadImage() function requires after processing it now accepts<br />

the parameter “myBitmap.png”.<br />

The setup() function 93


An Introduction To Programming With <strong>Processing</strong><br />

In order for it to accept this parameter it has to allocate a certain amount of it's<br />

memory to load the image. Computers have a limited amount of memory and the<br />

larger the bitmap image's size (in terms of kilobytes, megabytes, etc.) the more<br />

memory they require to be loaded into a sketch. As a result the computer must try<br />

to allocate memory that has not already been assigned to another value and does<br />

not request more memory than is necessary. All of this work performed by the<br />

computer is performed without us having to know anything about the steps it must<br />

take to display the image in our sketch.<br />

As you can see, although this assignment statement was relatively easy for us to<br />

create, the steps that our computers must take in order to make what we are<br />

requesting possible is actually not so straightforward.<br />

The setup() function can be very useful in a situation such as this, because the<br />

previous statement is so resource insensitive it is not the kind of statement we<br />

would like to have repeated throughout the duration of our running program.<br />

Doing this will simply cause a bottleneck effect on the resources of the computer<br />

running the sketch and ultimately cause the sketch's performance to drop, as the<br />

computer struggles to keep up with our requests.<br />

The setup() function as a result will run only once throughout the duration of a<br />

program, and is designed to keep system performance at optimal speeds so that<br />

our sketches can run more efficiently with the code that does need to be repeated<br />

such as that of the draw() function.<br />

The draw() function<br />

The draw() function differs substantially from the setup() function in that it is<br />

designed to repeat the code block associated with it and cradled between it's<br />

braces. The ability to repeat code and have it update itself in the process is a key<br />

feature in creating dynamic content. For example when creating interactive<br />

programs it is quite useful to know the position of the users mouse, so that you<br />

can use this information to determine whether the user is hovering over a button, a<br />

scroll bar, an image or other interactive interface feature. As the user is likely to<br />

move the mouse around several times while the program is running, the mouse's<br />

position will change regularly. Knowing the mouses current x and y position and<br />

being able to compare it with a previous x and y position can tell us something<br />

like which direction the user is moving their mouse in, this information can be<br />

used to enhance the interactive quality of the application.<br />

The draw() function 94


An Introduction To Programming With <strong>Processing</strong><br />

Using the setup() and draw() functions in <strong>Processing</strong> is actually quite easy, and in<br />

the following example we'll use them for the purpose of getting the user's mouse<br />

position in terms of x and y coordinates and then use the println() function to print<br />

these values to the debugging console.<br />

Enter the following code and run it. Don't be alarmed when <strong>Processing</strong> starts to<br />

print line after line of information to the console, this is actually the desired<br />

effect. Move your mouse around in the Display Window to see the values update<br />

in the console view then close the Display Window when you are done:<br />

void setup(){<br />

size(510,300);<br />

}<br />

void draw(){<br />

println("The Mouse's X position is " + mouseX +<br />

" The Mouse's Y position is " + mouseY );<br />

}<br />

The Mouse's X and Y position is updated every 60th of a second and printed to the<br />

console<br />

95


An Introduction To Programming With <strong>Processing</strong><br />

Experimentation<br />

The setup() function must always precede the draw() function, and is used to<br />

define the initial properties of the sketch such as the size of the sketch. The size()<br />

function when used within an active mode sketch must always follow the setup()<br />

function before any other statements. If we had images to display in our sketch<br />

assigning them to variables would generally be done within the setup() structure,<br />

we'll have a look at this technique a little later.<br />

The draw() function repeats once every 60 th of a second by default, but this<br />

behaviour can be changed with the frameRate() function which would be called<br />

within the setup() structure too.<br />

Within the println() function you might have noticed something a little different,<br />

two new commands, mouseX and mouseY are system variables in <strong>Processing</strong> that<br />

store the X and Y position of the mouse when it is over the window the sketch is<br />

running in. When used within a sketch they simply return a number that is either<br />

the respective X or Y coordinate of the user's mouse. It is also worth noting that it<br />

is necessary for the println() function to be repeated within the draw() structure<br />

because whenever the user moves the mouse within the Display Window a new<br />

value for the mouse's x and y position replaces the old value for the previous<br />

position of the user's mouse. If this command was within the setup() function<br />

<strong>Processing</strong> would only print the mouse's x and y values once and not again.<br />

Although this is perfectly valid code it, is not very useful to us because if the user<br />

has moved the mouse since the start of the program (when setup() ran for the first<br />

and only time) the current position of the user's mouse would not have been<br />

updated thereafter. The statement to update the mouse's x and y position would<br />

not have been repeated so according to <strong>Processing</strong> the x and y position of the<br />

mouse would be the same as when the program first started, this is obviously not<br />

the case if the user has moved the mouse.<br />

The repetitious nature of an active mode sketch<br />

Experimentation 96


An Introduction To Programming With <strong>Processing</strong><br />

The mouseX and mouseY system variables are important keywords in<br />

determining the interactive nature of many sketches so lets attempt to use them in<br />

another way that is more directly related to the visualization of sketches.<br />

Add the following statement before the println() statement:<br />

line(0,0, mouseX, mouseY);<br />

The mouseX and mouseY system variables can be used to add interactivity to a sketch<br />

After running the sketch you should be able to recreate an image within the<br />

Display Window like the preceding image. The line() function is used to draw a<br />

straight line in <strong>Processing</strong> and accepts four parameters in the form of the starting<br />

point of the line's x and y coordinates and the end point of the line in terms of x<br />

and y coordinates. In our sketch we made the starting point of the line the origin<br />

of the sketch, that is (0, 0) or zero x and zero y and we made the end point of our<br />

line equal whatever the mouse's current x and y values are. There are infinite<br />

ways of using the mouseX and mouseY system variables to create interesting and<br />

interactive qualities within a sketch, and they don't always have to relate to<br />

positional data as in our previous statement. For example, if we wanted to use the<br />

mouse's x value to determine the greyness of the line we could add the following<br />

statement to effect the strokes color, which we will add before the line()<br />

statement:<br />

Experimentation 97


An Introduction To Programming With <strong>Processing</strong><br />

stroke(mouseX/2);<br />

Remember that the stroke() function used in this way with only one parameter<br />

accepts values between 0 to 255 which relates to the greyness of the following<br />

strokes that are drawn? So because the size of our sketch is 510 pixels across our<br />

mouse's x position will, in the context of this sketch, return a value between 0<br />

and 510 for the mouseX system variable, as any value greater than this would<br />

mean that the mouse is no longer positioned over the sketch. Bearing this<br />

information in mind we can use what we know about the width of the sketch and<br />

divide this value by 2 so that we never receive a value greater than 510/2 or 255<br />

which is white, when input as a parameter of the stroke() function. This is a very<br />

simple example of mapping one value to another but <strong>Processing</strong> conveniently<br />

provides us with a more sophisticated method of mapping values by use of the<br />

map() function which we will look at in more detail later.<br />

By linking one value to another we can start to create some interesting effects, within our<br />

sketch<br />

Try experimenting with the mouseX and mouseY system variables until you are<br />

comfortable with them as we will be using them quite regularly in our following<br />

sketches. For example try combining the previous sketch with an ellipse that<br />

attaches itself to your mouse and has an interactive transparency feature.<br />

Experimentation 98


An Introduction To Programming With <strong>Processing</strong><br />

Here's a hint:<br />

More interactivity can be added to this sketch example quite easily<br />

fill(50, 60, 127, ??/2);<br />

ellipse(??, ??, 50,50);<br />

As you might remember, the order in which commands are issued in many<br />

programming languages is really quite important. So when <strong>Processing</strong> reads your<br />

code it is important that commands are issued to <strong>Processing</strong> in the correct order,<br />

for example we would not want to have a command that updates the color of an<br />

ellipse's fill after the ellipse has been drawn to the Display Window. We are<br />

already aware of this from our static mode sketches, however in active mode even<br />

if you do have a fill() command after an ellipse() command to update that ellipse's<br />

fill your results sometimes might be more forgiving.<br />

As active mode requires that the code within the draw() structure is repeated there<br />

remains a history from one execution of this code to the next. What that means is,<br />

even though the fill() command is issued after the ellipse() command when the<br />

program repeats the next time around <strong>Processing</strong> will remember what the value of<br />

the fill was set to in the previous execution and update your ellipse in the current<br />

cycle to match that command of the previous execution. Currently this might not<br />

seem like a big issue to you because you are ultimately getting the results that you<br />

want, but this is at the expense of creating ambiguity within your program. This<br />

could also lead to possible errors later in the programs development cycle, and is<br />

therefore not a recommended methodology for several reasons.<br />

Firstly, it is not clear within the order of such a program why the fill() command<br />

is being called. Whereas if the fill() is issued before ellipse() it is clear that it is<br />

meant to effect the color of the fill of the next ellipse that is drawn to the Display<br />

Experimentation 99


An Introduction To Programming With <strong>Processing</strong><br />

Window. Secondly, if there are other values depending on your ellipse's fill being<br />

a particular color at that point in time, and these values precede the fill()<br />

command these values will always be calculating their results based on the color<br />

of the ellipse's previous fill color and not the current color for that particular<br />

cycle. This color only becomes evident the next time the program repeats, and by<br />

then the visual representation of the fill will no longer match the values that are<br />

used in calculations preceding it. This could lead to inaccurate calculations such<br />

as division by zero which could cause your program to halt or even worse to<br />

crash. Needles to say that although you can get the results you are hoping to<br />

achieve by structuring your program in a manner that contradicts appropriate<br />

ordering, you might in effect be causing yourself more problems in the long run<br />

than necessary. Always consider how the ordering of your commands and<br />

structure of your program can be improved.<br />

Ordering statements appropriately can contribute significantly to the readability of your<br />

code.<br />

Experimentation 100


An Introduction To Programming With <strong>Processing</strong><br />

Datatyping<br />

You might have noticed something else that's new about the active mode structure<br />

of a sketch, that being the usage of the void keyword preceding both the setup()<br />

and draw() functions. The keyword void is used for defining functions that do not<br />

return a value, all other user defined functions must return a value of a certain<br />

type of data. The setup() and draw() functions differ significantly from their roots<br />

in the C/C++ main() function in that they are not intended to return a value of any<br />

type of data to the main program, the mandatory usage of the void keyword<br />

ensures this. We'll have a look at user defined functions in more detail later.<br />

The process of assigning a type to data is known as datatyping. There are many<br />

different types of data within <strong>Processing</strong> we have already had a look at some of<br />

the categories that the different types of data within <strong>Processing</strong> can be broken<br />

down into, but what exactly are these different types of data and how do they<br />

assist us in programming?<br />

One of the datatypes we're already familiar with is the PImage datatype. We know<br />

that if we want to use a bitmap image in our sketch we must first assign it to the<br />

object we created from PImage. That new object that we have then created has<br />

inherited all of the properties of the PImage data type amongst which is the ability<br />

to resize the image, get information about the pixels that make up the image and<br />

what the alpha and color values of each pixel making up the image is. We did not<br />

have to tell <strong>Processing</strong> what a pixel is or how we would like to use it, these<br />

definitions exist already predetermined within the PImage class, which will be a<br />

body of code that exists somewhere on your computer (probably in the location<br />

you installed the PDE). Now that we have a new object instantiated from the<br />

PImage class it has inherited all of the properties that define that particular type of<br />

data, in other words the new object we have created has been datatyped as<br />

PImage.<br />

But in order to understand what is really going on here we need to look a little<br />

deeper...<br />

Datatyping 101


An Introduction To Programming With <strong>Processing</strong><br />

Variables<br />

Variables are common to most programming languages as they provide us with a<br />

means of storing data within the memory of a computer without having to know<br />

the process the computer has taken to store that data and where exactly within the<br />

computers memory that data has been stored. This provides us with a convenient<br />

method for accessing data, without having to understand the complexities of<br />

manual memory management as might be the case in lower level languages. Lets<br />

have a look at how variables play a part in helping us store data.<br />

Using variables is pretty straight forward and can be thought of as a two step<br />

process, 1.) Declaration and 2.) Assignment.<br />

The second step we are already familiar with, which could imply that you might<br />

have already used variables in your previous sketches, and this is in fact correct.<br />

You have used both steps of variable creation in your previous programs as<br />

variable assignment relies on declaration.<br />

Declaration is the process of giving the data you are representing in your program<br />

a name, and is a process that involves datatyping (preformed by the programmer)<br />

and memory allocation (performed automatically in <strong>Processing</strong>). So lets have a<br />

look at a declaration in the following statement:<br />

PImage img;<br />

This is known as a form of variable declaration, you might at this point be<br />

thinking “I thought this is supposed to be object instantiation (as it has previously<br />

been referred to)?” You'd be right on both counts in this particular case because<br />

there are in fact two different things going on here. Firstly the PImage class<br />

defines all objects that are instantiated from it by whatever code that makes up it's<br />

class body, and because PImage is specific to <strong>Processing</strong>'s API and not something<br />

that exists readily within other programming languages referring to the preceding<br />

statement as object instantiation reveals the underlying structure of what is going<br />

on in <strong>Processing</strong> when compared with other programing languages. However,<br />

since PImage is a class defined within <strong>Processing</strong>'s API and can be used for<br />

datatyping the preceding statement can also be viewed as declarative, as such img<br />

can be referred to as an object variable. In contrast lets have a look at a simpler<br />

declaration that does not involve a <strong>Processing</strong> specific datatype, which can make<br />

the process of defining variables easier to grasp:<br />

Datatyping 102


An Introduction To Programming With <strong>Processing</strong><br />

int myVar;<br />

The keyword int in this statement is used to datatype a variable with the<br />

properties of type integer.<br />

Integers are primitive datatypes that must be whole numbers, such as 0, 5, -1,<br />

2430 and so on. They cannot have a decimal value. All we are doing at this stage<br />

is giving the variable a name, that being myVar, we have not given the variable a<br />

value yet the value would effectively be an integer, and associating the variable<br />

with a value is specifically what assignment is for.<br />

In the above statement we have declared a variable called myVar and datatyped it<br />

as an int. So when we want to use the variable and the data associated with it in<br />

our program we can simply refer to it by it's name for example:<br />

println(myVar);<br />

However this is getting ahead of ourselves a little, as you might remember one of<br />

the main reasons we use variables is so that we can associate data with them<br />

through the process of assignment. In the previous example we have declared a<br />

variable but not given it a value, so lets restructure the example to be more<br />

meaningful:<br />

int myVar; //Declaration<br />

myVar = 5; //Assignment<br />

println(myVar); //Prints 5<br />

In the second line we have used assignment to associate the numerical integer<br />

value of 5 with our variable, and in the third line we have put the variable to work<br />

by getting println() to read it's value back to us. You might also notice that<br />

variables are never placed between double quotes, like the literal strings we have<br />

been using with the println() function up till now.<br />

What makes variables so special is that we can get them to store any value that is<br />

valid to it's datatype, change this value then re-use it in another statement with the<br />

new value, without the help of variables a task like this would be very<br />

impractical. This is particularly useful as we never have to know what address the<br />

variable we are using has in memory, our computers take care of that for us.<br />

Here's an example of the changing (or variable) nature of a variable:<br />

Datatyping 103


An Introduction To Programming With <strong>Processing</strong><br />

int x;<br />

//declaration<br />

x = 5; //assignment x is now 5<br />

x = x + x; //assignment expression x is now 10<br />

println(x); //Prints 10<br />

The value you assign to a variable can be changed when ever you instruct your<br />

program to do so, usually through use of the assignment operator. As a result in<br />

the previous example although we started off with the variable we called x having<br />

a value of 5 assigned to it in the second statement, in the next line we added it's<br />

current value of 5 to itself then reassigned that new value of 5 + 5 (on the right of<br />

the assignment operator) back to itself (on the left of the assignment operator),<br />

making x = 10. Using this simple method we have represented two different<br />

values of 5 and 10 with only one variable, x. That does not mean that x could be<br />

either 5 or 10 it simply means that at the start of the program x was 5 and by the<br />

end of the program x ended up being 10. By having one variable that can be used<br />

to represent many different values we can save on memory as at any given time<br />

that variable can only have one value associated with it, meaning that if a new<br />

value is assigned to it like in our previous example that new value will replace the<br />

old one and so on. Not only does this make our program run more efficiently but<br />

it also makes keeping track of the representations of the different data in your<br />

program more manageable.<br />

Variable Scope<br />

An important aspect of working with variables is that they can be accessed at<br />

various places in your program so that the values associated with them can be<br />

referenced (in their original form) or changed and then referenced. For example<br />

you can reference a variable in one statement, run a couple of other statements<br />

then choose to reference the original variable again even with all the code<br />

separating the the first reference from the second, <strong>Processing</strong> will still remember<br />

what the variable you are referring to is.<br />

But not every variable is accessible from every place within a program. Variable<br />

scope refers to the enclosing range within a program that a variable can be<br />

accessed. For example variables defined within the setup() function are not<br />

accessible to the rest of the program, which is why setup() is best suited for<br />

assignment in terms of dynamic programming. As such there is a scope in which<br />

variables can be defined such that they are accessible from every place within a<br />

sketch, we call this the global variable scope.<br />

Datatyping 104


An Introduction To Programming With <strong>Processing</strong><br />

Erroneous code is produced from a lack of considering variable scope<br />

As you can see in the previous image x cannot be accessed from within draw()<br />

because it has been initialized within the setup() function. Initialization is the<br />

process of combining variable declaration and assignment into one statement. For<br />

example the following declaration and assignment statements can be written as<br />

such:<br />

int x;<br />

x = 20;<br />

//declaration<br />

//assignment<br />

or the statements could be combined in one statement and written as such:<br />

int x = 20; //initialization is both declaration and assignment<br />

Although the latter statement might save you some time in terms of typing, it is<br />

something you should be careful of doing when taking variable scope into<br />

consideration, as when this method of initialization is used within setup() it is<br />

going to create variables that are not accessible (and therefore cannot be<br />

referenced) from outside of the setup() structure.<br />

The proper way to address this issue would be to declare the variable outside of<br />

both draw() and setup(). Generally it is not a good idea to declare a variable more<br />

than once because this could cause unnecessary overhead on your program, as<br />

such, declaring variables within the draw() structure is best avoided when ever<br />

possible. Nonetheless, declaring variables within the draw() structure sometimes<br />

cannot be avoided and as a result is considered to be valid code.<br />

Each time you use a datatyping keyword for variable declaration <strong>Processing</strong><br />

thinks you are trying to create a new variable, and does not perceive the statement<br />

as updating the already existing variable with the same name.<br />

Programming like this tends to look ambiguous and difficult to read. However, as<br />

already mentioned, there are times when declaring a variable within draw() is<br />

unavoidable, or in some cases can even contribute to the readability of your code.<br />

Datatyping 105


An Introduction To Programming With <strong>Processing</strong><br />

Basically, what this boils down to is that where you choose to declare your<br />

variables is your choice, but there are also certain rules in place that if you are<br />

aware of, can make this decision somewhat easier for you.<br />

Lets restructure the previous example using a more readable format that takes<br />

variable scope into consideration:<br />

int x;<br />

//declare variable only once in global<br />

//variable scope<br />

void setup(){<br />

//assign a starting value to the<br />

x = 20;<br />

//variable. Note: accessible within<br />

} //setup()structure<br />

void draw(){<br />

//access the variable from elsewhere in<br />

println(x);<br />

//the program. Note: also accessible<br />

} //within draw() structure<br />

By declaring a variable outside of the setup() and draw() functions we have<br />

created a global variable. A global variable can be accessed from both the setup()<br />

and draw() structures, it is said to have a greater scope than a variable that is<br />

defined within the setup() or draw() structures. Within setup() the variable has<br />

been given a starting value, remember that the variable already exists before the<br />

program reaches setup(), so setup() is not being used to create or declare the<br />

variable only for assignment. By the time the program gets to draw the new value<br />

associated with the variable is the value that the println() function reads each<br />

time it repeats. It's also worth noting again that only the code block within the<br />

draw() function is repeated.<br />

Interacting with images<br />

We're going to use what we've learned to have an image in a sketch react to our<br />

mouse's Y position, making the image move up and down accordingly. You might<br />

have seen this effect when viewing so called “high resolution” images that are<br />

larger than the window they are begin displayed in, in an online gallery.<br />

Locate the image named doorsClosed.png and drag it into your sketch. We can<br />

then start by rendering the image at the origin with the following code:<br />

//declare global variables<br />

Interacting with images 106


An Introduction To Programming With <strong>Processing</strong><br />

PImage doors;<br />

void setup(){<br />

//size() always first in setup<br />

size(800,600);<br />

//use setup() for assignment where ever possible<br />

doors = loadImage("doorsClosed.png");<br />

}<br />

void draw(){<br />

//draw the image<br />

image(doors,0, 0);<br />

}<br />

When loading images into an active mode sketch, it's important that you declare<br />

the images object variable name outside of both setup() and draw(). This makes<br />

the object accessible as a global variable so that it is now within the scope of both<br />

setup() and draw(), this is important because we will need to access the new<br />

object variable from within both structures. It is advisable to use assignment in<br />

the setup() structure so that the image is loaded into the new object variable only<br />

once, placing the loadImage() function, within an assignment statement, for the<br />

new object inside the setup() structure, ensures this.<br />

Finally once we have set the image up for rendering we can use the image()<br />

function, as usual, to display the image in the sketch. It's worth noting that<br />

because the image is static, it is not possible to see that the image is in fact being<br />

redrawn to the Display Window approximately 60 times per second, when the<br />

sketch is run and although this might sound like a lot of excessive usage of system<br />

resources, most modern day computers should be able to handle this framerate for<br />

one image with relative ease. However, we will take a look at how to reduce the<br />

amount of times <strong>Processing</strong> cycles through the draw() structure in second, when<br />

we use start using the frameRate() function, a little later.<br />

Making the image follow the mouse's Y position is actually quite easy, modify the<br />

image statement to read:<br />

image(doors, 0, mouseY);<br />

Now when you run the sketch your image will start to move up and down in the<br />

Interacting with images 107


An Introduction To Programming With <strong>Processing</strong><br />

Display Window because the value that the image() function is reading for it's Y<br />

parameter is the system variable mouseY. As you might recall mouseY stores the<br />

mouse's current Y position. If your mouse has moved the new position of your<br />

mouse's coordinate will replace the previous value that was stored in the mouseY<br />

system variable of the previous run-cycle, and as a result the image will be drawn<br />

in a new position.<br />

But why does the image appear to be streaking across the Display Window?<br />

Streaking<br />

The streaking effect<br />

We have told <strong>Processing</strong> to repeatedly draw the image by placing the image()<br />

function within the draw() structure, as a result the streaking effect is actually<br />

caused by the “ghosting” of the previous image having been drawn to the Display<br />

Window and not being erased before the image is redrawn in a new position for<br />

the current frame. To fix this effect we need to tell <strong>Processing</strong> to first clear the<br />

Display Window before drawing the image again in the current position. We can<br />

do this quite easily by adding the background() function before the image<br />

statement, thereby clearing the Display of the the image's previous rendering. Add<br />

the following statement before the image() statement in the draw() structure:<br />

background(0);<br />

Now when you run the sketch it should act in a more predictable fashion. I've<br />

chosen black as a background color but you can choose any color. There are<br />

however several areas that can be improved on,<br />

• firstly the way in which the image moves in relation to the mouse is not<br />

Interacting with images 108


An Introduction To Programming With <strong>Processing</strong><br />

very interesting to interact with. It would seem that the image appears to<br />

be stuck to the mouse.<br />

In order to fix this we will make the image lag slightly behind the mouse<br />

and then slowly catch up to the position of the mouse by creating a new<br />

variable that we can use to control the speed at which the image moves.<br />

This will create the impression of the image's movement being affected by<br />

friction.<br />

• Secondly because the image's origin is it's top left hand corner, when we<br />

move the mouse down we tend to expose the background above the image,<br />

so we'll also make the image react to the mouse's y position in relation to<br />

the center of the image and not it's top left hand corner. This reduces the<br />

possibility of exposing the background and makes the image more of a<br />

focal point.<br />

• Finally we will constrain how far the image can move along the Y axis so<br />

as to completely eliminate the possibility of exposing the background.<br />

Friction simulation<br />

Friction is the force that resists the relative motion of something else (like an<br />

object, a gas, a liquid, etc), and is the effect that we will be attempting to simulate<br />

(in a simplified form) in this sketch. By moving the mouse up and down within<br />

the Display Window the image should try to follow the mouse and slow down as<br />

it approaches the mouse, this will create the impression of friction.<br />

We'll start by creating three new variables. Add the following statements at the<br />

top of the sketch, below the PImage statement:<br />

float yPos;<br />

float difY;<br />

int frict = 30;<br />

//declaration related to image Y position<br />

//declaration related to difference between<br />

//mouse and image's Y position<br />

//initialization, friction. high values make<br />

//image move slower<br />

float is a keyword for declaring floating point variables. Floating point values are<br />

numbers that have a fractional part, that is to say they are numbers with a decimal<br />

value such as 1.0, -2.9865, 10000.423, 0.0000001 and so on. Floating point<br />

numbers will tend to require more memory for storage so if you can get away<br />

Interacting with images 109


An Introduction To Programming With <strong>Processing</strong><br />

with representing the number data as type int and not compromising the integrity<br />

of your program you should consider doing so.<br />

We are using the float datatype in this program because we will be using division<br />

in one of our expressions. This is important because true division will always<br />

return a number with a decimal value, if you were to use an int instead of a float<br />

or double depending on the programming language you are using, you risk having<br />

datatype conversion errors or truncated integers returned. As a result when you<br />

use division in your expressions always consider whether representing that data<br />

with an int is a good idea or not.<br />

The three variables yPos, difY and frict are going to be used to represent three<br />

different values of which only one will remain constant throughout the duration<br />

that the program is running. The only variable that will remain constant is the frict<br />

variable. As a result the frict variable has been initialized through a declaration<br />

and assignment statement outside of both setup() and draw() structures. This<br />

value will control how fast or slow we would like the image to move towards the<br />

mouse.<br />

Creating a variable such as this within the global variable scope, will give us<br />

access to the variable within both setup() and draw() thereby allowing us to tweak<br />

the value associated with the variable and have it update throughout the program.<br />

This will save us some unnecessary work in the long run. When the sketch is<br />

complete setting the frict value high will cause the image to appear to have more<br />

resistance when moving towards the position of the mouse ultimately making the<br />

image move slower, and setting this value low (but not to zero, because division<br />

by zero is not permitted in mathematics, as is the case in programming) will cause<br />

the image to appear to have no resistance and move almost immediately to the Y<br />

position of the mouse.<br />

The variable yPos will be used to store the Y position of the image and also<br />

update the Y position of the image, and the variable difY will be used to store the<br />

difference between the mouse's Y position and the center of the image's Y<br />

position. Both of these variables will need to be updated regularly for each of the<br />

cycles of the draw() function, this is because each time the user moves the mouse<br />

the position of the image must change as a result of difY now being less or more<br />

depending on whether the mouse is closer or further from the images center.<br />

Interacting with images 110


An Introduction To Programming With <strong>Processing</strong><br />

Variable naming conventions<br />

Before proceeding, it's worth noting the convention I've used for naming these<br />

variables. There are several rules (depending on what language you are<br />

programming in) that determine what a valid variable name is generally you'll<br />

find that many popular higher level languages share these similarities regarding<br />

valid variable declaration,<br />

1. Variable names can only contain alphanumeric characters and underscores<br />

(that is “_”, “a” to “z”, “A” to “Z” and/or “0” to “9”). Spaces cannot be<br />

used in variable names.<br />

2. Variable names cannot start with numbers.<br />

3. Variable names should be descriptive but not verbose, for example “yPos”<br />

as opposed to “Y_Position_Of_The_Image”.<br />

4. Use consistent casing. Variable names generally do not start with an<br />

upper-case character. This convention is reserved for Classes. In the<br />

previous example I've used a mixture of both upper-case and lower-case<br />

characters to name my variables such as yPos which is intended to be an<br />

abbreviation for “y Position” or difY which is an abbreviation for “the<br />

difference in Y positions”.<br />

Some programmers might use different conventions including underscores<br />

because to them this might look more readable y_pos or dif_y. Either of<br />

these conventions is perfectly valid. But you should determine which<br />

convention you are using, and stick with it throughout your program.<br />

Changing from one naming convention to another can often make a<br />

program confusing and less readable.<br />

5. Your variable names should be self documenting, that is to say they<br />

should be descriptive about their purpose without having to include<br />

additional comments explaining their purpose. This point is with the<br />

exception of intentionally, explicitly documented code, which is generally<br />

a convention used for teaching programming.<br />

6. Variables that are typed in all upper-case characters are often referred to<br />

as constants. Their value is not supposed to change. This is simply a<br />

naming convention and there is nothing stopping you from changing the<br />

value of a constant in many higher level languages, although this is not<br />

recommended. So beware when using this naming convention as it could<br />

lead to confusion if not used properly.<br />

Interacting with images 111


An Introduction To Programming With <strong>Processing</strong><br />

Planning and Pre-Debugging<br />

We'll start by making an assignment within the setup() structure that sets the yPos<br />

value to the center of the Display Window. This has not effected the position of<br />

the image yet, because we have not linked the yPos variable to the image yet. Add<br />

the following statement at the end of the setup() structure, before it's closed<br />

braces:<br />

yPos = height/2;<br />

If we wanted to make sure that yPos is returning the value we are expecting it to<br />

return then we could add a println() statement within the draw() structure to test it.<br />

The statement would look like this:<br />

println(yPos);<br />

If the program was run at this stage it should print a value that is representative of<br />

the center of the Display Window's height. Using this method of tracking<br />

variables is a common technique for debugging a program and provides an easy<br />

and convenient method of understanding how the program is changing and<br />

updating values internally. When you are happy that the program is returning the<br />

results you were expecting you can simply comment out the println() statement<br />

and resist deleting the statement until the program is fully completed, tested,<br />

documented and functional.<br />

In order to render the image at the correct position we need to:<br />

Determine what the Y position of the users mouse is (mouseY) and from this<br />

value subtract the sum of the Y position of the image (yPos) and half of it's height<br />

(doors.height/2). The latter value (yPos + doors.height/2) describes the position of<br />

the image with relation to it's center.<br />

Interacting with images 112


An Introduction To Programming With <strong>Processing</strong><br />

The image's movement will react to the mouse's relative position to the images center.<br />

Once we have the mouseY – (yPos + doors.height/2) value we will assign it to<br />

difY, then in the following statement we'll divide difY by the frict variable. This<br />

is important because we're then going to take that value (that is the answer of difY<br />

divided by frict) and add it to the yPos variable, meaning that if the value of difY<br />

was initially returned as 90 dividing it by frict would return a value of 3 (because<br />

90/30 = 3) which is subsequently the value that we add to the images current Y<br />

position to cause it to move down by a value of 3 (plus moves down the Y axis<br />

minus is moves up the Y axis). On the other hand if difY returned a value of -90,<br />

this would mean that the users mouse is above the center of the image and the<br />

value of -3 would be added to the images Y position causing the image to move<br />

up by 3.<br />

Interacting with images 113


An Introduction To Programming With <strong>Processing</strong><br />

As the mouse's Y position is less than the center of the image, the image is forced to<br />

move up.<br />

Then we're going to assign the sum of those values (yPos + difY/drag) back to the<br />

yPos variable.<br />

Finally we will use this value to determine the position that the image is currently<br />

rendered at.<br />

The results of this method is that the image will start moving fast towards the<br />

mouse then get slower as it approaches the mouse.<br />

Implementing a Programmatic Solution<br />

To summarize we are dividing the difference between the mouse's Y position and<br />

the center of the image with the frict value, then adding this value to the images<br />

current position. We can express this programmatically with the following two<br />

statements, which you can add to your sketch before the image statement:<br />

difY = mouseY - (yPos + doors.height/2);<br />

yPos += difY/drag;<br />

In the second statement we use a technique known as Augmented assignment<br />

Interacting with images 114


An Introduction To Programming With <strong>Processing</strong><br />

which is the process of condensing a statement that uses the common technique of<br />

using a variable in an expression, then assigning the value of the expression back<br />

to the same variable. For example the statement:<br />

x = x + 5;<br />

Can be expressed in augmented assignment form as:<br />

x+=5;<br />

Both statements evaluate to the same answer, the latter is a more commonly used<br />

method for this type of statement, as this kind of statement is so commonly<br />

implemented in programming. Some other examples of augmented assignment<br />

follow:<br />

x = x -5;<br />

//Can be expressed in augmented assignment form as:<br />

x-=5;<br />

x = x * 7;<br />

//Can be expressed in augmented assignment form as:<br />

x*=7;<br />

/= and %= can also be used in augmented assignment. As you can see the<br />

following statement used in our sketch is an example of augmented assignment:<br />

yPos += difY/drag;<br />

//Can also be expressed as:<br />

yPos = yPos + difY/drag;<br />

At this point if you were to run the sketch, your image still would not move in<br />

relation to the two statements you just added to your sketch. However if you were<br />

to add a println() statement for the yPos variable you would see the numbers<br />

indicating that the code is working. It's always a good idea to test an<br />

implementation before fully integrating it into your program when ever possible,<br />

with the println() function.<br />

In order to create a link between these two statements and the y position of the<br />

image we would need to place the variable yPos into the Y parameter field of the<br />

the image() function. However, if we where to do this our image would continue<br />

Interacting with images 115


An Introduction To Programming With <strong>Processing</strong><br />

to move beyond it's boundaries and display the sketches background. Fortunately<br />

we have a function in <strong>Processing</strong> that allows us to stop values from getting too<br />

high or too low.<br />

Constraining Values<br />

The constrain() function works by clamping a value between a range that you<br />

specify. It accepts three parameters, the first parameter is the value that you want<br />

to constrain and in our case this would be the variable yPos. The next parameter is<br />

the minimum value of the range you would like the value constrained between<br />

and the final parameter is the maximum value for the range that the value yPos<br />

will be constrained between.<br />

Modify the image() statement to match the following code fragment, and<br />

complete your sketch:<br />

image(doors,0, constrain(yPos, height- doors.height, 0));<br />

At first this statement could look a little intimidating, but in fact you already<br />

know what's going on in most of the statement and it's only the Y parameter of the<br />

image() function that is somewhat different.<br />

As you are aware the image() function accepts three parameters, firstly the object<br />

variable containing the image (doors), secondly the value of the X position you<br />

would like the image rendered at and finally the images Y position.<br />

This statement is in the draw() structure and as a result will be repeated<br />

throughout the program's run-cycle, this means that every time the user moves the<br />

mouse the difY variable will change and as a result so too will the yPos variable.<br />

It is therefore necessary for this statement to be within the draw() structure, or<br />

these changes will never be seen. The Y parameter of the image() function<br />

accepts an expression in this example, the expression consisting of the constrain()<br />

function:<br />

constrain(yPos, height - doors.height, 0)<br />

This expression when evaluated, returns the value of the image() function's Y<br />

parameter. The constrain() function clamps the yPos value so that the image is<br />

never raised above the value returned from height – doors.height and never<br />

Interacting with images 116


An Introduction To Programming With <strong>Processing</strong><br />

lowered below 0, this will be the point where the image's origin matches the<br />

Display Window's origin.<br />

The area which the image's motion is constrained to, exists above and outside of what is<br />

visible within the Display Window.<br />

Of course if you think this example could be easier to read, you're probably right.<br />

For example you could declare a global variable to which you assign the previous<br />

expression to within the draw() structure. The additional overhead that such an<br />

action would create in this example is minimal, for example:<br />

...<br />

float imageY;<br />

void setup(){<br />

...<br />

doors = loadImage("doorsClosed.png");<br />

...<br />

}<br />

void draw(){<br />

…<br />

imageY = constrain(yPos, height- doors.height, 0);<br />

image(doors,0, imageY);<br />

}<br />

However in order to demonstrate how expressions can be used as parameters in<br />

code, this example uses the former method which does not accommodate for the<br />

imageY variable. Nonetheless if you would like to see how this example can be<br />

implemented you can examine the comments in the imageScroll.pde file.<br />

Interacting with images 117


An Introduction To Programming With <strong>Processing</strong><br />

Branching<br />

When we write a program we generally don't want the script to do the same thing<br />

every time we use it. Often, what we want is a script that is versatile in it's<br />

application. Excluding this versatility would make the interactive software<br />

predictable and boring. We therefore use certain built-in structures that help us<br />

control the way in which our programs run, allowing us to skip blocks of code<br />

and execute other blocks of code before others in a non-linear way. This can be<br />

done in a dynamic and changing sequence based on the users input, the logic of<br />

the program, the time of day or whatever other characteristic we choose to model<br />

into a program. The process of creating this dynamic ordering that determines the<br />

programs flow of control is what is referred to as branching.<br />

Branching is also referred to as conditional programing and is the process of<br />

creating code that has the ability to choose a certain path based on a set of<br />

conditions stipulated in the program but which can also be influenced by<br />

conditions outside of the program, such as a user interaction. The conditional<br />

statement is syntactically a single statement made up of multiple branching<br />

statements. What determines the course of action that the program follows is a<br />

boolean value of true or false returned from a comparison within the structure of a<br />

conditional statement.<br />

The if() structure<br />

The if() structure can also be referred to as an if statement because although, the<br />

statement is in practice made up of multiple statements the structure of the if<br />

statement is treated like a single statement during compilation and/or<br />

interpretation.<br />

if statements must always have a conditional to qualify as an if statement. An<br />

example of the structure of an if statement follows:<br />

conditional<br />

if(expression1){<br />

… do statements<br />

}<br />

keyword<br />

if() statement<br />

structure<br />

Branching 118


An Introduction To Programming With <strong>Processing</strong><br />

Multiple if statements can be used within the same program and even within the<br />

same draw() structure. They are identified by the if keyword followed by<br />

parenthesis containing a conditional. The conditional for an if() statement will<br />

always return a value that is true or false through the process of evaluation which<br />

can be based on a comparison expression. We'll have a look at the process of<br />

comparison a bit later, for now we'll focus on the boolean datatype.<br />

Data that can either be true or false is a primitive datatype known as a boolean.<br />

Just like all primitive data types booleans can be declared with a keyword<br />

followed by a variable name.<br />

The expression within the conditional of an if() statement must, through the<br />

process of evaluation, return a boolean value of either true or false in <strong>Processing</strong>,<br />

in order for the program to continue. In other programming languages the<br />

conditional can also evaluate to a 1 or a 0, with 1 being representative of true and<br />

0 being representative of false. The language's compiler/interpreter will then<br />

convert the 0 or 1 to a boolean equivalent value through a process known as type<br />

casting., <strong>Processing</strong>, however, requires that the conditional evaluate to a boolean<br />

value of true or false, so that automatic type casting can be avoided. As you are<br />

aware 1 and 0 are of type int in <strong>Processing</strong> and the <strong>Processing</strong> does not<br />

automatically convert them to boolean values. In the event of your conditional<br />

evaluating to an int or datatype other than a boolean you will receive a “cannot<br />

convert” datatype error. Later we will have a look at how to use <strong>Processing</strong>'s inbuilt<br />

ability to prevent automatic type casting to our advantage. Although<br />

automatic type casting is favored in some programming languages it is usually an<br />

inherent legacy feature of a lower level language that a current higher level<br />

language is based on. In <strong>Processing</strong> type casting must be done explicitly with a<br />

type casting function.<br />

Type casting errors<br />

Branching 119


An Introduction To Programming With <strong>Processing</strong><br />

If we were to declare a boolean variable and use it in an if statement, it might look<br />

something like this:<br />

boolean myValue = true;<br />

//initialization<br />

if(myValue){<br />

//if conditional returns true<br />

… run these statements //statements within if() structure<br />

} //are run<br />

...then run these statements<br />

//if conditional is false entire if<br />

//structure is skipped<br />

In the previous example we have used initialization to declare a variable of type<br />

boolean and assign the value of true to it. We then used the new variable in an if()<br />

statement conditional (the part between parenthesis following the if keyword).<br />

The way that an if statement works is the program will evaluate the expression<br />

within the conditional, if the conditional evaluates to true the code delimited<br />

within the if() statements braces will be run. However if the conditional evaluates<br />

and a value of false is returned, it will skip the code within the if() statement's<br />

braces and proceed to the statements that follows, for example:<br />

boolean myValue = false;<br />

if(myValue){<br />

… don't run these statements<br />

}<br />

...run these statements<br />

//variable initialized to<br />

//false<br />

//conditional evaluates to<br />

//false<br />

//entire if() structure is<br />

//skipped<br />

Using this method of programming we have allowed our program to make a<br />

decision based on certain conditions, in a real world situation the conditions the<br />

program would evaluate would usually be dynamic for example a user interaction<br />

or some other dynamic feature.<br />

Branching 120


An Introduction To Programming With <strong>Processing</strong><br />

Relational Operators<br />

Writing if() statements becomes really interesting when more than one expression<br />

is used in the conditional. Up until now we have only used a single expression as<br />

a condition.<br />

Using a single expression within a conditional<br />

In the previous image the highlighted area indicates a single expression for the<br />

conditional in the form of a variable called myBooleanVar which has been<br />

datatyped as a boolean, in this case the variable has been assigned the value of<br />

true, therefore the conditional evaluates to true. This simplistic approach to using<br />

if statements can be useful in some situations but, the ability to use comparison<br />

within a conditional statement extends it's usefulness much further.<br />

Comparison<br />

A comparison requires at least two entities (which are most commonly numerical<br />

values and/or expressions in <strong>Processing</strong>, but can extend into strings in some other<br />

programming languages) and a relational operator (also known as a comparison<br />

operator in other programming languages). Comparisons included within a<br />

conditional, just like the previous expressions we've been working with, must also<br />

evaluate to a value of either true or false. Comparisons simply instruct the<br />

program to evaluate the two expressions on either side of the relational operator<br />

and compare the results of the two expressions with each other and from this<br />

comparison return a boolean of either true or false. Relational operators include:<br />

Branching 121


An Introduction To Programming With <strong>Processing</strong><br />

< less than<br />

> greater than<br />

== equality<br />

= is greater than or equal to<br />

!= inequality<br />

Let's have a look at how we can use the a relational operator to compare two<br />

values.<br />

(5>1)<br />

This is a conditional extracted from an if() statement, it consists of a single<br />

comparison. The comparison returns a value of true and would be read as “ five<br />

is greater than one”. The next example demonstrates a comparison that returns a<br />

value of false:<br />

(5


An Introduction To Programming With <strong>Processing</strong><br />

void setup() {<br />

size(300,300);<br />

}<br />

void draw() {<br />

if( mouseY >= height/2){<br />

println("Mouse is in the bottom half of the sketch");<br />

println(mouseY);<br />

}<br />

println("Mouse could be in either half");<br />

}<br />

The program starts, as always, by running the code within the setup() structure<br />

then moves onto draw(). Within draw() it runs the if() statement which instructs<br />

the program to check whether the mouse's Y position is greater than or equal to<br />

the height of the Display Window divided by 2. For example in our sketch the Y<br />

parameter of the size function within setup() is 300 so if the user has placed the<br />

mouse at a Y position that is anywhere between 150 and 300 then the conditional<br />

will return a value of true as these values are all greater than or equal to 150 (i.e.<br />

height/2). It's also worth noting that the relational operator that has been used in<br />

this comparison is the >= (greater than or equal to) operator, which means that the<br />

value that is returned on the right side of the operator is included within the range<br />

of values (as the minimum value in this range) that will cause the conditional to<br />

evaluate to true. What this means is that if you want a value of false returned the<br />

mouse must be within the range of 0 to 149.<br />

If the conditional returns a value of true meaning that the mouseY system variable<br />

has a current value of 150 or anything between 150 to 300, the program then runs<br />

the code delimited within the if() structure, which in this case tells <strong>Processing</strong> to<br />

print "Mouse is in the bottom half of the sketch" and then print the value of the<br />

mouseY system variable. The program then moves on to the rest of the code<br />

within the draw() structure. This tells the program to print "Mouse could be in<br />

either half", as this statement exists outside of the if() structure, it will be<br />

evaluated regardless of whether the if()'s conditional is returned as true or false.<br />

The program then loops back to the beginning of the draw() function and goes<br />

through the code within the draw() structure again as it has reached the end of the<br />

draw() structure at this point. If the users mouse is not within the bottom half of<br />

the Display Window this time the comparison conditional will return a value of<br />

false, the program will then skip the code delimited within the if() structure that<br />

tells it to print "Mouse is in the bottom half of the sketch" and move onto the rest<br />

Branching 123


An Introduction To Programming With <strong>Processing</strong><br />

of the code within the draw() structure that once again tells it to print "Mouse<br />

could be in either half".<br />

if() structures can increase the amount of options that can be programmed into a sketch.<br />

As you can see branching provides us with a very easy way of changing the<br />

behaviour of our program by including variables within a comparison that in<br />

themselves are dynamic.<br />

Extending the if() structure with else<br />

In our previous example, we where able to run statements based on whether the<br />

mouse was in the bottom half of the Display Window, if we change the<br />

conditional to read:<br />

(mouseY


An Introduction To Programming With <strong>Processing</strong><br />

of the Display Window and a different set of statements when the mouse is in the<br />

other half of the Display Window?<br />

Using an if statement to do this by itself would not be possible, but fortunately we<br />

can extend the if() structure with the else keyword.<br />

Use of the else keyword within an if() structure ensures that even if the<br />

conditional returns a value of false that the code that follows else (which is still<br />

within the if() structure) will be run, before the program exits the if() structure and<br />

moves on to the rest of the statements making up the program. This can<br />

effectively provide us with a fail safe method of ensuring that code is run within<br />

an if() structure before the program exits the structure. For example if we wanted<br />

to get our sketch to tell us whether the mouse is specifically in the upper or lower<br />

half of the Display Window we would modify the previous sketch to look like<br />

this:<br />

void setup() {<br />

size(300,300);<br />

}<br />

void draw() {<br />

if( mouseY >= height/2){<br />

println("Mouse is in the bottom half of the sketch");<br />

println(mouseY);<br />

}else{<br />

println("Mouse is in the upper half of the sketch");<br />

println(mouseY);<br />

}<br />

println("Mouse could be in either half");<br />

}<br />

Notice that as soon as you start the sketch and if your mouse is not hovering over<br />

the Display Window, <strong>Processing</strong> will read the mouseX and mouseY system<br />

variables as being 0 and 0. As a result the first branch of the if() structure is<br />

skipped because the conditional evaluates to false (0 is less than 150) and the<br />

second branch is immediately run, that being the else code block. Once you start<br />

moving your mouse around in the Display Window you will see the println()<br />

statements execute depending on which half of the Display Window the mouse is<br />

in.<br />

Branching 125


An Introduction To Programming With <strong>Processing</strong><br />

Extending the if() construct with if else if else<br />

There are many times when you will require more than the two branches that an if<br />

else construct will permit, and in that case you can use the process of nesting<br />

multiple if else structures within others. For example, in our previous sketch when<br />

our program started and our mouse was not hovering over the Display Window,<br />

<strong>Processing</strong> rightfully skipped the first if() control structure and went to the else<br />

structure. However we could capture this possibility in a condition and associate it<br />

with it's own code block. An if else if else construct generally follows this pattern:<br />

if(condition){<br />

...statements<br />

}else<br />

if(condition){<br />

..statements<br />

}else{<br />

...statements<br />

}<br />

As you can see nesting if else constructs within each other is pretty easy, but<br />

when typed in the previous format they can be a bit difficult to read. As a result<br />

they are generally written in the following format, remember that because<br />

<strong>Processing</strong> is a free form programming language you are free to format the<br />

statements as you wish, however certain formats might be easier to read than<br />

others, for example the traditional format for an if else if else construct follows:<br />

if (condition){<br />

...statements<br />

}else if(condition){<br />

...statements<br />

}else{<br />

...statements<br />

}<br />

There are no limits to how many if else structures you can nest within an if else<br />

construct, but bear in mind that nesting too many if else structures within others<br />

can make it difficult to follow and keep track of what is going on in your code.<br />

<strong>Processing</strong> and many other higher level languages have structures such as<br />

switch() that might serve your purposes better, if you want your program to be<br />

able to branch between a possibility of three or more control structures.<br />

Branching 126


An Introduction To Programming With <strong>Processing</strong><br />

Logical Operators<br />

Logical operators allow us to to extend our conditionals by creating a means of<br />

comparing one relational expression with another. They come in the format of:<br />

&& logical AND<br />

|| logical OR<br />

! logical NOT<br />

These operators can be used within a conditional to return a value of true or false<br />

based on the context in which they are used, for example logical AND will return<br />

a value of true only when both expressions on either side of it evaluates to true<br />

and can be used as in the following examples:<br />

(5>3 && 3>1) //Returned as True, because both<br />

//expressions are true<br />

(5>3 && 33 || 3>1) //Returned as True, because both<br />

//expressions are true<br />

(5>3 || 3


An Introduction To Programming With <strong>Processing</strong><br />

if (!(x>1))<br />

...<br />

//can also be expressed as,<br />

if (x


An Introduction To Programming With <strong>Processing</strong><br />

PImage img;<br />

PImage sliderBk;<br />

PImage sliderFd;<br />

int margin = 50;<br />

void setup(){<br />

size(800,600);<br />

img = loadImage("tunnel.png");<br />

sliderBk = loadImage("sliderBk.png");<br />

sliderFd = loadImage("sliderFd.png");<br />

}<br />

void draw(){<br />

background(0);<br />

image(img,0,0);<br />

image(sliderBk, width/2 – sliderBk.width/2, margin);<br />

image(sliderFd, width/2 – sliderBk.width/2, margin);<br />

}<br />

Starting a sketch in this way is enables us to see a template of the sketch, and<br />

provides us with foundation on which to build. After adding the previous code<br />

you should have a sketch that looks something like the following image.<br />

The template from which the sketch will evolve.<br />

Interface Controls: Setting up a Slider 129


An Introduction To Programming With <strong>Processing</strong><br />

User Defined Functions<br />

Now that we have a template we can start modifying it, to include some<br />

interactivity. One of the fundamental components of this sketch is the slider, as<br />

the whole idea of changing the color of an image is going to be based on the<br />

user's interaction with the slider. As a result we're going to start by setting up the<br />

button of the slider first. The kind of button we will be setting up in <strong>Processing</strong> is<br />

going to be determined by a range. This range will encompass the clickable area<br />

of the button, and because our button is part of a slider the range should<br />

automatically be able to adjust itself to accommodate for the button moving<br />

around the area that it can be dragged within by the user.<br />

Slider Button<br />

Area in which button can be dragged<br />

As detecting the location of the button is a fundamental requirement for this<br />

sketch and is something that needs to work throughout the duration that the sketch<br />

is running, we are going to create a user defined function that will take care of this<br />

requirement for us.<br />

Up until now we have been using <strong>Processing</strong>'s built-in functions, which can<br />

suffice for many different situations but you will occasionally come across a<br />

situation in programming when the language you are coding in does not provide<br />

the functionality you need built directly into it's API. This is not a reflection on<br />

the language's inability to perform in a certain situation, but rather an intentional<br />

quality built into a programming language's design where paradoxically it's<br />

limitations, in terms of built-in functionality, can actually extend the languages<br />

capabilities. What this means in terms of <strong>Processing</strong> is we have a set of functions<br />

already provided for us, these functions already have definitions associated with<br />

them, by creating user defined functions we take these predetermined functions<br />

and combine them into new forms of useful, reusable and compact code. This not<br />

only allows us to extend the languages capabilities into fields that perhaps even<br />

the developers of the language never imagined but also to create our own<br />

definitions which suite the specific needs of our own applications in a more<br />

practical sense.<br />

Perhaps at this point you are wondering why all programming languages do not<br />

User Defined Functions 130


An Introduction To Programming With <strong>Processing</strong><br />

share the same set of functions? Many useful, popular programming languages do<br />

in fact share many of the same functions we find in <strong>Processing</strong>, but might be<br />

referred to as directives, commands or subroutines amongst other terms<br />

depending on which language you are programming in. Besides the functions that<br />

are common amongst many different programming languages each programming<br />

language will have certain features (perhaps in the form of functions or some<br />

other built in feature) that will tailor that language to the environment it is best<br />

suited, as defined by it's developers and possibly extended in definition by a<br />

community, as is the case with <strong>Processing</strong>. This feature set that contributes<br />

significantly to defining the language's functionality, is intentionally maintained<br />

within the languages definition or philosophy as this makes the feature set easier<br />

to contextualize and thereby easier to learn for the programmer using the<br />

language, creates an abstraction of commonly used resources within an<br />

environment and can significantly improve the performance when a user's<br />

program is implemented. For example, if you wanted to write your own class for<br />

loading and displaying images within a <strong>Processing</strong> sketch, there is nothing<br />

stopping you from doing that, however the PImage class is maintained as a part of<br />

<strong>Processing</strong>'s feature set specifically for those reasons and as a result is optimized<br />

to run as efficiently as possible for the loading and displaying of images.<br />

Subsequently the possibility of you gaining any form of performance increase<br />

from creating your own class using <strong>Processing</strong>'s built-in functions to serve the<br />

same purpose as the PImage class is, unlikely. As a result it's worth considering<br />

whether writing your own class or user defined function is applicable or not<br />

before setting out to do so.<br />

In our case we are creating a user defined function because it will make our code<br />

easier to read and not reduce the performance of the application, as our function<br />

will contribute to making our program running more efficiently than having the<br />

function definition within the draw() structure causing the computer running the<br />

sketch to process the function definition line by line every time the draw()<br />

structure repeats. With a user defined function we can avoid this by loading the<br />

function's definition into memory and calling the definition with a simple function<br />

call, as we have been doing with built-in functions.<br />

As we are using <strong>Processing</strong>'s built-in functions, within the environment that they<br />

are intended for and best suited to, we will be enhancing the quality of our sketch<br />

with our user defined function rather than trying to work against the context that<br />

<strong>Processing</strong> is best suited.<br />

However, this is not to say that it is not possible to extend a programming<br />

User Defined Functions 131


An Introduction To Programming With <strong>Processing</strong><br />

language beyond the definition or philosophy of it's environment, but if that is<br />

your intention then you would more than likely consider abstracting a far greater<br />

degree of the languages built-in features within a library consisting of multiple<br />

classes.<br />

The definitions for user defined functions must exist outside of both setup() and<br />

draw() structures if they are to have a greater scope. Our function definition will<br />

reside at the bottom of the sketch and contain three main characteristics.<br />

1. Our function should always know whether the user's mouse is over the<br />

slider button or not.<br />

2. If the user's mouse is over the slider change the cursor to a hand icon<br />

indicating that the button is clickable to the user.<br />

3. Return a value of true or false to the main program, depending on whether<br />

the mouse is over the slider button or not.<br />

Although the process of creating a user defined function might seem new to you,<br />

it is in fact not really all that different to how we have been using the setup() and<br />

draw() function's structures. Bearing this in mind, our user defined functions are<br />

going to follow a very similar structure to that of setup() and draw(), for example<br />

expressed generically:<br />

datatype functionName(){<br />

...function definition<br />

}<br />

Then within the context of draw():<br />

void draw(){<br />

..statements defining draw() structure<br />

}<br />

Now as a user defined function, applicable to our sketch:<br />

boolean myFunction(){<br />

...statements defining myFunction<br />

}<br />

As you can see, not a lot has changed in terms of how a user defined function is<br />

structured in comparison to the previous example using draw(). The fundamental<br />

User Defined Functions 132


An Introduction To Programming With <strong>Processing</strong><br />

difference is that statements delimited within the braces associated with draw()<br />

define it's structure and not the function, as the definition of the draw() function<br />

exists outside of the sketch we are creating and is something that the developers<br />

of <strong>Processing</strong> have determined. In contrast statements delimited within a user<br />

defined function form a function definition, within it's braces.<br />

In order to use the function we will then need to include a call to the function<br />

from within our main program. This is very similar to the method used to call<br />

built-in functions such as rect(), ellipse(), println() and many other functions we<br />

have already used.<br />

Let's revise our previous example to demonstrate the process of defining a<br />

function then calling it from within the draw() structure:<br />

void setup(){<br />

...statements<br />

}<br />

void draw(){<br />

...statements<br />

myFunction();<br />

}<br />

boolean myFunction(){<br />

...statements defining myFunction<br />

}<br />

From this example you can see that a call to a user defined function is as simple<br />

as a call to a built-in function. This has the added benefits of making the code<br />

easier to read and removes the function definition from the body of the draw()<br />

structure. Now we can reuse the function as many times as we would like within<br />

our main program by simply evoking it via it's name, compare this to typing out<br />

every statement within it's definition in the main program every time we wanted<br />

to instruct the program to do what the user defined function does.<br />

Now that we have an understanding of how the function will fit into the program,<br />

lets have a look at creating it's definition.<br />

User Defined Functions 133


An Introduction To Programming With <strong>Processing</strong><br />

Creating a user defined function<br />

Datatyping a function<br />

The first line of a function definition must be used to declare the function, and as<br />

you are aware declaration in <strong>Processing</strong> means giving the function (variable or<br />

other entity) a name and datatyping it. Naming a function is a very similar process<br />

to that of naming a variable as you will see in the following code fragment<br />

forming the first line of our user defined function:<br />

boolean overButton()<br />

The parenthesis following the function name are used to contain declarative<br />

parameters. These parameters will be defined within the function body, in our<br />

case this function does not accept any parameters so we leave the parenthesis<br />

empty. As you have been using functions that accept parameters user defined<br />

function can also be created to accept parameters that you define.<br />

In comparison to setup() or draw() our function is being datatyped as a boolean,<br />

all functions must return a datatype or use the void keyword like setup() and<br />

draw(). As void does not return any data it is subsequently not classed as a<br />

datatype within <strong>Processing</strong> (and traditionally in C/C++) but as a structural<br />

element, this differs to other higher level languages (some of which are closely<br />

tied to <strong>Processing</strong>) that do consider void as a datatype. Nonetheless our function<br />

is going to return data of type boolean, which will be used to determine whether<br />

the user's mouse is over the slider button or not.<br />

Determining a range<br />

In order to calculate whether the mouse is over the slider button or not we will<br />

have to determine the range in which the slider button is located. We already<br />

know where the slider button is in terms of x and y because these are values<br />

determined by parameters if the image() function used to draw the image. We can<br />

use this information, along with the width and height object variables to work out<br />

the slider button's range.<br />

User Defined Functions 134


An Introduction To Programming With <strong>Processing</strong><br />

Determining the range of the button as the area covered in diagonal stripes.<br />

In the previous image if A and B where variables the image() function to render<br />

the slider button could be rewritten as:<br />

image(sliderFd, A, B);<br />

This method of expressing the X and Y parameters as variables is particularly<br />

useful to us because, we would like the slider button to be able to “slide” along<br />

the x axis, this means the value of A would need to be dynamic.<br />

As the slider button only moves along the x axis the variable B will not change,<br />

however this value is used in more than one situation, firstly to determine the Y<br />

position of the image that will form the area along which the slider button can be<br />

dragged referred to as sliderBk (short for slider background), secondly to<br />

determine the Y position of the slider button referred to as sliderFd (short for<br />

slider foreground) and thirdly referenced within the range we will set up shortly to<br />

determine the clickable area of the button. As a result this value has been declared<br />

as a variable of type int and named margin. This way if at a later stage we decide<br />

to move the entire slider down in order to make room for other graphical elements<br />

above it then all I have to do is update the value associated with margin, instead<br />

of having to find and change an explicit value scattered throughout the source<br />

code.<br />

The value described as A in the previous image requires a more meaningful name,<br />

something that is self documenting. As a result I have created the variable<br />

buttonXPos in the global region and datatyped it as an int:<br />

int buttonXPos;<br />

Eventually I'd like to replace the X parameter for the image() function rendering<br />

sliderFd in the X position determined by buttonXPos. As we are aware what the<br />

variable buttonXPos is going to represent we're going to set it up with a<br />

User Defined Functions 135


An Introduction To Programming With <strong>Processing</strong><br />

temporary value within our sketch to test our user defined function. So we're<br />

going to add a temporary statement for testing and debugging purposes to the<br />

draw() function which assigns a value to buttonXPos and then changes the<br />

image() function of which sliderFd is associated with to reflect this assignment<br />

statement. Once the buttonXPos variable is declared in global space, you can edit<br />

the draw() structure to include the first command and update the appropriate<br />

image command:<br />

...<br />

//temp for debugging<br />

buttonXPos = width/2 - sliderBk.width/2;<br />

...<br />

image(sliderFd,buttonXPos ,margin);<br />

Once we are sure that our function is working we will return to the temporary<br />

statement that we adding for debugging and testing purposes and include the<br />

buttonXPos variable assignment statement within an if() structure.<br />

We are now ready to proceed with setting up our function. To briefly recap our<br />

function has been declared as type boolean and given the name overButton(),<br />

setting up the range will occur within a conditional consisting of multiple<br />

comparisons and will look like this:<br />

boolean overButton(){<br />

if (mouseX >= buttonXPos && mouseX = margin && mouseY


An Introduction To Programming With <strong>Processing</strong><br />

1. mouseX >= buttonXPos, this checks if the mouse is anywhere in the<br />

highlighted area. If the mouse is then a value of true is returned and<br />

<strong>Processing</strong> will continue to evaluate the rest of the conditional.<br />

2. mouseX


An Introduction To Programming With <strong>Processing</strong><br />

3. mouseY >= margin, once again this comparison is only evaluated if the<br />

previous comparison was true because both comparisons are separated<br />

with &&. This comparison returns a value of true only if the mouse is<br />

below the top of the slider button.<br />

4. mouseY


An Introduction To Programming With <strong>Processing</strong><br />

let us know that when the value returned from the function is true that the mouse<br />

is over the button and when the value is returned as false we can safely conclude<br />

from this information that the mouse is not hovering over the button.<br />

First we are going to declare another variable in the global scope and datatype it<br />

as a boolean, add the following variable to the global space of your sketch:<br />

boolean mouseOverButton;<br />

Now we'll use this variable in our user defined function to return a boolean back<br />

to the main program.<br />

boolean overButton(){<br />

if (mouseX >= buttonXPos && mouseX = margin && mouseY


An Introduction To Programming With <strong>Processing</strong><br />

datatype if it is datatyped, meaning that in our case when the mouse is not over<br />

the slider button and we did not have an else structure capturing this possibility at<br />

that point our function would not be returning any data back to the main program.<br />

This is why it is important that we add an else structure to this if() construct, so<br />

that we can set the mouseOverButton variable to false, and subsequently return he<br />

correct data back to the main program. This also gives us an opportunity to<br />

change the cursor back to an arrow, indicating to the user that their mouse is no<br />

longer over a clickable element.<br />

Our function declaration and definition is now complete and we can use it in our<br />

main program. Calls to user defined functions are as easy as calls to <strong>Processing</strong>'s<br />

API functions. Add the following statement to the draw() structure.<br />

overButton();<br />

Now <strong>Processing</strong> will run the function at every frame and set the<br />

mouseOverButton variable within the overButton() function to true or false<br />

appropriately, update the cursor and return the correct value datatyped back to our<br />

main program, which we will soon put to use.<br />

Dragging the slider button<br />

mouseDragged() is a function that provides a structure to which we can add<br />

statements each time the mouse is dragged. A dragging operation qualifies as a<br />

user clicking and dragging a mouse button anywhere in the Display Window,<br />

when this happens the mouseDragged() function will be called once, and it's<br />

structure will be executed. As a result because the mouseDragged() function is not<br />

called repeatedly for each frame that the mouse is begin dragged, we will use the<br />

function to set a variable called buttonDrag to true indicating that the mouse is<br />

currently being dragged, this variable will then be used in the draw() structure,<br />

within an if() statement which causes the slider button to follow the mouse when<br />

the variable is true and remain stationary when it is false. When the user then<br />

releases the mouse we will use a call to the mouseReleased() function (which<br />

structurally works in a similar way to the mouseDragged() function) to set the<br />

variable, buttonDrag to false within the mouseReleased() structure. What this<br />

means is that when the if() statement in draw() checks the status of this variable it<br />

User Defined Functions 140


An Introduction To Programming With <strong>Processing</strong><br />

will now be returned as false causing the slider button to remain stationary. In<br />

other words, we already have a function that tells us if the mouse is over the<br />

button or not, we will now add two more functions that will tell us whether the<br />

user's mouse is attempting to drag the button and whether it has been released.<br />

Mouse related functions usually follow the end of the draw() structure and should<br />

not be mixed amongst user defined functions.<br />

We'll start by declaring the buttonDrag boolean in global space:<br />

boolean buttonDrag;<br />

Then using it within a mouseDragged() function, remember to place all mouse<br />

related functions together and not between user defined functions:<br />

void mouseDragged(){<br />

if (mouseOverButton){<br />

buttonDrag = true;<br />

}<br />

}<br />

This simple function is run once the user clicks a mouse button and starts to drag,<br />

then the function will check if the mouse is over the slider button as<br />

mouseOverButton is returned to our main program via our overButton() user<br />

defined function. If the mouse is over the slider button and the user has clicked<br />

and dragged in the Display Window, then we can safely conclude that the user is<br />

trying to click and drag the slider button. As a result we set the buttonDrag<br />

variable to true. Now we can use this variable in our main program to update the<br />

position of the button slider in the draw() structure.<br />

Firstly we will start by commenting out the following statement as it is no longer<br />

needed for testing, as we are ready to implement the actual code:<br />

//temp<br />

//buttonXPos = width/2 – sliderBk.width/2;<br />

The following statement will replace it:<br />

if(buttonDrag){<br />

buttonXPos = mouseX - sliderFd.width/2;<br />

}<br />

User Defined Functions 141


An Introduction To Programming With <strong>Processing</strong><br />

This if() statement will form the basis of the construct used to control the<br />

movement of the slider button. If you were to run the script at this stage you 'd<br />

notice that although you can now click and drag the button, there are a few new<br />

issues that need tending to:<br />

1. The slider button now starts at the 0 x position, and subsequently needs to<br />

be constrained to the region that the sliderBd object covers.<br />

2. When the button is dragged it can be dragged well beyond the sliderBd<br />

region, so this operation also requires constraints.<br />

3. Once the button is released it continues to follow the mouse.<br />

Setting up regional constraints<br />

As we have seen from previous examples the constrain() function can be used to<br />

setup a maximum and minimum value that can be used to determine the limits of<br />

another value. This provides a convenient solution for working with the<br />

buttonXPos value of which we'd like it's minimum value mapped to the left edge<br />

of the sliderBd object and it's maximum value mapped to the right edge of the<br />

sliderBd object minus the width of the slider button (sliderFd). We need to minus<br />

the width of the slider button (sliderFd) because the top left hand corner of the<br />

slider button image is the point that will be able to move the the maximum value<br />

specified in the constrain() function, as a result of using the default setting for<br />

imageMode() which is CORNER. If this point was matched to the right edge of<br />

sliderBd the results would look like the following image:<br />

sliderBd.width<br />

SliderFd CORNER<br />

The slider button is dragged too far right<br />

As you can see the slider button has gone too far past the right edge of the<br />

sliderBd image, subtracting the sliderFd's width from the right edge of sliderBd<br />

will solve this.<br />

User Defined Functions 142


An Introduction To Programming With <strong>Processing</strong><br />

Modify the if() statement to include the following if else clause:<br />

else{<br />

buttonXPos = constrain(buttonXPos, width/2 -<br />

sliderBk.width/2, width/2 + sliderBk.width/2 -<br />

sliderFd.width);<br />

}<br />

The minimum value for the constrain() function is the center of the Display<br />

Window minus half of the width of the slider background image (sliderBd).<br />

The maximum value for the constrain function is the center of the Display<br />

Window plus half of the width of the slider background image (sliderBd) minus<br />

sliderFd's width.<br />

The values that will be used in the constrain() function to determine the slider button's<br />

draggable area<br />

With this information in mind finishing the if() construct is just a matter of copy<br />

and paste with one minor modification. Although the modification is minor it's<br />

addition to the sketch will be what finally gives the user the results they were<br />

looking for. The value we are constraining in this case is going to be mouseX.<br />

The following if construct demonstrates this:<br />

User Defined Functions 143


An Introduction To Programming With <strong>Processing</strong><br />

if(buttonDrag){<br />

buttonXPos = constrain(mouseX - sliderFd.width/2, width/2 -<br />

sliderBk.width/2, width/2 + sliderBk.width/2 -<br />

sliderFd.width);<br />

}else{<br />

buttonXPos = constrain(buttonXPos, width/2 -<br />

sliderBk.width/2, width/2 + sliderBk.width/2 -<br />

sliderFd.width);<br />

}<br />

Finishing the slider<br />

The Third issue with the slider is to get it to stop dragging once the mouse has<br />

been released. For this we're going to use the mouseReleased() function. The<br />

mouseReleased() function should be placed directly below the mouseDragged()<br />

function for the purpose of readability. However to <strong>Processing</strong> it does not make a<br />

difference if the function is before or after mouseDragged(). The<br />

mouseReleased() function is pretty simple, all it does is run the function once<br />

every time the mouse button is released in the Display Window. In our case the<br />

function will check if buttonDrag is set to true, if it is then we can be sure that the<br />

slider button is being dragged. As the function is run when the mouse has been<br />

released, we can be certain that the user no longer wants to drag the button, as a<br />

result the function then sets the buttonDrag variable back to false. This means that<br />

the conditional using this variable in the draw() structure will evaluate to false, so<br />

that mouseX will no longer be used to determine the value of buttonXPos. The<br />

mouseReleased() function should look like the following code listing:<br />

void mouseReleased(){<br />

if(buttonDrag){<br />

buttonDrag = false;<br />

}<br />

}<br />

Mapping Values<br />

Now that we have the slider moving correctly we can use the values of<br />

buttonXPos and map them to any values that we choose, for example we cold<br />

User Defined Functions 144


An Introduction To Programming With <strong>Processing</strong><br />

map the range of values that buttonXPos returns to the amount we would like an<br />

image to scale on it's x axis, how far or fast an image moves across the screen, or<br />

just about anything that can accept a range of values as an input. We're going to<br />

map the buttonXPos range to the tint of an image, making the image appear to<br />

fade in from black. Mapping one range of values to another is done with the<br />

map() function. The map() function accepts parameters in the following format:<br />

map(mValue, oldLow, oldHigh, newLow, newHigh);<br />

The parameter mValue is the value that you will be mapping to the new range, in<br />

our case this is buttonXPos. The parameters oldLow and oldHigh are the<br />

minimum and maximum values of the range you would like to map to the new<br />

range, in other words these values are the furtherest left we can drag the slider<br />

button (oldLow) or expressed within the context of our program:<br />

width/2 - sliderBk.width/2<br />

The oldHigh value is the maximum value of the original range, and in the context<br />

of our program:<br />

width/2 + sliderBk.width/2 – sliderFd.width<br />

You might have noticed, by now that these two values are the exact expressions<br />

we used to determine the minimum and maximum values for the constrain()<br />

function assigned to buttonXPos, this is no coincidence. These two values<br />

determined the maximum range of the sliders movement and this is the exact<br />

range we are mapping to a new range. The new range will be represented by the<br />

two parameters newLow and newHigh and in our case these are two simple<br />

numbers 0 and 255 respectively. As we are mapping the slider button's movement<br />

to the tinting of an image via the tint() function we will be using the single value<br />

that is returned from the map() function which will be between the newLow and<br />

newHigh parameters in order to create the impression of the image fading in. In<br />

the context of the actual values, 0 to 255 represent the range of values that the<br />

tint() function uses to tint the image with various levels of gray. For example the<br />

value 0 has the effect of making an image appear as fully gray (or black) and 255<br />

has the effect of making an image appear with no gray and no black tint.<br />

With the slider button's values converted to the correct range of values, all that is<br />

left to do is link the new values to the image. In order to do this we will start by<br />

User Defined Functions 145


An Introduction To Programming With <strong>Processing</strong><br />

declaring a new variable in the global scope. Add the following variable to your<br />

sketch:<br />

float imgTint;<br />

As you can see this variable is datatyped as float, this is because the map()<br />

function returns floats. Remember that this does not mean that the parameters<br />

themselves have to be floats, nonetheless it is worth noting that in order to<br />

perform true division if the parameters you supply <strong>Processing</strong> with for the map()<br />

function are of type int <strong>Processing</strong> will typecast them to floats for the purpose of<br />

the map() function. What this means is that once those values have been evaluated<br />

by the map() function, the answer will be returned as a float. Since this is the<br />

variable that we will assign the return value of the map() function to, and as just<br />

stated this value will be a float it makes sense to datatype this variable as a float.<br />

If we try to use another datatype, such as an int, we will get a “type miss-match”<br />

error.<br />

With our new variable, imgTint, we will use assignment in the if() construct we<br />

created earlier within the draw() function, to determine it's value as the slider is<br />

dragged. Add the following statement to the if() construct, directly under the<br />

assignment statement for buttonXPos:<br />

imgTint = map(buttonXPos, width/2 - sliderBk.width/2, width/2 +<br />

sliderBk.width/2 - sliderFd.width, 0, 255);<br />

In the previous statement we use the map() function to determine the value of the<br />

imgTint variable. Now that we have a place to store this value we can associate it<br />

with the tint() function. Which we will do before the image() function to render<br />

img. We do this by adding the following statement:<br />

tint(imgTint);<br />

This statement must precede the statement telling <strong>Processing</strong> to render the img<br />

object. If you were to run the sketch at this point you might notice that everything<br />

is working, but not quite as expected. The answer to this problem is order. If you<br />

look at the current sketch it runs like so.<br />

User Defined Functions 146


An Introduction To Programming With <strong>Processing</strong><br />

draw()<br />

If the slider button is being dragged<br />

Update variables<br />

Else leave everything as it is<br />

render the images<br />

end draw()<br />

Although this method might be somewhat functional, it's not very intuitive. What<br />

this means is that when the user drags the slider the user should be able to see the<br />

results of their actions in realtime (another way of saying immediately or<br />

something very close to that) and when the user releases the mouse button, the<br />

values should stay as the user set them and not jump around to seemingly<br />

incorrect values. As a result we need to make sure that the images are being<br />

rendered for all possible situations using the correct values, which in our case is<br />

only two different branches. So we are going to restructure our code to<br />

accommodate for a more intuitively designed interface.<br />

draw()<br />

end draw()<br />

If the slider button is being dragged<br />

Update variables<br />

render the images<br />

Else leave everything as it is<br />

render the images<br />

How this new structure is implemented in our program will follow this pattern:<br />

buttonXPos<br />

imgTint<br />

tint()<br />

img<br />

noTint()<br />

//update variable<br />

//update variable<br />

//set the tint value<br />

//render main image now effected by tint<br />

//Turn tint off so slider images are not<br />

User Defined Functions 147


An Introduction To Programming With <strong>Processing</strong><br />

sliderBk<br />

sliderFd<br />

//effected by it<br />

//render slider background image<br />

//render slider button image<br />

This is the order within the first code block of the if else construct the second<br />

code block will follow the same order. For a full listing of the code it's best to<br />

look at the sketch itself which is<br />

named slider.pde. Finally to end off the example I've added another image to the<br />

sketch which I've associated with the object I've called star and mapped it's Y<br />

movement to the slider. Like I said the mapping of one value with a range to<br />

another range can lead to in infinite array of possibilities, and is largely the<br />

premise on which more complex applications are built upon. Why not try your<br />

own custom mappings you'll soon come to realize that with this simple function,<br />

the sky is definitely not the limit.<br />

The final slider.pde sketch<br />

The mystery shape maker<br />

In this next sketch we will discover two new fundamental programming concepts<br />

arrays and iterations, learn how to work with random numbers and try out a new<br />

datatype called color. The mystery shape maker is a sketch that allows the user to<br />

make several clicks in the Display Window, and by capturing and storing the<br />

The mystery shape maker 148


An Introduction To Programming With <strong>Processing</strong><br />

coordinates of each click constructs a new shape for the user in a randomly<br />

generated color. The shapes can be as simple or complex as you want, as you<br />

determine how many times the user gets to click in the Display Window before<br />

the mystery shape is drawn.<br />

Arrays<br />

Some of the shapes that can be created with the mystery shape maker<br />

Arrays are used to store data, but unlike the other data storage types we have been<br />

using (such as variables) arrays have the ability to store more than just a single<br />

value. Arrays can store multiple values of the same datatype in much the same<br />

way that an ordinary list (such as a grocery list) consists of multiple elements<br />

related to the topic of the list. In fact, this analogy is so true to the nature of arrays<br />

that every component making up an array is referred to as an element. This<br />

analogy can be extended ever further, as with a list each element in that list can<br />

have a number associated with it, in an array each element has a number<br />

associated with it too. We refer to these numbers as indices (in plural) or simply<br />

an index number in singular form.<br />

An everyday list:<br />

My Shopping List //name of the list<br />

1. Tea //element1<br />

2. Soy Milk //element2<br />

3. Vegan Cookie //element3<br />

Arrays 149


An Introduction To Programming With <strong>Processing</strong><br />

An Array<br />

int[] myArray = {20, 30, 40};<br />

//name of array is myArray[] and it is datatyped as an int, so it<br />

//can store integer values<br />

//element 1 is 20, and has an index value of 0<br />

//element 2 is 30, and has an index value of 1<br />

//element 3 is 40, and has an index value of 2<br />

Index values for arrays start at 0 and can go as high as the number of elements in<br />

an array minus 1, for example if an array has 15 elements, the index value of the<br />

last element in the array is 14.<br />

Element No. 1<br />

has an index<br />

value of 0<br />

Element No.3<br />

has an index<br />

value of 2<br />

int[] myArray = {20, 30, 40};<br />

Element No.2<br />

has an index<br />

value of 1<br />

Understandably at first this system of numbering might seem a bit strange, so in<br />

order to simplify things you can think of an index number as a means of referring<br />

to an element within an array without having to know what it's value is. This<br />

concept should not be new to you as it does not differentiate very much from that<br />

which defines a variable, the main difference being that instead of using a<br />

variable name we are now using an index number within an array to reference that<br />

specific value. The syntax for referencing an element within an array follows:<br />

int[] myArray = {20, 30, 40}; //initialize array<br />

myArray[0];<br />

//reference array element with<br />

//index number 0, which has a value<br />

//of 20.<br />

We can also use an array in a program in a similar way that we would use a<br />

variable, for example:<br />

Arrays 150


An Introduction To Programming With <strong>Processing</strong><br />

Index Number 0 1 2<br />

int[] myArray = {20, 30, 40}; //initialize array<br />

int x = myArray[0] + myArray[2]; //sets x to 20 + 40 i.e. 60<br />

Using an array in this format can be very similar to the way in which variables are<br />

used, and the comparison can extend further than the previous expressional<br />

example into initialization and assignment. As you can see in the previous<br />

example the array was initialized through both declaration and assignment in one<br />

statement in a similar way that variables use initialization.<br />

As arrays have multiple elements assigning values to the elements of an array<br />

cannot be through a simple reference to the arrays name, as <strong>Processing</strong> would not<br />

know which element is to inherit the value on the right of the assignment<br />

operator. As a result the process of assigning values to elements of an array after<br />

declaration or initialization must also include the index number of the element<br />

you wish to assign a value to, on the left hand side of the assignment operator. For<br />

example:<br />

int[] myArray = {20, 30, 40}; //initialize array<br />

myArray[2] = 10;<br />

//element 3 was 40 now has a value<br />

//of 10<br />

With all the similarities between variables and array elements you might be<br />

wondering what the purpose of an array is? Unlike variables storing one value<br />

followed by another value of the same type within the same variable, the array<br />

does not have to replace the previous value in order to store a new value. For<br />

example, what if I wanted to store the x position of the mouse when the user<br />

clicks in the Display Window. This would be easy enough, I'd just create a<br />

variable and assign it the value of the mouseX system variable. This is fine if all I<br />

need to know is the current x position of the mouse when the user clicks.<br />

However, what if I need to know the previous x coordinate of the mouse, or the<br />

one before that and so on. Retrieving this information with a simple variable<br />

would not be possible because each time the user clicks the mouse the current<br />

value of mouseX replaces the previous value.<br />

Arrays 151


An Introduction To Programming With <strong>Processing</strong><br />

int mXPos;<br />

if(userClicked){<br />

mXPos = mouseX;<br />

}<br />

//declare variable to store mouse x<br />

//position<br />

//hypothetical conditional to test if<br />

//user has clicked<br />

//sets variable to current X position of<br />

//mouse<br />

//user moves the mouse around and clicks again<br />

if(userClicked){<br />

mXPos = mouseX;<br />

}<br />

//hypothetical conditional repeats to<br />

//test if user has clicked<br />

//replaces the previous value for mXPos<br />

//with the new X position of the mouse,<br />

//and the previous value of mXPos can no<br />

//longer be retrieved.<br />

With arrays this information becomes accessible to us. By using the elements of<br />

an array we can store the first x coordinate of the mouse at index 0, the second<br />

coordinate at index 1 and so on. Lets have a look at an example of this in a sketch.<br />

int[] myArray = new int[4];<br />

int clicks;<br />

void draw() {<br />

}<br />

void mouseClicked(){<br />

if(clicks


An Introduction To Programming With <strong>Processing</strong><br />

}<br />

println(myArray[2]);<br />

println(myArray[3]);<br />

clicks++;<br />

}<br />

//print the value of the<br />

//third x coordinate<br />

//print the value of the last<br />

//x coordinate<br />

//increment the click value<br />

//by 1<br />

Program Notes<br />

In the first line of the sketch we declare an array with four elements. When using<br />

this technique to create a new array we must indicate the datatype of the array and<br />

use brackets[] to tell <strong>Processing</strong> that we are about to create an array (and not just<br />

simply declare a variable). We must then name the array and use the assignment<br />

operator to populate the array with the new elements (which do not have values<br />

assigned to them as of yet). We do this by use of the new keyword, followed by<br />

the datatype of the new elements which must match the array's datatype and<br />

finally, brackets indicating how many of these new elements will populate the<br />

array.<br />

int[] myArray = new int[4];<br />

Next the variable clicks is declared, this variable will be used to count how many<br />

times the user has clicked in the Display Window. The draw() function is then<br />

initiated in order to keep the program running, and prevent the sketch from<br />

turning to static mode.<br />

The mouseClicked() function consists of a simple if() statement. The conditional<br />

of the if() statement is executed when the user clicks a mouse button within the<br />

Display Window. The conditional checks if the clicks variable is less than four,<br />

which is the amount of elements in the array. If this is the first time the mouse has<br />

been clicked, clicks will equal a value of 0 as it has not been assigned a value<br />

through initialization, it has only been declared. As a result the following<br />

statement is run:<br />

myArray[clicks] = mouseX;<br />

Arrays 153


An Introduction To Programming With <strong>Processing</strong><br />

This is the statement that assigns a value to each element in the array. If this is the<br />

first time clicks has been used in the comparison it will also be the first time the<br />

user has clicked in the Display Window and therefore clicks will have a value of<br />

0, as a result the preceding statement can be translated and explicitly expressed<br />

as:<br />

myArray[0] = mouseX;<br />

This means the element with the index number 0 is assigned the value of<br />

whatever the mouse's x coordinate was at the time the user clicked a mouse<br />

button. The next four println() statements print the value of each of the four<br />

elements in the array. As only the first element has a value at this point in time, it<br />

will be the only element that is non-zero until the user clicks again (up to three<br />

more times).<br />

clicks++;<br />

In a similar way that we used augmented assignment to shorten an expression that<br />

is commonly used in programming, we have used an increment operator in the<br />

previous example to shorten this statement. The increment operator works by<br />

adding 1 to the current value of the particular variable it is used with, then<br />

assigning this new value back to the original variable. This is a common method<br />

of getting a program to count for you as each time the variable is used with the<br />

increment operator it will return a value that is one more than it's previous value.<br />

Writing this statement without the increment operator would look like this:<br />

clicks = clicks + 1;<br />

As you can see using an increment operator can make your code easier to read<br />

and save you some keystrokes.<br />

The decrement operator (which is two minus signs --) works in a similar way to<br />

the increment operator except that it subtracts 1 from the variable's current value<br />

before reassigning the new value back to the original variable.<br />

The result of this statement is that the clicks variable will now be one more than<br />

it's previous value by the time the program repeats. For example the clicks<br />

variable was initially 0, but at the end of the if() statement the clicks variable will<br />

have a value of 1. This is important because the next time the user clicks a mouse<br />

Arrays 154


An Introduction To Programming With <strong>Processing</strong><br />

button the comparison will be working with different values. For example on the<br />

first click the comparison can be expressed as (0


An Introduction To Programming With <strong>Processing</strong><br />

evaluating to true and subsequently assigning positional data to the elements in<br />

the array, will now evaluate to false as the number of clicks increases in value.<br />

We will then use the beginShape() and endShape() functions and combine each<br />

one of the two arrays' corresponding elements into a coordinate for the vertex()<br />

function, which will be embedded within a loop that cycles through the two arrays<br />

extracting the information from them and subsequently drawing the mystery<br />

shape.<br />

Although this might sound like a handful, you already know how to create two<br />

thirds of this program. Nonetheless, lets recap on these fundamental programming<br />

topics as they will more than likely prove to be a useful asset in many a sketch.<br />

First we are going to start by declaring and/or initializing the following global<br />

variables:<br />

int points = 6;<br />

int clicks;<br />

int[] numx = new int[points];<br />

int[] numy = new int[points];<br />

//number of points<br />

//click counter<br />

//array for mouse x<br />

//coordinates<br />

//array for mouse y<br />

//coordinates<br />

//generate a random color for the shape's fill<br />

color randCol = color(random(256), random(256), random(256));<br />

The points variable will be a number that we can change before running the<br />

sketch so that we can make our shape consist of as many or few points as we like,<br />

this number should not be negative.<br />

The clicks variable will be used to store the amount of times the user has clicked<br />

in the Display Window, it will also be an operand within the conditional that<br />

populates the array.<br />

Then we move onto declaring the arrays that will store the x and y coordinates of<br />

the user's clicks. Notice how the number of elements in this array has been<br />

defined as the variable points. As points is of type int it can be placed within the<br />

array's declaration brackets. The preceding statement relating to the declaration of<br />

the numx array can be translated and explicitly expressed as:<br />

int[] numx = new int[6];<br />

It is worth noting that in the actual sketch we have not used a numerical constant<br />

Arrays 156


An Introduction To Programming With <strong>Processing</strong><br />

but rather a variable to determine how many elements will populate the array, this<br />

is because if we decided we want to use more or less points making up the<br />

mystery shape, it would be easier to implement this change by means of<br />

modifying the initialization statement for the points variable rather than having to<br />

change numerical values scattered throughout the sketch.<br />

The final variable we have created within the global space is called randCol and<br />

has been datatyped as color. The color datatype is used to store color values, in<br />

our case we are using the format of:<br />

color varName = color(R, G, B);<br />

Where color is the keyword used to declare variables of type color, varName is<br />

the name of the variable, and the assignment operator is used to assign a color<br />

value in R (red), G (green) and B (blue) values. RGB values range from 0 to 255<br />

each. Note the expression used for each of the R, G and B values:<br />

random(256)<br />

random() is a function that is used to return a random number, that is between 0<br />

and the number specified, but not including the specified number. As a result the<br />

parameter 256 is used so that <strong>Processing</strong> will include values between 0 up to and<br />

including 255. random() also accepts parameters in the form of:<br />

random(Low, High);<br />

Where Low is the minimum number in the possible range of random numbers and<br />

High is one more than the maximum number in the range. If you assign the<br />

random() function to a float <strong>Processing</strong> will return random floats.<br />

The next step is to setup the setup() and draw() functions as per usual, then add<br />

the following if() statement to the draw() function:<br />

if (clicks


An Introduction To Programming With <strong>Processing</strong><br />

There's not really anything new about this if() statement, so we'll just run through<br />

it really briefly. First the conditional checks if the amount of times the user has<br />

clicked is less than the amount of elements in the arrays. Using this method<br />

creates an error catching scenario, as opposed to if the user was allowed to click<br />

repeatedly beyond the number of elements in the arrays which would result in the<br />

amount of elements that the program would attempt to store in the arrays<br />

exceeding the amount of elements that can be stored in the arrays. This would<br />

cause an “Array Index Out of Bounds” exception.<br />

We can then use the clicks variable in the if() structure to determine which<br />

element in the array is assigned the corresponding mouse X or mouse Y value.<br />

void mouseClicked(){<br />

clicks++;<br />

}<br />

Outside of the draw() function we setup a simple mouseClicked() function, which<br />

works in a very similar way to the mouseReleased() function. The difference<br />

being that the mouseClicked() function does not wait for the mouse to be released<br />

before running the code that makes up it's structure, it executes the code within<br />

it's associated braces as soon as the mouse is clicked within the Display Window.<br />

The purpose of the mouseClicked() function is simply to increment the clicks<br />

variable, which it does so within the function's only code block.<br />

Iterations<br />

<strong>Processing</strong> has two main types of iterations the for() structure and the while()<br />

structure. The while() structure can be thought of as a simplified version of the<br />

for() structure. We will be focusing on the for structure.<br />

The for() structure is used to iterate a value, that is to change a value by means of<br />

a recurring pattern. for() structures are also referred to as for() loops in some<br />

programming languages, whatever you call them they usually will be structured<br />

according to the following protocol.<br />

for(init; test; update){<br />

...statements<br />

}<br />

Iterations 158


An Introduction To Programming With <strong>Processing</strong><br />

Of the main differences that separate one languages implementation of for loops<br />

from that of another, will generally not be anything structural by rather syntactic.<br />

For example some programming languages use comma's to separate init, test and<br />

update <strong>Processing</strong> uses a semi-colon implying that each is a statement on it's own.<br />

• The term init in the previous example is used to describe initialization. In<br />

a for() loop iteration init is used to declare a temporary variable that will<br />

usually be used in the iterations structure, test and update.<br />

• Test is used to describe a conditional, which like a normal conditional will<br />

evaluate to true or false. If the conditional evaluates to true the for()<br />

structure will run, if the conditional evaluates to false the entire for() loops<br />

structure is skipped and <strong>Processing</strong> will continue to the statement/s that<br />

follow the for() structure in the sketch.<br />

• Update is used to describe an expression that will determine how the value<br />

of the variable in the conditional is being changed. The value of the<br />

variable being evaluated in the conditional must change, by means of the<br />

update, or the loop will go on forever which will eventually cause<br />

<strong>Processing</strong> to crash. For example an increment statement is often used in<br />

update to increment the value of the variable initialized in init and<br />

evaluated in the conditional test.<br />

In programming it is common to use a for() loop iteration to get your program to<br />

count for you, as per the following example:<br />

for (int i = 0; i < 10; i++){<br />

println(i);<br />

}<br />

//prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 one digit at a time<br />

The previous example used a for() loop iteration to count from 0 to 9, lets have a<br />

look at how we did this. First we need to use the for keyword to indicate to<br />

<strong>Processing</strong> that we are about to create a for() loop iteration. A for loop iteration<br />

relies on three statements init, test and update within parenthesis so that they are<br />

specifically associated with the for() loop iteration structure. As you can see the<br />

three statements are separated with semi-colons, this is unique to a for() loop<br />

iteration in <strong>Processing</strong> and clearly differentiates these statements from being<br />

parameters.<br />

As init is used to initialize a variable within the for() loop iteration structure, the<br />

scope of this variable is limited to the for() structure. What this means is that the<br />

Iterations 159


An Introduction To Programming With <strong>Processing</strong><br />

variable i in our previous example will not be accessible in other places within<br />

our sketch and only be accessible within the for() structure. As a result this<br />

variable name is usually i or n and not very descriptive. It is actually more<br />

distracting to call a variable initialized within a for() loop anything other than i or<br />

n (some people might also use x but this can be a bit distracting from variables<br />

that use x to denote a position on the x axis). It is therefore advisable to not use a<br />

variable name that is any more descriptive than a single character such as i or n.<br />

Once we have the variable initialized we can then use it in a test, if the test<br />

evaluates to true the code within the for structure will be run. It is important to<br />

note that if the test evaluates to true the code within the for structure is run, and<br />

only after this code is run is the update statement executed.<br />

A graphical representation of how an iteration works<br />

The update statement in our example is an incremental statement, which adds one<br />

to the variable from init subsequently increasing the value of the variable with<br />

each iteration. On the tenth occasion that the loop repeats the variable is<br />

incremented to a value of 10, so when the conditional evaluates the test (10


An Introduction To Programming With <strong>Processing</strong><br />

beginShape();<br />

for(int i = 0; i < points; i++){<br />

vertex(numx[i], numy[i]);<br />

}<br />

endShape();<br />

Using this method we can let the user decide what the shape should look like. If<br />

you recall beginShape() and endShape() require the vertex() function between<br />

them. The difference with this sketch is that we have nested the vertex() function<br />

inside a for() loop iteration. The program will loop through the vertex() function<br />

as many times as the variable initialized within the for() loop called i, is less than<br />

the points variable declared earlier in global space. What this translates to is the<br />

the vertex() function will be run six times and on the seventh attempt to run the<br />

for() loop the conditional of the for() loop will evaluate to false as i will be equal<br />

to points (i == points) causing the loop to break and running the rest of the code<br />

that follows the for() loop structure, which would be the endShape() function.<br />

This creates a shape with six vertices in the positions that the user specified by<br />

clicking in the Display Window. The coordinates of these vertices are determined<br />

by extracting the values associated with each element in the arrays numx[] and<br />

numy[], as the index number of each element is referenced with the for() loop<br />

variable i. A full listing of the mystery shape program follows:<br />

int points = 10;<br />

int clicks;<br />

int[] numx = new int[points];<br />

int[] numy = new int[points];<br />

color randCol = color(random(255), random(255), random(255));<br />

void setup() {<br />

size(300,300);<br />

smooth();<br />

}<br />

void draw() {<br />

background(100);<br />

if (clicks


An Introduction To Programming With <strong>Processing</strong><br />

}else{<br />

fill(randCol);<br />

beginShape();<br />

for(int tempx = 0; tempx < points; tempx++){<br />

vertex(numx[tempx], numy[tempx]);<br />

}<br />

endShape();<br />

}<br />

}<br />

void mouseClicked(){<br />

clicks++;<br />

}<br />

Transforms<br />

<strong>Processing</strong> provides a convenient method for animating and interacting with<br />

components of a sketch that are transformed in various ways. The term transform<br />

when used in this context generally refers to any one of, or combinations of the<br />

following three actions:<br />

Translation, Scaling, Rotation.<br />

Translation is simply another way of saying “moving” but as the term moving can<br />

tend to be somewhat ambiguous when you consider that rotation also involves<br />

movement and so too does scaling (when you consider that the components<br />

making up an object such as it's vertices move when the object is scaled), we<br />

prefer to use the term translation as it specifically refers to positional data in terms<br />

of x, y and z of an entity. The function for applying translations within a sketch is<br />

translate() and it accepts parameters in the form of x and y with an optional third<br />

parameter for z (which we will discuss soon) when using a 3D renderer.<br />

Rotation is a transform that we have not discussed in any of our previous<br />

sketches, and as you will see can be a useful asset to creating certain types of<br />

animation within a sketch. Amongst the functions that provide us with access to<br />

rotation are rotate(), rotateX(), rotateY() and rotateZ() these functions accept<br />

values in radians.<br />

Scaling is a transform accessed with the scale() function and it accepts a single<br />

float value or two floats that relate to x and y or three floats that relate to x, y and<br />

Transforms 162


An Introduction To Programming With <strong>Processing</strong><br />

z for 3D sketches. Scaling creates the impression of making things appear to be<br />

bigger or smaller within a sketch.<br />

Let's have a look at an example of a static sketch using the translate() function.<br />

size(400,60);<br />

rect(0,0,50,50);<br />

translate(width/2, 0);<br />

fill(255,0,0);<br />

rect(0,0,50,50);<br />

A static sketch using transforms<br />

In the first line of the sketch, we simply defined the window in which the sketch<br />

is running as being very long horizontally and short, vertically. In the following<br />

line we drew a rectangle at the origin, and because the rectMode() function by<br />

default is set to CORNER, the rectangle sits perfectly flush with the top left hand<br />

corner of the Display Window. We then used the translate() function with a<br />

modification to the x parameter, and as you would expect the next time we draw a<br />

rectangle (after changing the fill color) it's position on the x axis reflects this<br />

translation we previously applied. However, if you have a look at the x parameter<br />

for the rect() function you will notice that things are a bit different to what you<br />

might expect as the X parameter reads 0 whereas the rectangle is drawn close to<br />

the center of the Display Window and to the right of the previously drawn<br />

rectangle. Shouldn't the rectangle be drawn at the origin if it's X parameter is 0?<br />

If you were thinking something along those lines then you are absolutely correct<br />

and in fact the rectangle is being drawn at the origin, the main difference here is<br />

that we have used the translate() function to move the origin, not of the rectangle<br />

but of the entire coordinate system. Let's have a look at how this came to be.<br />

Although the effect of what you are seeing in the Display Window creates the<br />

impression that <strong>Processing</strong> has moved the rectangle, the rectangle as it is<br />

Transforms 163


An Introduction To Programming With <strong>Processing</strong><br />

indicated by it's X parameter in both rect() function calls tells us something<br />

different. That is that the rectangle has in fact not moved. The reason that the<br />

rectangle has come to be drawn in this new location is due to the effect of the<br />

entire coordinate system moving.<br />

If you were for a moment to reflect back on the Cartesian graph system that we<br />

discussed earlier you would remember that everything in <strong>Processing</strong> works in a<br />

similar fashion to that of something drawn on graph paper. Bearing this in mind,<br />

what we have done in the previous sketch cannot accurately be described as<br />

moving the rectangle, but rather more akin to us moving the “graph paper”. For<br />

example if you were to draw a rectangle on a piece of graph paper, then move the<br />

graph paper around, you would in effect be creating the impression of the<br />

rectangle drawn on the graph paper moving around. The rectangle itself would not<br />

be what you are moving around, in terms of the fact that the rectangle's positional<br />

x and y data has not changed with relation to the origin of the coordinate system it<br />

was drawn relative to. We can therefore say that the rectangle has not moved,<br />

however the coordinate system associated with it has.<br />

An object drawn on graph paper does not move but the graph paper does<br />

This is the purpose of transforms in <strong>Processing</strong>, they move the coordinate system<br />

for us. We can still move the components of a sketch through their own positional<br />

data, which we usually supply in terms of X and Y parameters of a function, but<br />

bear in mind that mixing translation techniques like this will result in the<br />

component appearing to have “moved” by the sum of the two data sets. To put<br />

this in another way, the distance the entity would appear to have moved would be<br />

the sum of the translate() function plus the X, Y and Z parameters of the function<br />

to draw the entity.<br />

So if we still have the ability to modify components of a sketch via their own X<br />

and Y parameters what's the benefit of having transforms?<br />

Transforms can save us a lot of unnecessary work, make our code a lot easier to<br />

read and provide us with functionality that would not be possible without them.<br />

Transforms 164


An Introduction To Programming With <strong>Processing</strong><br />

Lets have a look at an example of how this works.<br />

In order to see the benefits that transforms have on our code we'll revisit the smile<br />

sketch from our static sketch examples at the beginning. If you recall, the<br />

purpose of the sketch was simply to draw a smiley face to the Display Window in<br />

static mode with some other components. We're only interested in the smiley face,<br />

so first we're going to adapt the sketch for active mode by including the drawing<br />

of the face within the draw() structure:<br />

void setup(){<br />

size(640,480);<br />

}<br />

void draw(){<br />

background(127);<br />

//Drawing the face<br />

fill(191,233,255);<br />

ellipse(width/2, height/2, 100, 100);<br />

//smile<br />

noFill();<br />

stroke(255,0,0);<br />

arc(width/2, height/2 + 10, 50, 50, 0, PI);<br />

//eyes<br />

stroke(0,0,0);<br />

fill(0,255,0);<br />

ellipse(width/2-15, height/2-15, 20, 30);<br />

ellipse(width/2+15, height/2-15, 20, 30);<br />

}<br />

The smile static sketch revisited and modified to fit an active mode sketch<br />

Transforms 165


An Introduction To Programming With <strong>Processing</strong><br />

As you can see nothing surprising about the sketch, but what if we wanted to<br />

animate the smiley face by moving it across the Display Window, or attaching it<br />

to the mouse?<br />

This could become quite a cumbersome task as every component of the smiley<br />

face that has X and Y parameters would have to be updated for every frame. To<br />

give you an indication of how much extra work this is we're going to have a look<br />

at what sort of changes in the sketch would need to be implemented if we wanted<br />

to attach the smiley face to the mouse:<br />

void setup(){<br />

size(640,480);<br />

}<br />

void draw(){<br />

background(127);<br />

//Drawing the face<br />

fill(191,233,255);<br />

ellipse(mouseX, mouseY, 100, 100);<br />

//smile<br />

noFill();<br />

stroke(255,0,0);<br />

arc(mouseX, mouseY + 10, 50, 50, 0, PI);<br />

//eyes<br />

stroke(0,0,0);<br />

fill(0,255,0);<br />

ellipse(mouseX-15, mouseY-15, 20, 30);<br />

ellipse(mouseX+15, mouseY-15, 20, 30);<br />

}<br />

As you can see almost every second line of code had to be updated within the<br />

draw() structure. Now imagine if you had a whole character you wanted to draw<br />

and how much additional work something like that could amount to?<br />

With transforms making a change like this to your code is easy:<br />

void setup(){<br />

size(640,480);<br />

}<br />

void draw(){<br />

background(127);<br />

//transform<br />

translate(mouseX-width/2, mouseY-height/2);<br />

Transforms 166


An Introduction To Programming With <strong>Processing</strong><br />

//Drawing the face<br />

fill(191,233,255);<br />

ellipse(width/2, height/2, 100, 100);<br />

//smile<br />

noFill();<br />

stroke(255,0,0);<br />

arc(width/2, height/2 + 10, 50, 50, 0, PI);<br />

//eyes<br />

stroke(0,0,0);<br />

fill(0,255,0);<br />

ellipse(width/2-15, height/2-15, 20, 30);<br />

ellipse(width/2+15, height/2-15, 20, 30);<br />

}<br />

Notice that only one additional line of code was needed to accommodate for this<br />

update, the rest of the code remained unchanged.<br />

The additional statement is:<br />

translate(mouseX-width/2, mouseY-height/2);<br />

This statement simply uses the translate() function, with two parameters relating<br />

to X and Y. The X parameter tells <strong>Processing</strong> to “move” the entire coordinate<br />

system to the position of the mouse's X value then to subtract half the width of the<br />

Display Window from this value. The reason we need to subtract half the width of<br />

the Display Window from the mouseX system variable is because our entire<br />

sketch was originally made to draw the smiley face in the center of the Display<br />

Window.<br />

Offset from the origin with<br />

mouseX<br />

Offset from the origin with<br />

mouseX - width/2<br />

As the coordinate system is transformed, it's origin can exist within the boundaries of the<br />

Display Window or outside of these boundaries.<br />

Transforms 167


An Introduction To Programming With <strong>Processing</strong><br />

As transforms effect everything below their implementation within a sketch, due<br />

to them transforming the entire coordinate system, there are times when you will<br />

find that this is not the effect that you want.<br />

The image below of a cart is made up of three separate images which are rendered<br />

in the following order the wheel in the background, the main cart and the wheel in<br />

the foreground. If our intention was to rotate the back wheel first, as the back<br />

wheel would have to be rendered before any of the other images. We run the risk<br />

of having the transforms applied to the back wheel effecting the main cart and the<br />

wheel in the foreground as they are rendered after the back wheel, and will<br />

therefore be effected by any scale(), translate() and/or rotate() function that is<br />

intended for the back wheel. This would create the impression of the cart orbiting<br />

around the back wheel, which is obviously not what we where trying to<br />

accomplish. Two functions in <strong>Processing</strong> called pushMatrix() and popMatrix()<br />

help us to solve this problem.<br />

Main Cart<br />

Background wheel<br />

Foreground wheel<br />

The template rendering of the cart.pde sketch<br />

The function pushMatrix() when called before a transform is executed will store<br />

the current position of the coordinate system. This means that if you call a<br />

pushMatrix() function at the start of the draw() structure it will remember the<br />

default position of the coordinate system (pre-transform). You are then free to<br />

apply transforms to the particular component of the sketch that you would like to<br />

scale, rotate or translate. Once you are satisfied with the transforms you have<br />

performed you can then render the component, for example by means of a call to<br />

Transforms 168


An Introduction To Programming With <strong>Processing</strong><br />

the image() function. Running the popMatrix() function at this point will then be<br />

necessary to restore the coordinate system back to the state it was in when the<br />

previous pushMatrix() was called. You can then proceed to run more<br />

pushMatrix(), transforms, render, popMatrix() combinations on other components<br />

of the sketch which will remain unaffected by the previous transforms. Using<br />

pushMatrix() and popMatrix() in this way allows us to apply multiple transforms<br />

to a component of a sketch ,and not have those transforms effect other<br />

components.<br />

Transforms 169


An Introduction To Programming With <strong>Processing</strong><br />

Lets have a look at how to use this technique to make the cart move across the<br />

Display Window and have the wheels of the cart rotate accordingly.<br />

We'll start as always with a template of what we want the final result should look<br />

like:<br />

PImage cart;<br />

PImage wheelFd;<br />

PImage wheelBd;<br />

PImage grass;<br />

void setup(){<br />

size(800,600);<br />

cart = loadImage("cartMain.png");<br />

wheelFd = loadImage("wheelFd.png");<br />

wheelBd = loadImage("wheelBd.png");<br />

grass = loadImage("grassLessBlur.jpg");<br />

}<br />

void draw(){<br />

background(grass);<br />

imageMode(CENTER);<br />

}<br />

image(wheelBd, -75, 25);<br />

image(cart, 0, 0);<br />

image(wheelFd, -95, 35);<br />

//println(mouseY);<br />

Out of interest you might be wondering how I came about selecting the X and Y<br />

parameters of the image() functions which render the wheels relative to the<br />

position of the cart. If you look at the last line you'll see a println() function that<br />

has been commented out. By replacing the image() function's X and Y parameters<br />

with mouseX then mouseY, respectively and one at a time, you can run the<br />

sketch with the image of the wheel attached to either the mouse's X or Y position.<br />

Place the wheel in the position it should be in, the println() function (when<br />

uncommented) will print out the position of your mouse, note this value and<br />

replace it with the mouseX or mouseY system variable in the wheel's image()<br />

function's corresponding X or Y parameter.<br />

Transforms 170


An Introduction To Programming With <strong>Processing</strong><br />

As the imageMode() function is set to CENTER in this example you will have to<br />

move the cart image to a location that is not the origin, so that the left and top<br />

halves of the image is not obscured by the boundaries of the Display Window.<br />

You will then need to subtract the value that you added to the X and Y parameters<br />

of the image() function to draw the cart from the respective values printed in the<br />

Text Area that will be used to place the wheels in the correct locations.<br />

Now that we have a template from which to start let's set up a temporary system<br />

that allows the cart to trail after the mouse with a bit of friction, we'll then modify<br />

this code to suit the needs of our sketch. This methodological approach to<br />

sketching by creating a rough idea then refining it will allow us to see results<br />

much sooner in the sketching process, rather than spending a lot of time on a<br />

sketch only to find out when it is almost done that the effect we were trying to<br />

achieve isn't quite working out.<br />

We'll start by adding the following global variables:<br />

float xPos;<br />

float difX;<br />

int drag = 30;<br />

If you recall from the imageScroll.pde sketch, we used the technique of creating<br />

the impression of friction with a similar set of global variables. The only<br />

difference is that in this sketch we are now using the same technique to create the<br />

impression of friction along the x axis. Next we'll need to add the following<br />

statements to the draw() structure after the imageMode() function call:<br />

image(wheelBd, -75, 25);<br />

image(cart, 0, 0);<br />

image(wheelFd, -95, 35);<br />

difX = mouseX - (xPos + cart.width/2);<br />

xPos += difX/drag;<br />

Since we want the cart to move with relation to the mouse moving past the end of<br />

the cart on the right hand side, we're going to divide the cart.width object variable<br />

by 2 and add it to the position of the cart which is now determined by the center<br />

of the cart object because we have set imageMode() to CENTER.<br />

To temporarily link these statements to the rendering of the cart, directly after the<br />

previous statements add the following code:<br />

Transforms 171


An Introduction To Programming With <strong>Processing</strong><br />

pushMatrix();<br />

translate(xPos, 250);<br />

image(wheelBd, -75, 25);<br />

image(cart, 0, 0);<br />

image(wheelFd, -95, 35);<br />

popMatrix();<br />

Notice that we just added three additional statements. The first new statement is<br />

pushMatrix() this tells <strong>Processing</strong> to store the current transformational data of the<br />

coordinate system in memory, we then use the translate() function to to modify<br />

the coordinate system along the x axis by the value of the variable xPos and the<br />

numerical constant of 250 for the Y parameter. the Y parameter is a numerical<br />

constant simply because it will not change throughout the duration that the sketch<br />

is running. Next we render the images without any changes to their parameters as<br />

all of their positional data remains the same, the transform will create the<br />

impression of movement for us. Then finally we use the popMatrix() function to<br />

restore the transformational data relating to the coordinate system when<br />

pushMatrix() was initially called.<br />

When using pushMatrix() it must always be coupled with popMatrix() or<br />

<strong>Processing</strong> will complain about there being too many calls to pushMatrix() and<br />

not enough to popMatrix(). The term matrix simply refers to a grid of numbers,<br />

which is how <strong>Processing</strong> stores information about the coordinate system in<br />

memory. For example a matrix can be represented as:<br />

1 2 3 4 5<br />

6 7 8 9 10<br />

11 12 13 14 15<br />

16 17 18 19 20<br />

We would call this a 4 x 5 matrix meaning that it is made up of 4 rows and 5<br />

columns. This is not an actual representation of a matrix that <strong>Processing</strong> uses to<br />

calculate transforms but simply an example of what a matrix could look like, in<br />

fact the matrices that <strong>Processing</strong> uses are simpler than the previous matrix<br />

example.<br />

You might hear the term transformation matrix used on occasion, this is just<br />

simply referring to the numbers that make up the matrix that the matrix<br />

representing the current coordinate system must be processed through in order to<br />

produce the representation of the coordinate system in it's transformed state.<br />

Although this might sound like a bit of a tongue twister, the concept is less<br />

Transforms 172


An Introduction To Programming With <strong>Processing</strong><br />

complicated when you think of it in graphical form. Following is an example of<br />

what this might look like as a graphical representation, remember the numbers are<br />

purely illustrative, and not intended to represent actual numerical data and<br />

patterns that <strong>Processing</strong> calculates:<br />

pushMatrix()<br />

Matrix representing<br />

current coordinate<br />

system<br />

Transformation matrix<br />

stores data about<br />

translation, rotation<br />

and scaling<br />

=<br />

Resulting matrix<br />

representing new<br />

coordinate system<br />

popMatrix()<br />

Now that we have an idea of what the cart is going to look like when it's moving,<br />

lets concentrate on getting the wheels to rotate and translate.<br />

pushMatrix();<br />

translate(xPos -75 , 250 +25);<br />

rotate(xPos/wheelBd.width);<br />

image(wheelBd, 0, 0);<br />

popMatrix();<br />

image(cart, 0, 0);<br />

image(wheelFd, -95, 35);<br />

As you can see we have removed the image() function that renders the wheelBd<br />

object and placed it between a pushMatrix() and popMatrix() function pair.<br />

Between pushMatrix() and popMatrix() we are free to use translate() and rotate()<br />

to modify the coordinate system before rendering wheelBd with a call to the<br />

image() function. When we originally rendered the three images making up the<br />

cart, we had to offset the back wheel and front wheel so that they we in the<br />

correct places in relation to the position of the main cart. When performing<br />

transformations to an image it's best the have the image transform from the origin.<br />

As a result the X and Y parameters of the image() function used to render the<br />

image should remain at 0, and translations should be used when the image's X and<br />

Y coordinates need to change. This is often the simplest and most logical<br />

approach to working with transforms as it ensures that the image's relative<br />

distance to the origin is not modified which could lead to unexpected results.<br />

Transforms 173


An Introduction To Programming With <strong>Processing</strong><br />

Transforms are more predictable when the image() function's parameters are set to 0, 0<br />

for X and Y. Offsets in these parameters will often result in undesirable transformations.<br />

By setting the imageMode() function to CENTER and the X and Y parameters for<br />

the image() function to 0 and 0 we can be assured that the image of the wheel is<br />

going to be rendered with it's center at the origin. This is important because all<br />

transformations are relative to the origin, so that when we rotate the wheel it will<br />

appear to rotate from it's center, this is also due to setting imageMode() to<br />

CENTER and not leaving it at it's default of CORNER which would have resulted<br />

in the wheel appearing to rotate from it's top left hand corner. Bearing this in<br />

mind it is also important that the images that we use for the wheels are square in<br />

shape, in other words the image's width should match the same image's height.<br />

This creates the impression of the wheels being flat on the ground when they start<br />

to rotate. The following statement, is how we remove the image() functions offset<br />

and are still able to match the position of the cart with the mouse's X value:<br />

translate(xPos -75 , 250 +25);<br />

The xPos variable has not changed in terms of how it is applied in this sketch, the<br />

difference is that the X and Y parameter values that were used in the image()<br />

function to render the wheel have now been added to the translate() function's X<br />

and Y parameters. The rotate() function follows:<br />

rotate(xPos/wheelBd.width);<br />

As the xPos variable changes relative to the distance the cart has moved we can<br />

use the changing properties of this variable to make the wheels rotate. We can<br />

then divide this number by the width of the wheel image which is also the<br />

diameter of the circular shape of the wheel. This expression is based on the<br />

formula for pi which is pi = circumference/diameter, but it is worth noting that the<br />

Transforms 174


An Introduction To Programming With <strong>Processing</strong><br />

value returned from our modified expression is not equal to pi, as this would be a<br />

constant value as a result xPos is substituted for the circumference of the circle as<br />

this will yield a value that changes relative to the distance that the cart has<br />

traveled.<br />

We can then render the image at the origin after the coordinate system has been<br />

transformed, so the image appears to have moved because the coordinate system<br />

it is rendered relative to has, by then, been transformed.<br />

image(wheelBd, 0, 0);<br />

Finally use popMatrix() to reset the coordinate system back to it's original<br />

transformations.<br />

We can then continue to render the main cart and foreground wheel using the<br />

same techniques, and not have transformations from one rendering effect another.<br />

In the final cart.pde example I've added a shadow, try to figure out how you<br />

would go about creating this effect before looking at the code. Here's a hint, I've<br />

added four additional images to the sketch.<br />

The completed cart.pde sketch<br />

Transforms 175


An Introduction To Programming With <strong>Processing</strong><br />

An Introduction to 3D in <strong>Processing</strong><br />

Up until now we have been using <strong>Processing</strong> to create 2D sketches, that is<br />

sketches with 2 measurable dimensions such as width and height, however<br />

<strong>Processing</strong> allows us easy access to another dimension that being depth. As width<br />

is usually associated with the X axis and height is usually associated with the Y<br />

axis, depth is usually associated with the Z axis.<br />

Y<br />

X<br />

Z<br />

Axes indicating 3 Dimensions<br />

In <strong>Processing</strong> we have access to two 3D renderers, P3D and OpenGL. The P3D<br />

renderer is used mainly for 3D sketches on the web, the OpenGL renderer<br />

requires that the machine running the sketch must have OpenGL acceleration<br />

capabilities. Many modern 3D games and most 3D content creation software uses<br />

OpenGL, as it is not specific to <strong>Processing</strong> and a set of features that abstract the<br />

details of hardware acceleration for software developers. Using the P3D renderer<br />

in a <strong>Processing</strong> sketch is easy, as this renderer is simply invoked by adding an<br />

extra parameter to the size() function. For example:<br />

size(800, 600, P3D);<br />

This would cause <strong>Processing</strong> to use the P3D renderer. Using the OpenGL renderer<br />

is slightly different as this requires that the OpenGL library is first imported:<br />

An Introduction to 3D in <strong>Processing</strong> 176


An Introduction To Programming With <strong>Processing</strong><br />

import processing.opengl.*;<br />

All import statements in a sketch should precede all other statements. You can<br />

then use the OPENGL mode as a third parameter for the size() function.<br />

size(800, 600, OPENGL);<br />

A typical example of a sketch using OpenGL might look something like this:<br />

import processing.opengl.*;<br />

void setup(){<br />

size(500,500,OPENGL);<br />

}<br />

void draw(){<br />

background(127);<br />

…<br />

}<br />

3D Primitives<br />

In a similar way that <strong>Processing</strong> has 2D primitives such as rectangles, ellipses,<br />

lines etc you will also find a set of 3D primitives such as a box or a sphere.<br />

However you are free to use 2D primitives in a 3D sketch, but not 3D Primitives<br />

in a 2D sketch. One of the fundamental differences that separates the way in<br />

which the functions used to render 3D primitives differs from rendering 2D<br />

primitives, is that 3D primitives do not have parameters for X, Y and Z<br />

coordinates. For example the function to draw a box which is box() can accept<br />

three parameters but these parameters relate to width, height and depth.<br />

So how to we place 3D primitives in a sketch and move them around?<br />

This is achieved with the transform functions we have been using in our 2D<br />

sketches. The main difference is that now we have an additional axis to consider<br />

the Z axis, as a result in a 3D sketch translate() can be used with either 2 or 3<br />

parameters for example:<br />

An Introduction to 3D in <strong>Processing</strong> 177


An Introduction To Programming With <strong>Processing</strong><br />

translate(X, Y);<br />

//or<br />

translate(X, Y ,Z);<br />

Where X, Y and Z would be the numerical values relating to how the coordinate<br />

system is translated. The rotate() function can also be used in the following<br />

context:<br />

rotateX(num);<br />

//or<br />

rotateY(num);<br />

//or<br />

rotateZ(num);<br />

Where num is the numerical value in radians that the coordinate system will be<br />

rotated around the corresponding axis.<br />

Using the box() function and translations here's an example of how we could go<br />

about drawing a simple robot character using OpenGL:<br />

import processing.opengl.*;<br />

void setup(){<br />

size(500,500,OPENGL);<br />

}<br />

void draw(){<br />

background(127);<br />

pushMatrix();<br />

translate(width/2, (height/2)-100);<br />

box(40);<br />

translate(0,80);<br />

scale(0.8,1);<br />

box(80);<br />

translate(70,0);<br />

scale(1,2);<br />

box(30);<br />

translate(-140,0);<br />

box(30);<br />

translate(50,50);<br />

scale(1,1.5);<br />

An Introduction to 3D in <strong>Processing</strong> 178


An Introduction To Programming With <strong>Processing</strong><br />

}<br />

box(30);<br />

translate(40,0);<br />

box(30);<br />

popMatrix();<br />

A simple robot character rendered in <strong>Processing</strong> using OpenGL<br />

Creating 3D sketches can be fun, but can also become exceedingly difficult for<br />

the beginner as you will often find that a firm grasp of trigonometry is necessary<br />

and depending on what you are wanting to achieve an understanding of vector<br />

math and matrices might also be a prerequisite. However if you are interested in<br />

learning more about creating 3D sketches the best place to start is to work your<br />

way up from creating 2D sketches, that make use of the transformation matrix and<br />

basic trigonometric functions, then try adapt these ideas to include three<br />

dimensions.<br />

Guess My Number Game<br />

Using the information you've learned, thus far you should be able to follow the<br />

code within the guess my number game. Have some fun by modifying the code<br />

and try to make your own!<br />

Guess My Number Game 179


An Introduction To Programming With <strong>Processing</strong><br />

One of the many possible implementations of The Guess My Number Game<br />

Guess My Number Game 180


An Introduction To Programming With <strong>Processing</strong><br />

Object Oriented Programming<br />

Object Oriented Programming is a modern day programming paradigm, meaning<br />

that it is a fundamental style that suits the task of creating modern software. Most<br />

popular modern programming languages support OOP (Object Oriented<br />

Programming), and as a result understanding the fundamental concepts that define<br />

it within <strong>Processing</strong> can help in implementing it, by means of adapting your<br />

knowledge to suite any programming language that supports Object Oriented<br />

Programming.<br />

Earlier we discussed that OOP can be contrasted with Procedural Programming if<br />

you consider that Procedural Programming is a style of programming where the<br />

program is tailored to suite the data as opposed to Object Oriented Programming<br />

which is more akin to a style of programming where the data is tailored to suite<br />

the program. To briefly recap on these concepts, typically when creating<br />

programs using the procedural programming paradigm we use the programming<br />

language's built-in API features and associate the data we are representing in our<br />

program with the features that are defined by the developers of the language. The<br />

data that is associated with the API features is what we then use in our main<br />

program. This is in contrast to the object oriented programming paradigm where<br />

we define new types of data (called classes) to categorize and associate the data<br />

we are representing in our programs with the programming languages built-in API<br />

features. We then use instantiations of the classes called software objects in our<br />

main program.<br />

From this description you can see that the results of both programming paradigms<br />

can eventually lead to the same thing, however the process of getting to that result<br />

is what distinguishes one programming paradigm from that of another.<br />

Object Oriented Programming 181


An Introduction To Programming With <strong>Processing</strong><br />

The Procedural Programming<br />

Paradigm<br />

Data to represent<br />

The Object Oriented<br />

Programming Paradigm<br />

Data to represent<br />

API features<br />

API features<br />

Class organizes data<br />

Data represented with<br />

API features<br />

Objects representing<br />

Class<br />

Main Program<br />

Main Program<br />

An graphical representation of how OOP works<br />

OOP as you are aware relies on classes, from which we instantiate objects. These<br />

objects are the reason why we refer to this programming paradigm as Object<br />

Oriented Programming, and emphasize the “Object” part. We have already been<br />

using classes that are a part of <strong>Processing</strong>'s API such as PImage from which we<br />

have instantiated object variables which we have given names, and those objects<br />

have inherited various properties and functions (called methods in OOP) from the<br />

classes from which they where instantiated. But what exactly is a class?<br />

The concept of a class<br />

A class is simply a body of code that, in a similar way to a function, exists<br />

independently of the main body of code from which it is referenced. However, a<br />

class does not only have a singular purpose like a function that checks the<br />

position of the mouse, or moves and image around in a specific way or has some<br />

other purpose that can be summarized by a singularly specific directive. A class<br />

can consist of many functions, which in the context of OOP we refer to as<br />

methods. These methods can be used like functions of your main program but<br />

with the inherited properties of the class from which it came. As a result you can<br />

think of a method as being a function of a class, that when used in your main<br />

Object Oriented Programming 182


An Introduction To Programming With <strong>Processing</strong><br />

program will, like a function, have a definition independent of the main program<br />

and also have properties that are specific to the class it was instantiated from. The<br />

benefit of this is that when multiple objects are instantiated from a single class<br />

they all inherit the methods of that class, this allows you to use certain methods<br />

with one object and certain other methods with another object. Thereby creating<br />

relationships between those objects (and ultimately the data you are representing<br />

with you main program) with other data or API features in ways that would be<br />

very difficult or maybe not practically possible without OOP.<br />

Branch 01<br />

Method 1<br />

Branch 02<br />

Class<br />

Method 1<br />

Method 2<br />

Method 3<br />

Object 1<br />

Object 2<br />

Method 3<br />

MAIN PROGRAM<br />

Method 2<br />

Function Call<br />

Function<br />

Definition<br />

Method 2<br />

Branch 04<br />

Branch 03<br />

One class can result in many different branches.<br />

The Blueprint Analogy<br />

By creating classes we categorize the data we are representing and give these<br />

representations a context by associating them with features in the programming<br />

languages API. However a class is never used in the main program, it must first<br />

Object Oriented Programming 183


An Introduction To Programming With <strong>Processing</strong><br />

be instantiated as an object and the object is what we would use in our main<br />

program. In this sense a class is more like a blueprint, that describes the complex<br />

relationships between the data we are representing, like the blueprint of a house<br />

can describe how tall a wall will be or how far a window will be from the ceiling.<br />

If you can imagine a class to be like a blueprint then a software object is like a<br />

house made from that blueprint. For example, a class only describes the possible<br />

objects that can be instantiated from it, taking the blueprint analogy further we<br />

cannot live in a blueprint yet it has all the information we need to build a house<br />

which would be something that we use as a functional object. In other words we<br />

use the blueprint to build a house, this is just like instantiating an object from a<br />

class. The class only describes the possibilities of an object that can be<br />

instantiated from it and when we finally do instantiate an object from the class, it<br />

is the object that we use in our main program.<br />

Just like a blueprint describes a structure it does not say anything about how the<br />

structure can be used for example a blueprint can be used to build somebody's<br />

home or the same blueprint can be used to build an office. The purposes the<br />

buildings serve are different, but the structure of the buildings remains the same.<br />

The relationship between classes and software objects is very similar, in that one<br />

object instantiated from class can serve a certain purpose and another object<br />

instantiated from the same class can serve a different purpose, but because both<br />

objects are instantiated from the same class the context in which they are used<br />

will tend to have similarities.<br />

A single blueprint could be used to make several derivatives<br />

Object Oriented Programming 184


An Introduction To Programming With <strong>Processing</strong><br />

Why use Object Oriented Programming<br />

One of the fundamental concepts that makes OOP so popular is known as data<br />

encapsulation. We have already discussed how a variable can have a greater or<br />

lesser scope depending on where it is declared, that is to say that when a variable<br />

is not declared within the global variable scope it can only be accessed in some<br />

parts of a program and not in others that are outside of the structure in which it<br />

was declared. The range over which the variable is accessible refers to the<br />

variable's scope. Data encapsulation is a similar concept, except that the concept<br />

of “hiding” data is emphasized as opposed to defining a variable in the global<br />

variable scope where the concept of “exposing” data is emphasized. Another<br />

major difference between the two concepts is that with data encapsulation as<br />

opposed to variable scope we are not referring to a single variable but can, in fact,<br />

be referring to entire structures. These structures that we make inaccessible to the<br />

main program are what form the body of code that defines a class. By defining a<br />

class we use a modular approach to designing software, in the sense that the class<br />

that we have defined is not necessarily specific to the program we initially wrote<br />

it for, and as a result an be used in our program or removed from our program<br />

without us having to rewrite the entire program this is an inherent design<br />

characteristic of data encapsulation.<br />

Amongst other applications, creating a class defines the behaviors that an object<br />

instantiated from it will inherit. In order to interact with an object in a program,<br />

and subsequently use that which it has inherited from a class, we interact with the<br />

object via it's behaviors which are more commonly referred to as methods. This is<br />

a form of data encapsulation, in that we do not have direct access to how that<br />

object works as that is defined within the class. However we can still have the<br />

object interact with our main program through it's methods. In this sense Object<br />

Oriented Programming can provide a level of abstraction, when working with<br />

objects in the main program.<br />

Creating a Class<br />

As previously mentioned a class typically consists of method definitions and<br />

various fields (which we also refer to as member variables) that store information<br />

about the current state of the object instantiated from the class. The term fields<br />

Object Oriented Programming 185


An Introduction To Programming With <strong>Processing</strong><br />

refers to variables that are members of a particular class, and as a result are<br />

encapsulated data that store information about the object itself and are sometimes<br />

referred to in <strong>Processing</strong> as class data.<br />

Typically in <strong>Processing</strong> creating a class is a four step process that involves,<br />

1)Class Name creation<br />

2)Field declarations<br />

3)Constructor creation<br />

4)Method definitions<br />

The structure of a class looks similar to setup() and draw() and user defined<br />

functions, but since a class is not a function, but may contain many functions<br />

(called methods) it's name is not followed by parenthesis. An object variable<br />

name which we will have a look at shortly, on the other hand is followed by<br />

parenthesis in order to provide a means of communicating with the object's<br />

internal structure.<br />

void setup(){<br />

}<br />

void draw(){<br />

}<br />

class ClassName{<br />

}<br />

As you can see a class definition usually finds it place at the very end of a sketch,<br />

this is sometimes referred to as an in-line class definition. This simply emphasizes<br />

that the class is directly related to the sketch that it is defined within. As defining<br />

a class at the end of a sketch, after user defined functions, mouse and keyboard<br />

functions etc can create a cluttered looking sketch <strong>Processing</strong> also provides us<br />

with Tabs in which we can place additional code that will be compiled with the<br />

sketch we are currently working on. You can create a new tab by clicking the<br />

arrow pointing to the right on the far right of the PDE and a fly-off menu relating<br />

to Tabs will appear.<br />

Object Oriented Programming 186


An Introduction To Programming With <strong>Processing</strong><br />

The Tab fly-off from the PDE<br />

<strong>Processing</strong> will then ask you to provide a name for the new tab.<br />

Creating a new Tab<br />

Once you supply a unique name and click OK <strong>Processing</strong> will create a new blank<br />

Tab next to the original Tab. What has actually happened is that <strong>Processing</strong> has<br />

created a new .pde file that has the name you specified for the Tab that was just<br />

created. This new .pde file resides in the same location as the sketch you are<br />

currently working on, as a result it can access anything in the data folder that you<br />

can access from the code of the original Tab. Although <strong>Processing</strong> has created<br />

another .pde file this file is only part of a sketch. In a similar way that the original<br />

pde file can be reliant on the contents of the data folder, the new .pde file in the<br />

same location as the original pde file can also be reliant on the original .pde and<br />

the contents of the data folder. As a result we refer to this collection of elements<br />

(i.e. pde files, txt files, spreadsheets, images and anything else that is in the data<br />

folder used in the sketch) collectively as the contents of a sketch.<br />

Using additional Tabs in a sketch provides us with a convenient location for<br />

placing classes. This is useful because it emphasizes the modular design of classes<br />

and clears the main pde file from becoming over-cluttered with code. Working<br />

with additional tabs is not synonymous to working with multiple sketches.<br />

Multiple tabs are a means of breaking up the current sketch you are working on<br />

Object Oriented Programming 187


An Introduction To Programming With <strong>Processing</strong><br />

into smaller manageable portions of code. As a result when a sketch with multiple<br />

Tabs is run all the code within all the Tabs of that sketch are compiled together.<br />

This means that only one of the Tabs should have setup() and draw() structures,<br />

the other Tabs should be used for class definitions, user defined functions or other<br />

elements of a sketch that exist outside of setup() and draw() structures.<br />

A Button Class<br />

If we wanted to create a class for a button, that we will call Button. This class will<br />

also have<br />

• fields that will contain certain information about the object instantiated<br />

from the class such as the color of the button, it's size and position.<br />

• The class will also have a constructor that will use the class's fields to<br />

create an initial state for the object.<br />

• Finally the class will have 2 methods, one that renders (or displays) the<br />

button and another that tests whether the user's mouse is over the button.<br />

The completed buttonClassExample file<br />

In order to give the class a name and let <strong>Processing</strong> know that we are about to<br />

create a class we must use the class keyword. The name of a class generally starts<br />

with an upper-case character. For example. We'll start by adding a new tab and<br />

calling it Button. In this tab add the following code:<br />

class Button{<br />

}<br />

This is how we create a class and name it in <strong>Processing</strong>. As you can see the class's<br />

A Button Class 188


An Introduction To Programming With <strong>Processing</strong><br />

name is Button which starts with an upper-case character, in-line with popular<br />

standardized coding practices.<br />

When we instantiate an object from this class there are several properties we'd<br />

like this object to inherit from the class, which we will have access to modifying<br />

from the main program but not be able to modify the definitions of these<br />

properties as this will be encapsulated within the Button class. A list of the these<br />

properties follow:<br />

1. the color of the rectangle that will visually represent the button object,<br />

2. the object's X coordinate<br />

3. the object's Y coordinate<br />

4. the object's width<br />

5. the object's height<br />

6. and a name for the object.<br />

As a result we will need at least all six of these properties represented in the<br />

class's fields as variables.<br />

Let's add those fields to the class, inside the braces of the Button class add the<br />

following declarations:<br />

color cB;<br />

float xLocB;<br />

float yLocB;<br />

float xSizeB;<br />

float ySizeB;<br />

String nameB;<br />

As you can see each of these variables will hold the information related to the<br />

previous list of six items. To give you an idea of how these fields (or variables)<br />

will be used we need to fast forward a few steps into the future and take a quick<br />

look at what happens when we instantiate the class. The process of creating an<br />

object is actually nothing new to you, as you have already instantiated objects<br />

from the PImage class. One of the main differences with our Button class is that<br />

we will be using it's constructor to initialize objects instantiated from it, so when<br />

we get to doing this we will use an initialization statement that will in part look<br />

like this:<br />

//this is simply for illustrative purposes<br />

Button(cB, xLocB, yLocB, xSizeB, ySizeB, nameB);<br />

A Button Class 189


An Introduction To Programming With <strong>Processing</strong><br />

From this partially complete code fragment, Button accepts the parameters the<br />

user has input, which will be assigned to the object's fields (which were inherited<br />

from the class's fields). These parameters will be used to initialize the the object<br />

instantiated from the Button class. However at the moment, these variables don't<br />

really do much, or store any information that will help in constructing the button<br />

object. This is why we need a constructor. The constructor is like a method that is<br />

automatically called every time a new object is instantiated from a particular<br />

class. The main purpose of a constructor is to determine a default state that an<br />

object will exist in as soon as it is instantiated. The constructor is defined below<br />

the fields declaration of a class and our constructor will look like this:<br />

Button(color tempcB, float tempxLocB, float tempyLocB, float<br />

tempxSizeB, float tempySizeB,String tempNameB){<br />

cB = tempcB;<br />

xLocB = tempxLocB;<br />

yLocB = tempyLocB;<br />

xSizeB = tempxSizeB;<br />

ySizeB = tempySizeB;<br />

nameB = tempNameB;<br />

}<br />

Note that the constructor has the same name as the class, this is a requirement for<br />

using a constructor. When we refer to Button() we are actually referring to the<br />

constructor of the class and not the class itself, which we simply refer to as<br />

Button.<br />

The first line of the constructor tells <strong>Processing</strong> how the Button class will accept<br />

parameters when a new object is instantiated from it. You might have also noticed<br />

that we have declared six new variables that will temporarily store the values that<br />

the user inputs as parameters when an object is instantiated. These values will<br />

then be assigned to the original member variables which will store the values that<br />

the user has input as parameters when instantiating the button. Using this<br />

approach to designing a constructor ensures that multiple objects can be<br />

instantiated using different parameters with the same constructor.<br />

At this stage in the design of the Button class we have fields declaring the<br />

member variables that will be used to store information about the button, and how<br />

we would like to use those fields to construct the button, but we have not told<br />

processing to actually draw the button to the Display Window so that the user can<br />

see a visual representation of the object and interact with it. This is amongst one<br />

A Button Class 190


An Introduction To Programming With <strong>Processing</strong><br />

of the many reasons why class's have methods. In order to render this visual<br />

representation we're going to create a method called disp() which will create a<br />

rectangle from the parameters the user inputs into the Button() constructor when<br />

instantiating a new object. Just like user defined functions methods must use the<br />

void keyword if they do not return a datatype. Here's what our disp() method<br />

(short for display method) will look like:<br />

void disp(){<br />

fill(cB);<br />

rect(xLocB, yLocB,xSizeB, ySizeB);<br />

fill(0);<br />

text(nameB, (xSizeB/2)+xLocB-((xSizeB/2)/2),<br />

(ySizeB/2)+yLocB+((ySizeB/2)/2));<br />

}<br />

Creating a method follows the same routine as creating a user defined function.<br />

Our disp() method is really quite simple all it does is accept the cB variable as a<br />

fill() color, draw a rectangle with the positional data from xLocB and yLocB and<br />

finish the rectangle by determining it's size from the xSizeB and ySizeB<br />

variables. The method then goes on to set the fill() to black and render the name<br />

of the button (nameB) in the center of the button.<br />

A class can be as simple or a complex as you want, and since we have all the<br />

“main ingredients” of our class we're going to return to our main program and<br />

have a look at how to instantiate an object from this class.<br />

Object Instantiation<br />

Object instantiation is not a new concept to you as you have already instantiated<br />

objects from the PImage class. The process of instantiating an object from our<br />

Button class will follow a very similar pattern.<br />

Since we want this object to be accessible from both setup(), draw() and user<br />

defined functions we are going to declare an object variable in the global variable<br />

scope by adding the following declaration outside of both setup() and draw():<br />

Button myButton;<br />

A Button Class 191


An Introduction To Programming With <strong>Processing</strong><br />

We now have a variable name that we can use to reference the object we just<br />

instantiated from the Button class, this name is myButton.<br />

Within the setup() structure we'll initialize the button:<br />

myButton = new Button(color(255), width/2, height/2, 100, 40,<br />

"myButton");<br />

myButton (the object variable) has inherited the properties of the Button class. If<br />

you were to compare this statement with the modified example of the class's<br />

constructor:<br />

//this is simply for illustrative purposes<br />

Button(cB, xLocB, yLocB, xSizeB, ySizeB, nameB);<br />

You will notice that this button is currently being constructed, but remember that<br />

you will not actually see the button at this stage as all we have done is told<br />

<strong>Processing</strong> how we would like the button to be constructed we have not told<br />

<strong>Processing</strong> to actually display the button. The use of the new keyword in the<br />

previous listed assignment statement is followed by the class's constructor which<br />

is why we are using Button() and not Button.<br />

Now that we have told <strong>Processing</strong> how we would like this new button constructed<br />

let's move onto the draw() structure and actually render the button.<br />

Using an object's method is easy, and is very similar to a function call. The main<br />

difference is that the name of the method is preceded by the name of the object<br />

itself. For example:<br />

myButton.disp();<br />

Add this statement to the draw() structure, and you'll finally see your button.<br />

The button instantiated and displayed by it's disp() method<br />

A Button Class 192


An Introduction To Programming With <strong>Processing</strong><br />

As you can see when working with OOP the main program looks less cluttered<br />

with code and the majority of the code exists in creating classes. This for many<br />

people creates a more readable interface for designing software, and once you get<br />

the hang of using OOP it can also help to localize problematic code that might be<br />

difficult to locate without a program adopting a modular design.<br />

The completed sketch ButonClassExample.pde also contains another method<br />

called over() which will identify if the users mouse is over the button, if you take<br />

some time to examine the sketch you should be able to add your own<br />

functionality to the button.<br />

Working with external data<br />

There are many ways of getting data into a <strong>Processing</strong> sketch from importing a<br />

simple image, 3D geometry or importing spread sheet data and the list goes on.<br />

But amongst the simplest and most versatile methods of getting external data into<br />

<strong>Processing</strong> is by means of a text file.<br />

A simple text file<br />

A text file imported into a sketch should have the file extension .txt. A word<br />

processor document might have additional formatting and as a result might<br />

produce unexpected results when used in a sketch. For this exercise it is<br />

recommended that you use the file called names.txt.<br />

Importing a text document into a sketch works in the same way that that images<br />

are imported into a sketch. Locate the file to be imported and click and drag it into<br />

Working with external data 193


An Introduction To Programming With <strong>Processing</strong><br />

the PDE with the sketch you are working on, open. The PDE will report that a file<br />

has been added successfully to the sketch and if you were to open the sketch's<br />

data folder you will find a copy of the file in there. In order to display the contents<br />

of the names.txt file in the Display Window we will use an array of Strings with<br />

each element of the String representing a line of characters in the names.txt file.<br />

Lets have a look at how to do this.<br />

In the global variable scope declare a new array of Strings and call it names:<br />

String[] names;<br />

Notice that declaring an array like this does not indicate to <strong>Processing</strong> how many<br />

elements will be in the array. This is because we want <strong>Processing</strong> to tell us how<br />

many elements are going to make up this array. In other words if we had a text<br />

document with many lines each of which was intended to be an element in an<br />

array, instead of counting the lines in the text document and creating the array like<br />

so:<br />

String[] names = new String[10560];<br />

We would use the former method where the number of elements is decided by<br />

<strong>Processing</strong> and if we wanted to know how many elements <strong>Processing</strong> has<br />

populated the array with, we would use the String object's variable length to find<br />

out. We'll have a look at how to do this a bit later.<br />

In setup() we're going to populate the array with the loadStrings() function, which<br />

will accept one parameter that is the name of the text file containing the data that<br />

will be used to populate the array.<br />

names = loadStrings("names.txt");<br />

We now have an array of Strings that we can refer to by it's variable name called<br />

names. This array has several elements each consisting of a String representing<br />

each individual line of the names.txt file.<br />

Finally to display the information contained within the elements of the names<br />

array we will use the text() function within a for loop:<br />

Working with external data 194


An Introduction To Programming With <strong>Processing</strong><br />

void draw() {<br />

for(int i = 0; i < names.length; i++){<br />

text(names[i], 20, i*20 + 20);<br />

}<br />

}<br />

The String object's variable, names.length stores the amount of elements in the<br />

names array, this information is important for creating the test of a for loop<br />

iteration. The text() function uses each element in the names array as a data input<br />

parameter, subsequently rendering each line of the text file one after the other and<br />

offset on the Y axis.<br />

The loadStringsExample.pde file<br />

Using this technique of loading external data does not have to be confined to<br />

working with the Strings datatype. Typecasting provides a convenient approach to<br />

converting String data into numerical data that can be calculated. Here's an<br />

example of the loadStringsExample.pde file that does just that with a file<br />

containing numbers. It is worth noting that although when you open the<br />

numbers.txt file it reveals a list of numbers to you, when this information is read<br />

into our sketch <strong>Processing</strong> identifies this data as String data. Which is why we<br />

must first typecast each element of the numbers array with the int() function into<br />

an int datatype before we can perform addition on the data.<br />

String[] names;<br />

String[] numbers;<br />

int tCast;<br />

Working with external data 195


An Introduction To Programming With <strong>Processing</strong><br />

void setup() {<br />

size(300,300);<br />

smooth();<br />

names = loadStrings("names.txt");<br />

numbers = loadStrings("numbers.txt");<br />

}<br />

void draw() {<br />

background(100);<br />

for(int i = 0; i < names.length; i++){<br />

text(names[i],20,i*20 + 20);<br />

}<br />

for(int i = 0; i < numbers.length; i++){<br />

tCast += int(numbers[i]); //typecasting int(numbers[i])<br />

}<br />

text(tCast,250,20);<br />

}<br />

Working with external data 196


An Introduction To Programming With <strong>Processing</strong><br />

Attribution<br />

Images<br />

Apollo Guidance Computer 10<br />

Copyright NASA<br />

NASA Manned Spacecraft Center 10<br />

Copyright NASA<br />

Japanese Rickshaws 11<br />

Public Domain<br />

Medical Equipment 14<br />

Copyright the owner of the image<br />

Gambling Machines 15<br />

Yamaguchi 先 生 /Wikipedia<br />

Alan Turing 16<br />

Copyright the owner of the image<br />

LOLCAT image 17<br />

M-J<br />

<strong>Processing</strong>.org image 41<br />

Copyright the owner of the image<br />

Star Wars ARC-170 Starfighter<br />

Guess My Number Game<br />

Cody Borst (Sqorck)<br />

Coat of Arms Icons Social Commentary Viz<br />

Copyright the owner/s of the images<br />

Attribution 197

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!