Translation

 < Day Day Up > 

Let's start with the simple motion of moving objects left, right, up, and down on a flat 2D screen. The fancy name for moving objects in these directions is translation . Objects can be translated using both matrix addition and matrix multiplication. If all you plan to do is translate an object, you should definitely use matrix addition, because it is by far faster and easier. However, if you plan to scale and/or rotate your object in the same frame, you have to perform the translation using matrix multiplication instead. Let's tackle the addition method first.

Most people already have an intuitive feel for translation using addition after working with the Cartesian coordinate system. Suppose you had an object at point P(1,2) and you wanted to move it three units to the right and one unit up. What would you do? Well, if you add 3 to the x-coordinate and 1 to the y-coordinate, the object would end up three units to the right and one unit up. That gives you a new location of (1+3,2+1) = (4,3). You can indicate the new position with P', so your object would end up at point P'(4,3) after translating three to the right and one up.

That approach is simple if you're translating only one point or even just a few points. However, most models in games are defined by hundreds, if not thousands, of points, so you need a more systematic way of adding 3 to every x and 1 to every y . You could set up a loop and perform the following on each point:

x '= x +3

y '= y +1

This can be rewritten with matrices:

graphics/06equ01.gif


Remember that when adding matrices you just add corresponding entries, so the matrix format is really the same as the two equations above it. The matrices are more efficient for organizing values in code, so you can set up a loop that inputs the original location and returns the new location of each vertex.

You might not always know the numeric values of the change in x and the change in y when you set up the code. You might have to wait for user input to determine how far you want the object to move. That's fine. Just set up a generic matrix equation and then plug in the values as soon as they become available.

Earlier in this book, we used the delta symbol ( D ) for "change in," but there's no delta key on the keyboard, so most programmers use dx for change in x and dy for change in y . This leads to the general form for translation by addition.

2D Translation by Addition

graphics/06equ02.gif



NOTE

The values for dx and dy are not restricted to positive numbers . If dx is negative, it just indicates to the left instead of to the right, and a negative dy indicates down rather than up.


Example 6.1: 2D Translation by Addition

Set up a general matrix equation that will move 2D objects 50 pixels to the right and 100 pixels down on the computer screen, and then use it to move a triangle with vertices at A(20,30), B(0,200), and C(300,400).

