2D to 3D
2D transformations
2D-transformations are methods that allow you to change the position, size, shape and persective of an image with relative ease. The following short introduction is loosely based on the more in-depth tutorial on Processing.org.
Translation
The Translate method moves everything on the screen to a new zero point, which is given to it as a parameter. The position of the new zero point is calculated in relation to the existing one (which is, to start with, at the top left corner of the screen). In the example below, the first translate (30, 20) switches (0, 0) to (30, 20). Translation is a convenient way of moving everything on the screen in equal measure, without having to change the coordinates of individual shapes by hand.
size(400, 400);
rect(0, 0, 50, 50); // draws a white square at the old zero point
translate(300, 200);
fill(255, 0, 0);
rect(0, 0, 50, 50); // draws a red square at the old zero point
// (0+300, 0+200) = (300, 200) is now (0, 0)
translate(-150, -150);
fill(0, 255, 0);
rect(0, 0, 50, 50); // draws a green square at the new zero point
// (300-150, 200-150) = (150, 50) is now (0, 0)
Rotation
Here we'll have a quick look at rotation and combining different transformations. We'll also look at rotation within a draw loop.
int i = 0;
void setup(){
size(500, 500);
noStroke();
}
void draw(){
fill(255, 10);
rect(0, 0, width, height); // see fading: draw a translucent square
// over the entire screen
fill(100, 100); // and make it a translucent grey
translate(width/2, height/2); // move the image to the centre of the screen
rotate(radians(i)); // convert i to radians and adjust image
// position accordingly
rect(0, 0, 50, 50); // draw a square at (0, 0)
// which is now at the centre of the screen
i++; // increase the value of i by one
// when i exceeds 360, the shape
// has gone around itself once
}
The Radians-method converts the degrees given as parameters into radians.
The square now spins around one of its angles. You can try tweaking its position a little. What happens if you position the square at (-25, -25) instead of (0,0)? How about if you switch the translate and rotate methods around?
Scaling
We'll now change the scale of the shape and add a little interactivity by using the X-coordinate of the mouse.
void setup(){
size(500, 500);
background(255);
noStroke();
}
void draw(){
fill(255, 100);
rect(0, 0, width, height); // fading
fill(100, 100);
// scales the shape in relation to the value of mouseX
// you can try changing the value of the constant 0.2
scale(mouseX/(width*0.2));
rect(0, 0, 100, 100);
}
Shear
Let's try to tilt shift the angle of the the photo. We'll do this by using two commands : shearX ja shearY.
void setup(){
size(500, 500);
background(255);
noStroke();
}
void draw(){
fill(255, 100);
rect(0, 0, width, height); // fade
fill(100, 100);
// tilt photo in relation to both x and y
// depending on mouse location
// you can also try to change the constant 0.9
shearX(mouseX/(width*0.9));
shearY(mouseX/(height*0.9));
rect(50, 50, 100, 100);
}
Execution Order of Transformations
You may have noticed before, that if the rotate-method is run before the translate-method, the outcome is different then with reverse order. The most common order to run transformations is: Translate, Rotate, Scale, but feel free to experiment!
There are two matrix operations in Processing: pushMatrix and popMatrix. PushMatrix sets the frame now to be updated and popMatrix returns the edited frame on screen. You can have a closer look at how these methods function in the Processing.org tutorial 2D Transformations if you want to, but at this stage you can also manage with the knowledge that you should call the pushMatrix-method before making transformations and the popMatrix after.
3D Graphics
Almost all the following examples will be built on top of the 2D transformations. In this material, we’ll only scratch the surface as we go through an example. The subject is so vast, that you should go through the Processing.org P3D-tutorial and search for more info on the web.
Box
In 3D graphics we need to define a renderer in the size-method, because the Processing default renderer won't be enough for what is needed for all three dimensions. We can produce a simple box object by defining the renderer in the size-method, moving the image with the translate-method (necessary in 3D graphics!) and by drawing the box with a box-method. Let's add a few mouse-reacting rotate-methods, so we can perceive the three dimensions of the photo.
void setup(){
// define P3D-renderer in the size method
size(500, 500, P3D);
fill(200);
noStroke();
}
void draw(){
background(0);
// move the things we're drawing to a preferred place
translate(width/2, height/2, 0);
// mouse moving rotates the image
rotateX(mouseX*0.01);
rotateY(mouseY*0.01);
// draw a box with the size 100
box(100);
}
Our box is still a strange lump and there's really nothing new in twisting something around. So let's add lights to the program with the lights-method and make changes of perspective possible using the perspective-method. Two new variables make it possible to move the camera around by using the arrow keys.
// field of view in radians
float fov = PI/3.0;
// camera on the x-axis
float posx = 0;
void setup(){
size(500, 500, P3D);
fill(200);
noStroke();
}
void draw(){
background(0);
// lights() turns on default lights
lights();
// define perspective: area of view,
// width to height ratio, closest to furthest
// drawable level on the z-axis
perspective(fov, float(width)/float(height), width/2.0, height*2.0);
// take posx into account in the translate method
translate(width/2+posx, height/2, 0);
rotateX(mouseX*0.01);
rotateY(mouseY*0.01);
box(100);
}
void keyPressed(){
// use arrow keys to define perspective
// and camera place
if (keyCode == UP){
fov -= 0.1;
} else if (keyCode == DOWN){
fov += 0.1;
} else if (keyCode == LEFT){
posx -= 5;
} else if (keyCode == RIGHT){
posx += 5;
}
}
Below is the final program. Try turning the box with your mouse and moving the camera with the arrow keys.