25 life-saving tips for Processing Posted by Amnon on January 28, 2012 · 46 Comments

Well, perhaps they won’t literally save your life. But they surely will help you write your sketches easier, faster and more efficiently! This post will be covering tips, tricks and other need-to-know information about Processing. I’ve also included many runnable code examples. Please note that my somewhat arbitrary list is mainly intended for beginners and is by no means definitive. Feel free to share your own tips, tricks and suggestions in the comments below! 😉

1. frameCount, millis(), modulo % and noise

Let me start with a few functions that in themselves and in combination are extremely useful. Since they’re often used together, it’s easier to combine them in one tip and one code example. But know there are countless other uses for these functions. frameCount is a simple number that increases by one on each frame. Apart from it’s informative quality it can generate change in your sketch. Millis() is something similar. It’s the number of milliseconds from the start of the sketch. Because it does not depend on the frameRate it is more accurate. This makes it very useful for precise timing (also see tip 15). Modulo is a somewhat non-intuitive function that gives the remainder when one number is divided by another. When you see it in action, it’s easier to understand. Finally, noise is an implementation of perlin noise. It’s semi-random nature makes it a great tool for achieving harmonious changes in movement, color, shape or anything else. All of these functions are highly recommended. For a very basic use of each, check out the following code example (and the examples that come with Processing, such as Basics > Math).

