An Introduction To Programming With Processing

A Convenient Animation System

Smile Sketch Revisited
So if we still have the ability to modify components of a sketch via their own X and Y parameters what's the benefit of having transforms? Transforms can save us a lot of unnecessary work, make our code a lot easier to read and provide us with functionality that would not be possible without them. Lets have a look at an example of how this works. In order to see the benefits that transforms have on our code we'll revisit the smile sketch from our static sketch examples at the beginning. If you recall, the purpose of the sketch was simply to draw a smiley face to the Display Window in static mode with some other components. We're only interested in the smiley face, so first we're going to adapt the sketch for active mode by including the drawing of the face within the draw() structure:
void setup(){
  size(640,480);
}

void draw(){
  background(127);
  //Drawing the face
  fill(191,233,255);
  ellipse(width/2, height/2, 100, 100);
  //smile
  noFill();
  stroke(255,0,0);
  arc(width/2, height/2 + 10, 50, 50, 0, PI);
  //eyes
  stroke(0,0,0);
  fill(0,255,0);
  ellipse(width/2-15, height/2-15, 20, 30);
  ellipse(width/2+15, height/2-15, 20, 30);
}
As you can see nothing surprising about the sketch, but what if we wanted to animate the smiley face by moving it across the Display Window, or attaching it to the mouse? This could become quite a cumbersome task as every component of the smiley face that has X and Y parameters would have to be updated for every frame. To give you an indication of how much extra work this is here's a look at what sort of changes in the sketch would need to be implemented if we wanted to attach the smiley face to the mouse:
void setup(){
  size(640,480);
}
void draw(){
  background(127);
  //Drawing the face
  fill(191,233,255);
  ellipse(mouseX, mouseY, 100, 100);
  //smile
  noFill();
  stroke(255,0,0);
  arc(mouseX, mouseY + 10, 50, 50, 0, PI);
  //eyes
  stroke(0,0,0);
  fill(0,255,0);
  ellipse(mouseX-15, mouseY-15, 20, 30);
  ellipse(mouseX+15, mouseY-15, 20, 30);
}
As you can see almost every second line of code had to be updated within the draw() structure. Now imagine if you had a whole character you wanted to draw and how much additional work something like that could amount to? With transforms making a change like this to your code is easy:
void setup(){
  size(640,480);
}
void draw(){
  background(127);
  translate(mouseX-width/2, mouseY-height/2);    //transform
  //Drawing the face
  fill(191,233,255);
  ellipse(width/2, height/2, 100, 100);
  //smile
  noFill();
  stroke(255,0,0);
  arc(width/2, height/2 + 10, 50, 50, 0, PI);
  //eyes
  stroke(0,0,0);
  fill(0,255,0);
  ellipse(width/2-15, height/2-15, 20, 30);
  ellipse(width/2+15, height/2-15, 20, 30);
}
Notice that only one additional line of code was needed to accommodate for this update, the rest of the code remained unchanged. The additional statement is:
translate(mouseX-width/2, mouseY-height/2);
This statement simply uses the translate() function, with two parameters relating to X and Y. The X parameter tells Processing to “move” the entire coordinate system to the position of the mouse's X value then to subtract half the width of the Display Window from this value. The reason we need to subtract half the width of the Display Window from the mouseX system variable is because our entire sketch was originally made to draw the smiley face in the center of the Display Window.
Transform Offset 01
Transform Offset 02
As the coordinate system is transformed, it's origin can exist within the boundaries of the Display Window or outside of these boundaries.