|
Chapter:
Transforms
What is the Transformation Matrix
The term matrix simply refers to a grid of numbers, which is how
Processing stores information about the coordinate system in memory.
For example a matrix can be represented as:
We would call this a 4 x 5 matrix meaning that it is made up of 4 rows
and 5 columns. This is not an actual representation of a matrix that
Processing uses to calculate transforms but simply an example of what a
matrix could look like, in fact the matrices that Processing uses are
simpler than the previous matrix example.
You might hear the term transformation matrix used on occasion, this is
just simply referring to the numbers that make up the matrix that the
matrix representing the current coordinate system must be processed
through in order to produce the representation of the coordinate system
in it's transformed state.
Although this might sound like a bit of a tongue twister, the concept
is less complicated when you think of it in graphical form. Following
is an example of what this might look like as a graphical
representation, remember the numbers are purely illustrative, and not
intended to represent actual numerical data and patterns that
Processing calculates:
A Programmatic
Solution For Rotating Wheels
Now that we have an idea of what the cart is going to look like when
it's moving, lets concentrate on getting the wheels to rotate and
translate.
pushMatrix();
translate(xPos -75 , 250 +25);
rotate(xPos/wheelBd.width);
image(wheelBd, 0, 0);
popMatrix();
image(cart, 0, 0);
image(wheelFd, -95, 35);
As you can see we have removed the image() function that renders the
wheelBd object and placed it between a pushMatrix() and popMatrix()
function pair. Between pushMatrix() and popMatrix() we are free to use
translate() and rotate() to modify the coordinate system before
rendering wheelBd with a call to the image() function. When we
originally rendered the three images making up the cart, we had to
offset the back wheel and front wheel so that they we in the correct
places in relation to the position of the main cart. When performing
transformations to an image it's best the have the image transform from
the origin. As a result the X and Y parameters of the image() function
used to render the image should remain at 0, and translations should be
used when the image's X and Y coordinates need to change. This is often
the simplest and most logical approach to working with transforms as it
ensures that the image's relative distance to the origin is not
modified which could lead to unexpected results.
Transforms are
more predictable when the image() function's parameters are set to 0, 0
for X and Y. Offsets in these parameters will often result in
undesirable transformations.
By setting the imageMode() function to CENTER and the X and Y
parameters for the image() function to 0 and 0 we can be assured that
the image of the wheel is going to be rendered with it's center at the
origin. This is important because all transformations are relative to
the origin, so that when we rotate the wheel it will appear to rotate
from it's center, this is also due to setting imageMode() to
CENTER and not leaving it at it's default of CORNER which would have
resulted in the wheel appearing to rotate from it's top left hand
corner. Bearing this in mind it is also important that the images that
we use for the wheels are square in shape, in other words the image's
width should match the same image's height. This creates the impression
of the wheels being flat on the ground when they start to rotate. The
following statement, is how we remove the image() functions offset and
are still able to match the position of the cart with the mouse's X
value:
translate(xPos -75 , 250 +25);
The xPos variable has not changed in terms of how it is applied in this
sketch, the difference is that the X and Y parameter values that were
used in the image() function to render the wheel have now been added to
the translate() function's X and Y parameters. The rotate() function
follows:
rotate(xPos/wheelBd.width);
As the xPos variable changes relative to the distance the cart has
moved we can use the changing properties of this variable to make the
wheels rotate. We can then divide this number by the width of the wheel
image which is also the diameter of the circular shape of the wheel.
This expression is based on the formula for pi which is pi =
circumference/diameter, but it is worth noting that the value returned
from our modified expression is not equal to pi, as this would be a
constant value as a result xPos is substituted for the circumference of
the circle as this will yield a value that changes relative to the
distance that the cart has traveled.
We can then render the image at the origin after the coordinate system
has been transformed, so the image appears to have moved because the
coordinate system it is rendered relative to has, by then, been
transformed.
image(wheelBd, 0, 0);
Finally use popMatrix() to reset the coordinate system back to it's
original transformations.
We can then continue to render the main cart and foreground wheel using
the same techniques, and not have transformations from one rendering
effect another.
In the final cart.pde example I've added a shadow, try to figure out
how you would go about creating this effect before looking at the code.
Here's a hint, I've added four additional images to the sketch.
The completed
cart.pde sketch
|
|