float x, y, r, g, b, radius; int timer; void setup() { size(500, 500); background(255); noStroke(); smooth(); } void draw() { // use frameCount to move x, use modulo to keep it within bounds x = frameCount % width; // use millis() and a timer to change the y every 2 seconds if (millis() - timer >= 2000) { y = random(height); timer = millis(); } // use frameCount and noise to change the red color component r = noise(frameCount * 0.01) * 255; // use frameCount and modulo to change the green color component g = frameCount % 255; // use frameCount and noise to change the blue color component b = 255 - noise(1 + frameCount * 0.025) * 255; // use frameCount and noise to change the radius radius = noise(frameCount * 0.01) * 100; color c = color(r, g, b); fill(c); ellipse(x, y, radius, radius); }

2. math, logical and relational operator shortcuts

Any program will use operators. So since you will be using them a lot, it’s good to know shortcuts that will keep your code shorter and save you some typing. Let me walk through them quickly. First, you can write x = x + 10 shorter as x += 10. Exactly the same can be done with all other mathematical operators like substraction, multiplication and division. Second, when you want to add (or substract) 1, there is an even shorter way to write it: x++. Third, when checking if something is true or false, there is no need to fully write it out, so: if(something == true) is the same as: if (something). Fourth, to negate a statement (aka if NOT something), you can put an exclamation mark in front of it: if (!something). Check out the following code example.

int x = 0; x = x + 10; x += 20; x++; println("x = " + x); int y = 90; y /= 3; y++; y *= 2; println("y = " + y); boolean feelingPositive = true; // change this to false to go Doh! if (feelingPositive) { println("Yeah!"); } if (!feelingPositive) { println("Doh!"); }

3. math with ints

A very common mistake is doing math operations on integers and expecting a floating number outcome. Obviously, this won’t happen. When you divide an int by another int, the result will be an int. If you want a floating number outcome, then one of your numbers should be a float. Or you have to specifically tell the program that you want a floating number outcome. Check out the following code example and notice the difference.

println(1 / 3); println(1.0 / 3); println((float) 1 / 3);

4. frameRate

Processing’s frameRate is by default capped at 60 fps. You could say that’s the default top speed of the sketch. If you want to make it run faster, you can set the maximum frameRate manually. To get the actual frameRate, you can use frameRate. I often find it useful to display the frameRate in the sketch window title. Check out the following code example.

float x, y, radius; void setup() { size(500, 500); background(255); smooth(); frameRate(200); } void draw() { x = random(width); y = random(height); radius = random(200); fill(random(255)); ellipse(x, y, radius, radius); frame.setTitle(int(frameRate) + " fps"); }

5. loading specific files from an external input directory

Many applications use file input, for example an image or a data file. In most cases one can place these in the data directory and they become available to load into the program. However when a program uses a lot of input files, for example a large sequence of images or text files, this method is not very practical. Using an external directory is then more efficient. First, you won’t need to keep copies for every sketch (each sketch will use the same files from a central location). Furthermore, when working with many files you don’t want to type out all the individual filenames or be forced to name them sequentially. So you need a function to load the filenames, whatever they are. Finally, you might not want to load all the files in a directory. Maybe you only want the images or perhaps only the text files. In short, you will need the ability to filter by file extension. Fortunately you can do all of this with relatively little code. Check out the following code example.

String[] filenames; String fullPath = "C:/WINDOWS/Web/Wallpaper"; // use forward slashes void setup() { filenames = loadFilenames(fullPath); println(filenames); exit(); } String[] loadFilenames(String path) { File folder = new File(path); FilenameFilter filenameFilter = new FilenameFilter() { public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(".jpg"); // change this to any extension you want } }; return folder.list(filenameFilter); }

6. timestamp

When saving output to a file you often need a way to distinguish between different sessions. A great way to do this is by using a unique timestamp. Either for one file or one sequence. There are many ways in Processing and/or Java to create a timestamp. One way is to use the built-in Processing functions for year, month, day, hour, minute and second. Then format the final timestamp to keep the number of characters fixed (no matter if it’s made out of single or double digits). Check out the following code example.

String timestamp; void setup() { timestamp = year() + nf(month(),2) + nf(day(),2) + "-" + nf(hour(),2) + nf(minute(),2) + nf(second(),2); println(timestamp); exit(); }

7. fast image sequence saving

If you want to save your visual output to a file you can use the save() or saveFrame() funtions. In addition you could use a timestamp or frameCount to distinguish between files. The saveFrame function automatically uses the frameCount. When you put this function at the end of draw it will save each frame to an image file. The bigger your output, the more it slows down your sketch. While there is no magic solution, the fastest image format to save an image sequence is… TGA. Bet you didn’t see that one coming. Since this is an uncompressed format it saves much faster than for example JPG and it also provides 100% quality. The price you pay is the size of the output files. Of course there are situations when even this will not work out and specialist software such as fraps is needed.

float x, y, radius; void setup() { size(500, 500); background(255); smooth(); } void draw() { x = random(width); y = random(height); radius = random(200); fill(random(255)); ellipse(x, y, radius, radius); saveFrame("output-####.tga"); // will save each frame with the frameCount }

8. slow fade & simulated motion blur

Most Processing sketches use a background call at the beginning of the draw() loop to clear the screen each frame. A handful use the technique of aggregate drawing, whereby every frame adds imagery much like the canvas of a painter. But what if you want something in between: slowly fading shapes or motion trails. For these cases, you can use a semi-transparent rectangle. Check out the following code example.

void setup() { size(500, 500); noStroke(); smooth(); } void draw() { fill(255, 10); // semi-transparent white rect(0, 0, width, height); fill(random(255)); ellipse(mouseX, mouseY, 100, 100); }

9. combining 2D and 3D drawing

What if you want a 2D background behind a 3D sketch? Or put a 2D display on top of a 3D sketch? If you try to do this, you will quickly find that the 3D settings make your life difficult. The solution is to reset everything to basic 2D temporarily by placing the necessary code at the beginning or end of the draw loop() respectively. Different situations, will require slightly different solutions. But useful techniques are disabling the depth test with hint, resetting the camera(), turning off the lights, and sometimes using pushMatrix and popMatrix. Check out the following non-runnable code snippet.

void draw() { // 3D code hint(DISABLE_DEPTH_TEST); camera(); noLights(); // 2D code hint(ENABLE_DEPTH_TEST); }

10. change the transparency of an image

If you want to change the transparency of an image, you could of course do this through pixel manipulations. However for uniform changes in the transparency, it’s quicker to use tint(). Check out the following code example.

PImage img; void setup() { size(500, 500); img = loadImage("input.jpg"); } void draw() { background(255); tint(255, 125); image(img, mouseX, mouseY); }

11. mirror images vertically or horizontally

As with the previous tip, if you want to change the orientation of an image, you could do this through pixel manipulations. However for a uniform orientation change another option is to use scale(). In a bigger sketch you can put it between push-popMatrix calls. Check out the following code example.

PImage img; void setup() { size(500, 500); img = loadImage("input.jpg"); } void draw() { background(255); scale(-1, 1); // this will flip everything! (read: also the coordinates) image(img, mouseX, mouseY); }

12. take full screen screenshots

If you only check out one code example, make sure it’s this one, it’s the most fun! It’s a quick ‘hack’ to get a full screen screenshot. Really full screen, so not just the sketch’s window. Click the mouse to toggle the quality (and speed). Check it out!

// note: For Processing 2.0 replace screen.width and screen.height by screenWidth and screenHeight respectively import java.awt.Robot; import java.awt.Rectangle; import java.awt.AWTException; PImage screenshot; boolean smoothOn; int x,y; void setup() { size(int(screen.width*0.85),int(screen.height*0.85)); frame.removeNotify(); frame.setUndecorated(true); } void draw() { if (smoothOn) { smooth(); } else { noSmooth(); } screenshot(); image(screenshot, 0, 0, width, height); } void screenshot() { try { Robot robot = new Robot(); screenshot = new PImage(robot.createScreenCapture(new Rectangle(0,0,screen.width,screen.height))); } catch (AWTException e) { } } void mouseMoved(){ x = int((float) mouseX/width * (screen.width - width)); y = int((float) mouseY/height * (screen.height - height)); x = int(x * 0.02 + frame.getLocation().x * 0.98); y = int(y * 0.02 + frame.getLocation().y * 0.98); frame.setLocation(x,y); } void mousePressed() { smoothOn = !smoothOn; }

13. keyboard text and number input

Allowing the user to input text can be a great addition to your sketch. For example to change text on the screen or to input search terms. While Processing provides the basic tools to realise this via the keyPressed() function, there are several tweaks required to make keyboard input an intuitive experience for the user. This mainly relates to keys that one does not want to use (such as CTRL, ALT and others) and keys that allow removing some or all characters in a string (BACKSPACE and DELETE respectively). Check out the following code example.

String myText = "Type something"; void setup() { size(500, 500); textAlign(CENTER, CENTER); textSize(30); fill(0); } void draw() { background(255); text(myText, 0, 0, width, height); } void keyPressed() { if (keyCode == BACKSPACE) { if (myText.length() > 0) { myText = myText.substring(0, myText.length()-1); } } else if (keyCode == DELETE) { myText = ""; } else if (keyCode != SHIFT && keyCode != CONTROL && keyCode != ALT) { myText = myText + key; } }

14. a simple menu and/or different screens

When you want to create a simple menu or perhaps a program that moves through different screens, the best way to do it is by using a switch. This is clearer and faster than the alternative if-else structure in these circumstances. A switch will allow the user to easily move back and forth through different screen, for example via keyboard or mouse input. To keep things clearly readable, my advise is to refer to seperate functions for each screen instead of putting all the code in the draw() loop itself. Check out the following code example.

int currentScreen; void setup() { size(500, 500); noStroke(); smooth(); } void draw() { switch(currentScreen) { case 0: drawScreenZero(); break; case 1: drawScreenOne(); break; case 2: drawScreenTwo(); break; default: background(0); break; } } void mousePressed() { currentScreen++; if (currentScreen > 2) { currentScreen = 0; } } void drawScreenZero() { background(255, 0, 0); fill(255); ellipse(100, 100, 400, 400); } void drawScreenOne() { background(0, 255, 0); fill(0); rect(250, 40, 250, 400); } void drawScreenTwo() { background(0, 0, 255); fill(255, 255, 0); triangle(150, 100, 150, 400, 450, 250); }

15. controlling the sketch through millis() or frameCount

Using millis() can be useful to start actions exactly when you want. Or to do the opposite: (temporarily) disable actions. Or to do something for a certain amount of time. You get the point. This was touched upon in the very first tip, here we take a little further. Check out the following code example to see how millis() and frameCount can be used to control what happens in your sketch.

boolean blinker; int timer = -3000; void setup() { size(700,400); textFont(createFont("Arial",30)); } void draw() { background(255); fill(0); text("you are in frame: " + frameCount,50,50); text(millis()/1000 + " seconds have passed since the start", 50,100); text("this text will be here forever",50,150); if (frameCount < 500) { text("this text will be here for 500 frames",50,200); } if (frameCount > 800) { text("this text will be here from 800 frames onwards",50,200); } if (millis() < 8000) { text("this text will be here the first 8 seconds",50,250); } if (millis() > 12000) { text("this text will be here from 12 seconds onwards",50,250); } if (frameCount % 12 == 0) { blinker = !blinker; } if (blinker) { text("this text will blink",50,300); } if (millis() - timer < 3000) { text("this text will be here 3 secs after pressing a key",50,350); } } void keyPressed() { timer = millis(); }

16. high resolution output

Sometimes you only need to draw to the screen. Sometimes you want to save that output. Sometimes you need to have that output in a very high resolution, for example when you want to print it. There are different ways to generate high resolution output. One can use the PDF export options. Or one could use one of the many different ‘hacks’ to create a high resolution copy of the regular draw() loop. Here is an example of one such technique.

void setup() { size(500, 500); } void draw() { background(255); smooth(); strokeWeight(10); fill(255, 0, 0); ellipse(width/2, height/2, 200, 200); } void keyPressed() { if (key == 's') { save("normal.png"); saveHiRes(5); exit(); } } void saveHiRes(int scaleFactor) { PGraphics hires = createGraphics(width*scaleFactor, height*scaleFactor, JAVA2D); beginRecord(hires); hires.scale(scaleFactor); draw(); endRecord(); hires.save("hires.png"); }

17. checking if the mouse is over a circle or rect

It may be useful to check if the mouse is hovering over a circle or rectangle. For example if you want to make a button or text input field. Of course the principles can be applied to collision detection as well. To check if the mouse is over a circle one can use the dist() function in Processing in combination with the circle’s radius. To check if the mouse is over a rectangle one can check the mouse coordinates against the sides of the rectangle. Check out the following code example.

void setup() { size(500, 500); noStroke(); smooth(); } void draw() { background(255); int rX = 40; int rY = 60; int rW = 150; int rH = 170; if (mouseOverRect(rX, rY, rW, rH)) { fill(0, 0, 255); } else { fill(255, 0, 0); } rect(rX, rY, rW, rH); int cX = 340; int cY = 280; float cD = 250; if (mouseOverCircle(cX, cY, cD)) { fill(0, 255, 0); } else { fill(255, 0, 0); } ellipse(cX, cY, cD, cD); } boolean mouseOverCircle(int x, int y, float diameter) { return (dist(mouseX, mouseY, x, y) < diameter*0.5); } boolean mouseOverRect(int x, int y, int w, int h) { return (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h); }

18. change the PRESENT mode background color

This does not refer to the background of the sketch (window), but rather to the background color that is used in the PRESENT mode (and for full screen applications). By default I believe it’s set to grey. But it’s possible to change this color to any RGB color you want. Remember, to see this in action you have to use Sketch > Present (CTRL+SHIFT+R). Check out the following code example.

void setup() { size(500, 500); frame.setBackground(new java.awt.Color(255,0,0)); } void draw() { background(frameCount % 255); }

19. disable the ESCAPE key

For a full screen application, one might want to disable the use of the ESCAPE key to prevent end-users from escaping the application, whether deliberately or by accident. Keep ‘em tight, right? Well, you can! Check out the following code example.

void setup() { size(500, 500); noStroke(); smooth(); } void draw() { background(255); fill(0); ellipse(width/2, height/2, 300, 300); } void keyPressed() { if (key == ESC) { key = 0; println("Trapped! Muhaha! ;-)"); } }

20. per-vertex color fills within a beginShape-endShape

Processing’s P2D, P3D and OPENGL render modes allow for individual fill colors per vertex in a beginShape-endShape. This allows you to easily create very smooth gradients. Check out the code.

void setup() { size(500,500,P2D); noStroke(); smooth(); } void draw() { background(0); beginShape(); fill(255,0,0); vertex(100,100); fill(0,255,0); vertex(400,100); fill(0,0,255); vertex(mouseX,mouseY); endShape(); }

21. breakShape

Disclaimer! breakShape has been undocumented, mysterious and unsupported ever since I started using Processing. But it’s still there hidden in the source code. Maybe this will change with Processing 2.0. But for now let me just mention this function that can create holes in a beginShape-endShape. 😉

void setup() { size(400, 400); smooth(); } void draw() { background(255); fill(255, 0, 0); ellipse(width/2, height/2, 200, 200); fill(255, 255, 0); beginShape(); vertex(0, 0); vertex(width, 0); vertex(width, height); vertex(0, height); vertex(0, 0); breakShape(); vertex(mouseX-100, mouseY-100); vertex(mouseX-100, mouseY+100); vertex(mouseX+100, mouseY+100); vertex(mouseX+100, mouseY-100); endShape(CLOSE); }

22. using arctangent to determine angle

The atan2() function can be used to compute the angle between two points, which -as you can imagine- may come in handy in many cases. Here is a code example.

int x, y; void setup() { size(500, 500); x = width/2; y = height/2; textSize(20); textAlign(CENTER, CENTER); noStroke(); smooth(); } void draw() { background(255); float angle = atan2(mouseY-y, mouseX-x); translate(x, y); fill(0); ellipse(0, 0, 100, 100); fill(255); text(int(degrees(angle)), 0, 0); rotate(angle); fill(0, 0, 255); ellipse(50, 0, 30, 30); }

23. constraining a point within a circle

There are always more ways than one to do something. I wanted to show a bit of vector math. Because once you start to use more mathematical operations, it pays off to learn about vectors. Either the basic PVector class that comes with Processing or if you wanna get serious (or lazy) the more elaborate Vec2D/Vec3D classes of Toxiclibs. The example below was an answer to specific question on the forum, how to constrain a point within a circle? As mentioned, there are multiple ways to do it, but using vectors makes it pretty easy. Check it out.

float x, y; float easing = 0.05; PVector circle = new PVector(250, 250); int diameter = 300; void setup() { size(500, 500); x = y = width/2; noStroke(); smooth(); } void draw () { background(51); fill(255); ellipse(circle.x, circle.y, diameter, diameter); PVector m = new PVector(mouseX, mouseY); if (dist(m.x, m.y, circle.x, circle.y) > diameter/2) { m.sub(circle); m.normalize(); m.mult(diameter/2); m.add(circle); } fill(0, 0, 255); ellipse(m.x, m.y, 6, 6); x = x + (m.x - x) * easing; y = y + (m.y - y) * easing; fill(255, 0, 0); ellipse(x, y, 24, 24); }

24. renderers (choose wisely)

At the moment Processing has four different renderers: JAVA2D, P2D, P3D and OPENGL. The advantage of different renderers is that each has it’s strengths and weaknesses. So it’s sensible to determine which renderer will work best for your situation. The first obvious difference is 2D versus 3D. JAVA2D is basically the best quality. P2D is the fastest for pixel manipulations. P3D is useful for basic 3D sketches. OPENGL is best for more elaborate 3D sketches. Choose the one that works best for your specific sketch. From Processing 2.0 onwards there will be only 2 renderers: JAVA2D and OPENGL. The main reason is that the developers want to focus their energy on two renderers (one for 2D, one for 3D) instead of having to divide their attention over four. In the short term there is some cost (the loss of the speedy P2D, some libraries will break until updated to work with 2.0). However in the long run there are greater benefits (higher quality renderers for both 2D and especially 3D).

25. libraries + java

I guess one of the greatest qualities a programmer can have is to be as lazy as possible! 😉 Kidding aside, besides useful code example there is a huge reservoir of existing code that can be directly used within Processing. First there are over 100 libraries that extend the capabilities of Processing in areas like sound, video, computer vision, data import/export, math, geometry, physics and many more things. Don’t reinvent the wheel! If that wasn’t enough, realise this: Processing is java. Yes, that’s right. Processing is java. Which means that all java code (and java libraries) can be used within Processing. A world of possibilities.

BONUS TIP: the knowledge base

One of Processing’s greatest strengths, besides it’s low entry barrier, is it’s extensive knowledge base. Use these invaluable resources to your advantage. Check the examples that come with processing and the ones that are available on openprocessing. Check out the wiki. And most importantly, search the forums. The current forum and all that came before. I speak from experience when I say they are a huge source of knowledge. And most questions HAVE been asked before. If all of this doesn’t get you what you need, you can always ask a question on the forum yourself.

Final note!

This post is meant to help you with all the little tips and tricks I have learned while using Processing. This is NOT the grand opening of a special helpdesk. The best way to get help is first to help yourself (aka figure it out or use the knowledge base for existing answers to your question) and second to ask the question on the Processing forum. I hope this post was helpful. Again, feel free to share thoughts or your own tips & tricks. Good luck!