Processing uses a Cartesian coordinate system. It is important to note that the zero point is in the upper left corner in processing. The X axis is from left to right and the Y axis is from top to bottom. While this might seem odd, it comes from the tradition that bitmaps were always read in that order. In computer graphics the cartesian coordinate system is almost always used. This provides some convenience, so you can also move, scale, or even rotate coordinate systems. I can simplify the drawing of objects in many cases. Imagine an animation of a car. The wheels should rotate naturally. If you draw this per processing you must always add the current position of the body to the wheels and then turn them. If you do this with the change of the coordinate system, this is a lot simpler. Here you just have to move the coordinate system, draw the car body and then move the coordinate system again for the respective wheels. Such coordinate system changes are called transformations. There are three basic types:
- Translation – shifting
- Rotation
- Scaling
It should be noted that such transformations are not commutative. That means the order that you make the transformations will effect the output. In processing, the commands look like this:
translate(float x, float y) rotate(float angle) scale(float xScale, float yScale)
If you work in 3D mode, there is a third parameter for the z axis.
Frequently, local and global coordinate systems will be used. The global coordinate system is the original coordinate system, in processing this is the one fixed to the upper left corner. If the original coordinate system is transformed, then the result is local coordinate system (in reference to the global). To switch between these coordinate systems, there are two commands from Processing:
- pushMatrix() – save the current coordinate system
- popMatrix() – return to the last saved coordinate system
These two commands work according to the stack principle. This is an very old form of working with computer memory. Just imagine a stack of graph paper: when you call pushMatrix, the stack is increased by one sheet. On this page we would describe the current data of our coordinate system. Now you can rotate, scale and transform as you want. If you now want to bring the coordinate system back to the position of the last pushMatrix call, you must call popMatrix. Now this sheet is removed from the stack.
With an example program, this should be easer to understood:
void setup() { size(400,400); // def. window size strokeWeight(15); // line thickness } void draw() { background(255); // def. background colour float radius = dist(mouseX,mouseY,width/2,height/2); // calculate the distance from the mouse curser to the center of the screen radius = map(radius,0,width,1,4); // modify the radius to keep it within a specific range. pushMatrix(); translate(200,200); rotate(calcAngle()); scale(radius); smiley(); // function call popMatrix(); pushMatrix(); translate(30,30); scale(.2); smiley(); // function call popMatrix(); } // funktion void smiley() { noFill(); ellipse(0,0,180,180); // head fill(0); ellipse(0 - 30,0 - 30,20,20); // left eye ellipse(0 + 30,0 - 30,20,20); // right eye noFill(); arc(0,0,100,100,radians(20),radians(180-20)); // mouth } // calculate the angle from the screen middle to the mouse cursor // the angle is in radians float calcAngle() { return -atan2(mouseX - (width / 2),mouseY - (height / 2)); }
This example introduces a couple of new things starting on line 13:
float radius = dist(mouseX,mouseY,width/2,height/2);
Here the distance from the mouse pointer to the window center is determined (see Pythagoras).
radius = map(radius,0,width,1,4);
The original range is from 0 to the width of the window. The target range is from 1-4. Now radius is transformed from original range to the target range.
Exercise 8
Modify the program so a small smiley orbits around he big smiley, in the direction of the mouse position.