Solution
  1. Set up the matrix equation. To move 50 pixels to the right and 100 pixels down, dx must be 50, and dy must be 100 (negative because it's down):

    graphics/06equ03.gif


  2. Now you have to plug in each old point and add the matrices to see where it moved. First, plug in the old location of vertex A(20,30):

    graphics/06equ04.gif


    So A' is the point (70,70).

  3. If you repeat step 2 with the old locations of B and C, you get the new locations B'(50,100) and C'(350,300). By moving all three vertices, you have moved the whole triangle.

  4. Figure 6.1 shows the old location with dashed lines and the new location with solid lines.

    Figure 6.1. Triangle ABC before and after translation.

    graphics/06fig01.gif

In Example 6.1 you translated a simple triangle with three vertices. Keep in mind, however, that most models are defined by many more vertices than that. Most polygonal models are covered by hundreds (or thousands) of triangles , but if you can translate one triangle, you can translate many.

You can also translate objects in 3D simply by adding one more entry to each matrix for the z-coordinate.

3D Translation by Addition

graphics/06equ05.gif



Example 6.2: 3D Translation by Addition

Set up a general matrix equation that will move 3D objects 100 pixels to the left, 200 pixels up, and 50 pixels back (behind the screen), and then use it to move a triangle with vertices at A(40,0,100), B(0,350,200), and C(100,200,10).

Solution
  1. Set up the matrix equation. To move 100 pixels to the left, 200 pixels up, and 50 pixels back, dx = 100, dy = 200, and dz = 50. (If you can't remember which direction is positive or negative, you can always flip back to Chapter 1, "Points and Lines.")

    graphics/06equ06.gif


  2. Now you have to plug in each old point and add the matrices to see where it moved. First, plug in the old location of vertex A(40,0,100):

    graphics/06equ07.gif


    So A' is the point (60,200,50).

  3. If you repeat step 2 with the old locations of B and C, you get the new locations B'(100,550,150) and C'(200,400,60). By moving all three vertices, you have moved the whole triangle.

Translation by addition is pretty straightforward. Here is an example of how to translate a 3D point using addition:

 Matrix3X1 translate3DByAddition(Matrix3X1 start, Matrix3X1 trans)     {       Matrix3X1 temp;       temp = addMatrices(start,trans);       return temp;     } 

It is much more common to translate 3D points in games using matrices than it is 2D values. Generally speaking, a basic unit of a game that might represent the player will contain an x and y value. For example, if the player needs to have a position set 10 units to the right, one way to do this is to get away from the matrix notation:

 Player.setX(Player.getX()+10); 

If you are feeling comfortable with the matrix notation, feel free to keep it. It will actually be more beneficial when the emphasis comes to working with 3D points as well as rotation in 2D.

Again, if all you need to do is translate an object, use matrix addition. However, if you plan to also scale or rotate the object, you need to use matrix multiplication. You can set up a matrix equation in much the same way. Then, all you need to do is plug in each original location one at a time and multiply the matrices to find the new location.

2D Translation by Multiplication

graphics/06equ08.gif


where dx = change in x and dy = change in y .


Notice that the old point and the new point have an extra 1 on the end. It's not actually part of the point, but it needs to tag along for the matrix math to work. You might want to research "homogeneous coordinates" for further explanation.

Also, take note of the order in which the matrices are multiplied. If the order were switched (old point * translation matrix), the product would no longer be defined, and the program would crash. Remember from Chapter 5, "Matrix Operations," that the order in which you multiply matrices is critical. The number of columns in the first matrix must equal the number of rows in the second matrix. In this case, you must set it up to be a 3x3 times a 3x1, not the other way around.

Make sure that the matrix equation is always set up in that ordertranslation matrix * old point.

Let's repeat Example 6.1 using matrix multiplication and see if we get the same results.

Example 6.3: 2D Translation by Multiplication

Set up a general matrix equation (using matrix multiplication) that will move 2D objects 50 pixels to the right and 100 pixels down on the computer screen, and then use it to move a triangle with vertices at A(20,30), B(0,200), and C(300,400).

Solution
  1. Set up the matrix equation. To move 50 pixels to the right and 100 pixels down, dx must be 50, and dy must be 100 (negative because it's down):

    graphics/06equ09.gif


  2. Now you have to plug in each old point and multiply the matrices to see where it moved. First, plug in the old location of vertex A(20,30):

    graphics/06equ10.gif


    So A' is the point (70,70), which is exactly what you found before.

  3. If you repeat step 2 with the old locations of B and C, you get the new locations B'(50,100) and C'(350,300), just like last time. By moving all three vertices, you have moved the whole triangle. Notice that it ends up moving to the same place, as it did in Example 6.1.

If you look closely at the matrix multiplication, you can see the important role that the extra 1 plays. Notice the dot product that you calculated for x '. You kept the old x (multiply by 1), ignored the old y (multiply by 0), and added dx (multiply by 1). Then, to calculate y ', you ignored the old x , kept the old y , and added dy . You needed that extra 1 to add the dx and dy .

The same thing happens when you translate 3D objects using matrix multiplication.

Let's take a quick look at one way to handle this in code. Here is a function that will multiply a 2D point using matrix multiplication:

 Matrix3X1 translate2DByMultiplication(Matrix3X1 start,float dx, float dy)     {          Matrix3X3 temp;          Matrix3X1 result;          //Zero out the matrix.          temp = createFixed3X3Matrix(0);          //setup the 3x3 for multiplication;          temp.index[0][0] = 1;          temp.index[1][1] = 1;          temp.index[2][2] = 1;          //put in the translation amount          temp.index[0][2] = dx;          temp.index[1][2] = dy;          result = multiplyMatrixNxM(temp,start);          return result;      } 

There are some important things to note here. First of all, we go through and set up the positions [0][0];[1][1];[2][2] to the value of 1. The reason for this is so that the dot product will work out. Then we set the additional positions by the amount we want to move by in each direction. Once that is settled, we multiply the 3x3 matrix against our matrix that was holding our original position. The step to setting up the matrix for proper evaluation will become much more important as we move toward 3D multiplication.

3D Translation by Multiplication

graphics/06equ11.gif


where dx = change in x , dy = change in y , and dz = change in z .


The process for 3D is the same as that for 2D; the only difference is that you're now using a 4x4 translation matrix. Notice that the extra 1 is still along for the ride so that the matrix math works out.

Example 6.4: 3D Translation by Multiplication

Set up a general matrix equation (using matrix multiplication) that will move 3D objects 100 pixels to the left, 200 pixels up, and 50 pixels back (behind the screen), and then use it to move a triangle with vertices at A(40,0,100), B(0,350,200), and C(100,200,10).

Solution
  1. Set up the matrix equation. To move 100 pixels to the left, 200 pixels up, and 50 pixels back, dx = 100, dy = 200, and dz = 50. (If you can't remember which direction is positive or negative, you can always flip back to Chapter 1.)

    graphics/06equ12.gif


  2. Now you have to plug in each old point and add the matrices to see where it moved. First, plug in the old location of vertex A(40,0,100):

    graphics/06equ13.gif


    So A' is the point (60,200,50), just like last time.

  3. If you repeat step 2 with the old locations of B and C, you get the new locations B'(100,550,150) and C'(200,400,60). By moving all three vertices, you have moved the whole triangle. Notice that again you have found the same new location as you did using matrix addition.

Translation through multiplication is very similar for 3D. The major difference is that you are working with 4x4 and 4x1 matrices. The rest is fairly straightforward. Here is the function that translates 3D by multiplication:

 Matrix4X1 translate3DByMultiply(Matrix4X1 start,float dx, float dy,float dz)      {          Matrix4X4 temp;          Matrix4X1 result;          //Zero out the matrix.          temp = createFixed4X4Matrix(0);          //setup the 4X4 for multiplication;          temp.index[0][0] = 1;          temp.index[1][1] = 1;          temp.index[2][2] = 1;          temp.index[3][3] = 1;          //put in the translation amount          temp.index[0][3] = dx;          temp.index[1][3] = dy;          temp.index[2][3] = dz;          result = multiplyMatrixNxM(temp,start);          return result;       } 

Again, we go through and initialize the important components of the matrix, then use the starting coordinates to set the rightmost column. The result is a 4x1 matrix that holds the new position of the point.

NOTE

Notice that each time you calculate the new location, the last entry is always a 1. In code, you're wasting precious time if you calculate the extra 1 for every vertex. All you really need to find is x ', y ', and z ', so don't bother calculating the last entry each time. Can you implement this as a small optimization into the translation code?


The beginning of this section said that matrix addition is by far easier and faster. After practicing both methods , I think you'll agree. Unfortunately, the only way to combine translation with scaling and rotating is to use matrix multiplication. The good news is that if you feel comfortable with translation, scaling and rotating should fall right into place for you.

Self-Assessment

Using the matrix equation provided, find the new locations of the following vertices:

graphics/06equ14.gif


1.

D(30,80)

2.

E(50,200)

3.

F(100,0)

4.

Set up a general matrix equation (using matrix addition) that will move 3D objects 50 pixels to the right, 300 pixels down, and 0 pixels back (behind the screen), and then use it to move a triangle with vertices at G(200,30,50), H(90,0,40), and J(400,50,100).

5.

Set up a general matrix equation (using matrix multiplication) that will move 2D objects 200 pixels to the left and 20 pixels up on the computer screen. Then use it to move a triangle with vertices at L(100,30), M(50,80), and N(70,0).

6.

Repeat question 4 using matrix multiplication. Do you get the same three new locations?


 < Day Day Up > 


Beginning Math and Physics for Game Programmers
Beginning Math and Physics for Game Programmers
ISBN: 0735713901
EAN: 2147483647
Year: 2004
Pages: 143
Authors: Wendy Stahler

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net