An Introduction To Programming With Processing


Repetitious Active Mode
The setup() function must always precede the draw() function, and is used to define the initial properties of the sketch such as the size of the sketch. The size() function when used within an active mode sketch must always follow the setup() function before any other statements. If we had images to display in our sketch assigning them to object variables would generally be done within the setup() structure, we'll have a look at this technique a little later. The draw() function repeats once every 60th of a second by default, but this behaviour can be changed with the frameRate() function which would be called within the setup() structure too. Within the println() function you might have noticed something a little different, two new commands, mouseX and mouseY are system variables in Processing that store the X and Y position of the mouse when it is over the window the sketch is running in. When used within a sketch they simply return a number that is either the respective X or Y coordinate of the user's mouse. It is also worth noting that it is necessary for the println() function to be repeated within the draw() structure because whenever the user moves the mouse within the Display Window a new value for the mouse's X and Y position replaces the old value for the previous position of the user's mouse. If this command was within the setup() function Processing would only print the mouse's X and Y values once and not again. Although this is perfectly valid code it, is not very useful to us because if the user has moved the mouse since the start of the program (when setup() ran for the first and only time) the current position of the user's mouse would not have been updated thereafter. The statement to update the mouse's X and Y position would not have been repeated so according to the sketch the X and Y position of the mouse would be the same as when the program first started, this is obviously not the case if the user has moved the mouse.
Experiment 01
The mouseX and mouseY system variables are important keywords in determining the interactive nature of many sketches so lets attempt to use them in another way that is more directly related to the visualization nature of sketches. Add the following statement before the println() statement:
line(0,0, mouseX, mouseY);
After running the sketch you should be able to recreate an image within the Display Window like the preceding image. The line() function is used to draw a straight line in Processing and accepts four parameters in the form of the starting point of the line's X and Y coordinates and the end point of the line in terms of X and Y coordinates. In our sketch we made the starting point of the line the origin of the sketch, that is (0, 0) or zero X and zero Y and we made the end point of our line equal whatever the mouse's current X and Y values are. There are infinite ways of using the mouseX and mouseY system variables to create interesting and interactive qualities within a sketch, and they don't always have to relate to positional data as in our previous statement. For example, if we wanted to use the mouse's X value to determine the greyness of the line we could add the following statement to effect the strokes color, which we will add before the line() statement:
Experiment 02
Remember that the stroke() function used in this way with only one parameter accepts values between 0 to 255 which relates to the greyness of the following strokes that are drawn. So because the size of our sketch is 510 pixels across our mouse's X position will, in the context of this sketch, return a value between 0 and 510 for the mouseX system variable, as any value greater than this would mean that the mouse is no longer positioned over the sketch. Bearing this information in mind we can use what we know about the width of the sketch and divide this value by 2 so that we never receive a value greater than 510/2 or 255 which is white, when input as a parameter of the stroke() function. This is a very simple example of mapping one value to another but Processing conveniently provides us with a more sophisticated method of mapping values by use of the map() function which we will look at in more detail later.
Experiment 03
Try experimenting with the mouseX and mouseY system variables until you are comfortable with them as we will be using them quite regularly in our following sketches. For example try combining the previous sketch with an ellipse that attaches itself to your mouse and has an interactive transparency feature.
fill(50, 60, 127, ??/2);    //Here's a hint...
ellipse(??, ??, 50,50);        //and another.
As you might remember, the order in which commands are issued in many programming languages is really quite important. So when Processing reads your code it is important that commands are issued to Processing in the correct order, for example we would not want to have a command that updates the color of an ellipse's fill after the ellipse has been drawn to the Display Window. We are already aware of this from our static mode sketches, however in active mode even if you do have a fill() command after an ellipse() command to update that ellipse's fill your results sometimes might be more forgiving.
Ambigious Code
As active mode requires that the code within the draw() structure is repeated there remains a history from one execution of this code to the next. What that means is, even though the fill() command is issued after the ellipse() command when the program repeats the next time around Processing will remembers what the value of the fill was set to in the previous execution and updates your ellipse in the current cycle to match that command of the previous execution. Currently this might not seem like a big issue to you because you are ultimately getting the results that you want, but this is at the expense of creating ambiguity within your program. This could also lead to possible errors later in the programs development cycle, and is therefore not a recommended methodology for several reasons.
Functional Unambigious Code
Firstly, it is not clear within the order of such a program why the fill() command is being called. Whereas if the fill() is issued before ellipse() it is clear that it is meant to effect the color of the fill of the next ellipse that is drawn to the Display Window. Secondly, if there are other values depending on your ellipse's fill being a particular color at that point in time, and these values precede the fill() command these values will always be calculating their results based on the color of the ellipse's previous fill color and not the current color for that particular cycle. This color only becomes evident the next time the program repeats, and by then the visual representation of the fill will no longer match the values that are used in calculations preceding it. This could lead to inaccurate calculations such as division by zero which could cause your program to halt or even worse to crash. Needles to say that although you can get the results you are hoping to achieve by structuring your program in a manner that contradicts appropriate ordering, you might in effect be causing yourself more problems in the long run than necessary. Always consider how the ordering of your commands and structure of your program can be improved.
Ordering statements appropriately can contribute significantly to the readability of your code.