Although many open source projects are driven to build alternatives for existing applications, there are numerous projects that represent new and innovative works. Processing is one of those programs. Processing began at the Massachusetts Institute of Technology's (MIT's) Media Lab in 2001, created by Ben Fry and Casey Reas, though it has contributions from Carnegie Mellon; the University of California, Los Angeles; Miami University; and others.
The original goal for Processing was the development of a graphical sketchbook and environment that could be used to teach (graphically) the fundamentals of computer science. It has since evolved into an environment that can be used to create professional works for graphical visualization. A community has grown around it, building libraries that evolve the language and environment for animation, visualization, vision, network programming, and many other applications. What you'll find here is that Processing is a great environment for data visualization, with a simple interface, a powerful language, and a rich set of mechanisms for data and application export.
Processing runs on GNU/Linux®, as well as Mac OS X and Windows®, and it supports the ability to export images to a variety of formats. For dynamic applications, it's even possible to export Processing applications as Java™ applets for use in Web environments.
This first article begins with an exploration of the Processing IDE, then reviews some of the first aspects of the Processing language. It then looks at some of the key graphical primitives and finally explores a couple of applications that take advantage of them.
Processing environment
The first step is to install the Processing environment. Go to Processing.org, click
Download Processing, and select your operating
system. Note that the examples in which article use V1.2.1 of
Processing. Once the gzipped tarball is downloaded, expand it using tar xvfz processing-1.2.1.tgz, for example.
You'll also need to ensure that you have Java technology available. On
Ubuntu, simply type sudo apt-get install
openjdk-6-jdk.
When installation is complete, go to the processing-1.2.1 directory created
by the earlier tarball and test it by typing ./processing.
This should bring up the Processing Development Environment (PDE, or Processing IDE), shown in Figure 1. The large portion of the window is the text editor. If you type the two lines shown in the figure and click Run (the triangle in the upper left), a window appears that is a result of the simple program (or sketch, in Processing lingo) that you entered. Clicking Stop (the square in the upper left) causes the program to exit and the window to disappear.
Figure 1. The PDE and Results window

Now, let's dig into the Processing language to explore its major features en route to developing some interesting applications.
Processing language
Processing is written in the Java programming language, and it's also the language to
which Processing is closest in the language tree. So, if you understand
C or the Java language, Processing will be
simple to learn. It does make some simplifications in the way the programs
are constructed. Processing doesn't include some of the more advanced
features of the Java language, but many of these features are integrated
into Processing, so it's not necessary for you to understand them.
The reason the Java language was chosen is that Processing applications are translated into Java code for execution. Choosing the Java paradigm simplifies this translation and makes it simple and straightforward to develop and execute visual programs. For a comparison of the Processing language and the Java language, check out Resources.
Graphics environment
As you saw in Figure 1, developing in Processing
involves the PDE and display window. The coordinate system, for
2-D graphics, is shown in Figure 2. The size keyword defines the dimensions of the
display window in pixels and is commonly the first step in a Processing
application.
Figure 2. Coordinates of a 2-D display window

As shown in Figure 2, the size keyword specifies the X and Y coordinate extremes of the
display window. The line keyword draws a line
between two pixels in the display (in the form x1, y1 to x2, y2). Note that drawing off screen (outside of the bounds
defined by size) is not illegal, but simply
ignored.
This article doesn't explore it, but size
accepts an optional third argument for mode.
mode defines the rendering engine to be
used and supports PDF (for rendering directly
to an Adobe® PDF document), OPENGL
(to exploit an available Open-GL graphics adapter), P3D (for fast 3-D rendering), and others. The default is JAVA2D, which is best for high-quality 2-D
imaging.
Now, let's explore some of the basic graphics primitives before digging into a couple of sample applications.
Graphics primitives
Processing includes a large variety of geometric shapes and controls for those shapes. This section introduces some of the basic graphics primitives.
Background and colors
The background function is used to set the color
of the display window. This function can use a variety of different
parameters (to define a gray value, or a Red-Green-Blue [RGB] color). The
code segment in Listing 1 generates the output shown
in Figure 3, cell a.
Listing 1. Using the Background function
size(100, 100); background( 0, 128, 0 );
Drawing pixels
You can also draw individual pixels using the set function. This function takes the x,y coordinate within
the display window and a third argument for the color. Processing also has
a type called color through which you can
define the color used for a particular operation. In this case, you create
a color instance and use it to set a particular pixel within the display
window (see Listing 2 and Figure
3, cell b).
Listing 2. Setting pixels and colors
size(100, 100);
for (int x = 0 ; x < 100 ; x++) {
for (int y = 0 ; y < 100 ; y++) {
color c = color( x*2, y*2, 128 );
set(x, y, c);
}
}You can use a get operation to read the color of
a given pixel in the display. Although set is
simple, it's not the fastest way to manipulate the display. For faster
access, use the pixels array (in concert with
the loadPixels and updatePixels functions), instead.
Drawing shapes
It's also simple to draw shapes within Processing using single functions.
To set the color that's used when drawing shapes, you use the stroke function. This function can take a single
gray parameter or three parameters for RGB. You can also define the color
that's used to fill the shape with the fill
command.
Listing 3 shows how to draw lines, rectangles, circles
(using the ellipse), and ellipses. The line
function takes four arguments, representing the points between which a
line is drawn. The rect function draws a
rectangle, with the first two points defining the location and the next
two defining width and height, respectively. The ellipse function also takes four arguments, defining the
location and width/height. When width and height are equal, the shape is a
circle. You can also tailor ellipses using the ellipseMode function, which specifies whether the x,y location
represents the corner (CORNER) or the center of
the ellipse (CENTER). See Figure 3, cell C.
Listing 3. Lines and shapes
size(100, 100); stroke(0, 128, 0); line(10, 10, 90, 90); fill(20, 50, 150); rect(30, 30, 60, 40); fill(190, 0, 30); ellipse(30, 70, 20, 20); fill(0, 150, 90); ellipse(70, 30, 30, 20);
Drawing quadrilaterals
You can easily draw four-sided polygons in Processing with quad. The quadrilateral takes eight arguments
representing the four points of the quadrilateral. The example in Listing 4 creates 10 random quadrilaterals (where
the points must be in clockwise or counter-clockwise order. This code also
creates a random grayscale color for each quad.
Listing 4. Drawing quadrilaterals
size(100, 100);
for (int i = 0 ; i < 10 ; i++) {
int x1 = (int)random(50);
int y1 = (int)random(50);
int x2 = (int)random(50) + 50;
int y2 = (int)random(50);
int x3 = (int)random(50) + 50;
int y3 = (int)random(50) + 50;
int x4 = (int)random(50);
int y4 = (int)random(50) + 50;
fill( color((int)random(255) ) );
quad( x1, y1, x2, y2, x3, y3, x4, y4 );
}Figure 3. Graphics output for listings 1 through 4

Numerous other shapes exist, as do controls for line width and smoothness
of image. Figure 4 shows the quad function example from Listing 4 with
a call to smooth. This function provides
anti-aliasing of the edges and improves the quality of the image at the
cost of speed.
Figure 4. Using the smooth function

Structure of a Processing application
So far, you've explored the Processing language in a collection of simple
scripts — unstructured code that provided simple elements
of an application. Processing applications have a structure, which is
important when developing graphical applications that run continuously and
alter the display window over time (for example, for animation). Two of
the important functions in this context are setup and draw.
The setup function is used for initialization
and is executed once by the Processing run time. Typically, the setup function contains the size function (to define the bounds of the window) as well as
initialization of variables that are used during operation. The Processing
runtime continuously executes the draw. Each
time the draw function finishes, a new frame is
drawn to the display window, and the draw
function is invoked again. The default draw rate is 60 frames per second,
although you can alter this rate by calling the frameRate function.
You can also control when frames are drawn using noLoop and draw. The noLoop function causes drawing to stop and can be
restarted using the loop function. You can
control when draw is called by calling redraw.
Now that you know how to develop a Processing application, let's look at a simple example that demonstrates the use of text.
Using text
Processing also supports text, both within the display window and in the
form of a console for debugging. To use text within the display window,
you need a font. The first step is to create a font (which you do using
the Tools option of the PDE). After selecting a font to
create, this font file (VLW) will show up in the project's ./data
subdirectory. You can then load this file using the loadFont function, and then define it as the default using
textFont. Both of these steps are shown in
Figure 5 within the setup function. Note also that you slow the frame rate down to
one frame per second (because that's the frequency at which updates
naturally occur).
The draw function demonstrates a number of other
functions you've not yet seen. First are the time functions, which return
the hour, minute, and second of the clock. Note that there are additional
functions that return the year, month, and day. With the time data stored,
you then create a string using the nf function,
which converts numbers into strings. To add some variety to your clock,
manipulate the colors of the background and clock using background and fill
functions. The background ranges from 255 (white) to 137 (light gray). The
fill function, which colors the text,
ranges from 100 (light gray) to 218 (near black). With the colors set, the
text function emits your time string to the
display window at the defined coordinates. You also emit the string to the
console using the println function (see the
bottom left of Figure 5).
Figure 5. Using text within a Processing application

Building simple applications
Now, let's look at a couple of simulations built with Processing. The first is an implementation of a 2-D cellular automaton that implements the forest-fire model. This model, from Chopard and Droz's "Cellular Automata Modeling of Physical Systems," provides a simple system that illustrates the growth of trees in a grid and the spread of fire resulting from a lightning strike. This simulation consists of a simple set of rules that are defined as:
- On an empty site (brown), a tree grows with probability pGrowth.
- A tree becomes a burning tree (red) if at least one of its neighbors is burning.
- A burning tree (red) becomes an empty site (brown).
- A tree without any burning neighbors becomes a burning tree with probability pBurn. This occurs, for example, as a result of a lightning strike.
These rules are encoded in the update function
(see Listing 5), which iterates through the 2-D space
to determine how states transition per the defined rules. Note that the 2-D
space is actually 3-D because you maintain two copies
of the space — one for the current iteration and one for the
last. You do this to avoid corrupting the space with changes. The space
then becomes a display space (what is displayed) and a compute space
(application of the rules). The spaces swap over each generation.
For the most part, this application uses very little of Processing's
graphics keywords. A few colors are defined for the space, stroke is used to change colors, and point is used to draw a pixel. Using the
Processing model, the draw function calls update to apply the rules; upon return, draw emits the updated space to the display
window.
Listing 5. Cellular Automata Forest Fire Model
int[][][] pix = new int[2][400][400];
int toDraw = 0;
int tree = 0;
int burningTree = 1;
int emptySite = 2;
int x_limit = 400;
int y_limit = 400;
color brown = color(80, 50, 10); // brown
color red = color(255, 0, 0); // red;
color green = color(0, 255, 0); // green
float pGrowth = 0.01;
float pBurn = 0.00006;
boolean prob( float p )
{
if (random(0, 1) < p) return true;
else return false;
}
void setup()
{
size(x_limit, y_limit);
frameRate(60);
/* Initialize to all empty sites */
for (int x = 0 ; x < x_limit ; x++) {
for (int y = 0 ; y < y_limit ; y++) {
pix[toDraw][x][y] = emptySite;
}
}
}
void draw()
{
update();
for (int x = 0 ; x < x_limit ; x++) {
for (int y = 0 ; y < y_limit ; y++) {
if (pix[toDraw][x][y] == tree) {
stroke( green );
} else if (pix[toDraw][x][y] == burningTree) {
stroke( red );
} else stroke( brown );
point( x, y );
}
}
toDraw = (toDraw == 0) ? 1 : 0;
}
void update()
{
int x, y, dx, dy, cell, chg, burningTreeCount;
int toCompute = (toDraw == 0) ? 1 : 0;
for (x = 1 ; x < x_limit-1 ; x++) {
for (y = 1 ; y < y_limit-1 ; y++) {
cell = pix[toDraw][x][y];
// Survey area for burning trees
burningTreeCount = 0;
for (dx = -1 ; dx < 2 ; dx++) {
for (dy = -1 ; dy < 2 ; dy++) {
if ((dx == 0) && (dy == 0)) continue;
else if (pix[toDraw][x+dx][y+dy] == burningTree) burningTreeCount++;
}
}
// Determine next state
if (cell == burningTree) chg = emptySite;
else if ((cell == emptySite) && (prob(pGrowth))) chg = tree;
else if ((cell == tree) && (prob(pBurn))) chg = burningTree;
else if ((cell == tree) && (burningTreeCount > 0)) chg = burningTree;
else chg = cell;
pix[toCompute][x][y] = chg;
}
}
}Figure 6 shows the iteration of the Cellular Automata Forest Fire Model, skipping appropriately to show the effect of the rule set. Time 0 consists solely of empty space into which trees grow. At time 40, you can begin to see fires burning that eventually take over the space. At around time 100, tree growth is more visible, but at time 120, more fires begin and the process cycles.
Figure 6. Output from the Cellular Automata Forest Fire Model

The Susceptible/Infected/Recovered Model
The Susceptible/Infected/Recovered (SIR) Model simulates the spread of a disease within a hospital. Like the forest-fire model, SIR is implemented by a simple set of rules but adds complex and interesting behavior. In this model, you have a grid of beds filled by patients. At time 0, all patients are susceptible to the new disease, meaning that they've never had the disease and may, therefore, contract it. If one of the patients in the four N/S/E/W neighborhoods has the disease, then the patient becomes infected with a probability of tau. An infected patient remains sick for K days, during which time the patient may infect other patients. After K days, the patient recovers and is now resistant to the disease.
As with the previous example, the setup function
initializes the hospital to all susceptible patients, except for the
patient in the center who is infected. In this implementation, 0 is susceptible, 1-K
is infected, and -1 is recovered. The draw function emits the geometry to the display
window, and update implements the SIR rules. As
before, a 3D array is used to maintain the current and working geometries.
Listing 6 shows the code.
Listing 6. The SIR Model in Processing
int[][][] beds = new int[2][200][200];
int toDraw = 0;
int x_limit = 200;
int y_limit = 200;
color brown = color(80, 50, 10); // brown
color red = color(255, 0, 0); // red;
color green = color(0, 255, 0); // green
int susceptible = 0;
int recovered = -1;
float tau = 0.2;
int k = 4;
boolean prob( float p )
{
if (random(0, 1) < p) return true;
else return false;
}
void setup()
{
size(x_limit, y_limit);
frameRate(50);
for (int x = 0 ; x < x_limit ; x++) {
for (int y = 0 ; y < y_limit ; y++) {
beds[toDraw][x][y] = susceptible;
}
}
beds[toDraw][100][100] = 1;
}
void draw()
{
update();
for (int x = 0 ; x < x_limit ; x++) {
for (int y = 0 ; y < y_limit ; y++) {
if (beds[toDraw][x][y] == recovered) stroke( brown );
else if (beds[toDraw][x][y] == susceptible) stroke( green );
else if (beds[toDraw][x][y] < k) stroke( red );
point( x, y );
}
}
toDraw = (toDraw == 0) ? 1 : 0;
}
boolean sick( int patient )
{
if ((patient > 0) && (patient < k)) return true;
return false;
}
void update()
{
int x, y, cell;
int toCompute = (toDraw == 0) ? 1 : 0;
for (x = 1 ; x < x_limit-1 ; x++) {
for (y = 1 ; y < y_limit-1 ; y++) {
cell = beds[toDraw][x][y];
if (cell == k) cell = recovered;
else if (sick(cell)) cell++;
else if (cell == susceptible) {
if (sick(beds[toDraw][x][y-1]) || sick(beds[toDraw][x][y+1]) ||
sick(beds[toDraw][x-1][y]) || sick(beds[toDraw][x+1][y])) {
if (prob(tau)) cell = 1;
}
}
beds[toCompute][x][y] = cell;
}
}
}The output of the SIR Model in Processing is shown in Figure 7. Note here that green pixels represent susceptible patients, red show the sick patients, and brown are the recovered patients. Given that the sickness lasts for four days and neighboring patients have a 20-percent chance of catching the disease, the disease randomly spreads throughout the hospital, infecting many but leaving islands of uninfected patients.
Figure 7. Output of the SIR Model in Processing

Going further
With luck, this article has whet your appetite for Processing and helped start your journey with this excellent open source language and environment. Part 2 of this series begins to explore some of the more advanced features of Processing and provide additional applications. In particular, it will look at object-oriented programming, image processing, particle swarms, and how to export your application as a Java applet.
Resources
Learn
- At Processing.org, you can download the latest version of the language and environment and get access to a full language reference. You can also learn where Processing is used. See how the Processing language compares to other languages, such as the Java language, as well.
- Processing originated from the Design By Numbers project by John Maeda at the MIT Media Lab. The project was created for visual designers and artists as an introduction to programming. Although the language has some significant differences, you'll find that Design By Numbers' environment heavily influenced that of Processing.
- The Cellular Automata Forest Fire Model and the SIR Model illustrate interesting and complex behavior from a simple set of rules.
- One of the best references for Processing is Processing: A Programming Handbook for Visual Designers and Artists (Casey Reas and Ben Fry, MIT Press, 20047). Also available is Getting Started with Processing (Casey Reas and Ben Fry, O'Reilly Media, 2010).
- To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
- Stay current with developerWorks' Technical events and webcasts.
- Follow developerWorks on Twitter.
- Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
- Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products, as well as our most popular articles and tutorials.
- The My developerWorks community is an example of a successful general community that covers a wide variety of topics.
- Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
Get products and technologies
- Innovate your next open source development project with IBM trial software, available for download or on DVD.
- Download IBM product evaluation versions or explore the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
- Participate in developerWorks blogs and get involved in the developerWorks community.
Comments
Dig deeper into Open source on developerWorks
developerWorks Premium
Exclusive tools to build your next great app. Learn more.
developerWorks Labs
Technical resources for innovators and early adopters to experiment with.
IBM evaluation software
Evaluate IBM software and solutions, and transform challenges into opportunities.
M. Tim Jones is an embedded firmware architect and the author of "Artificial Intelligence: A Systems Approach," "GNU/Linux Application Programming" (now in its second edition), "AI Application Programming" (in its second edition), and "BSD Sockets Programming from a Multilanguage Perspective." His engineering background ranges from the development of kernels for geosynchronous spacecraft to embedded systems architecture and networking protocols development. he is a platform architect with Intel and author in Longmont, Colo.