Today we look at homogeneous coordintes and the basic translation, scaling and rotation transformations.

Translation and rotation are *rigid body* transformations
which preserve lengths and angles. The general *affine* *transformation*
which multiplies a point in homogeneous coordinates (3rd coordinate =
1) by a matrix with arbitrary values in the first two rows (but last
row 0, 0 , 1 as always) preserves parallel lines but not lengths or
angles.

Here are the 3D versions of these transformations:

Translation:

1 0 0 d_{x}0 1 0 d_{y}0 0 1 d_{z}0 0 0 1

Scaling:

s_{x}0 0 0

0 s_{y}0 0

0 0 s_{z}0

0 0 0 1

Rotation about z-axis:

cos(t) -sin(t) 0 0

sin(t) cos(t) 0 0

0 0 1 0

0 0 0 1

Rotation about x-axis:

0 0 1 0

0 cos(t) -sin(t) 0

0 sin(t) cos(t) 0

0 0 0 1

Rotation about y-axis:

cos(t) 0 sin(t) 0

0 1 0 0

-sin(t) 0 cos(t) 0

0 0 0 1

These transformations are on the object, not the viewer, but the coordinate frame is always at the viewer. For example, if you translate an object -4 units in the z direction, the object moves in the negative z direction, or equivalently the camera moves in the positive direction. Either way the viewer and object are further apart. If we rotate 30 degrees around the y-axis, this means that the world rotates around the viewer 30 degrees, or that the viewer rotates -30 degrees while the world is stationary. Either way, objects will be seen as moving to the left.

The OpenGL functions for these transformations are (e.g.)

void **glRotatef**(GLfloat *angle*, GLfloat *x*,
GLfloat *y*, GLfloat *z*)

*angle*- Specifies the angle of rotation, in degrees.
- x
- Specify the
*x*,*y*, and*z*coordinates of a vector, respectively.

**glRotate** computes a matrix that performs a counterclockwise
rotation of *angle* degrees about the vector from the origin
through the point (*x*, *y*, *z*).

So for example, to rotate 30 degrees around the y-axis we could call glRotatef(30,0,1,0);

voidglScalef(GLfloatx,

GLfloaty,

GLfloatz)

*x*,*y*,*z*- Specify scale factors along the
*x*,*y*, and*z*axes, respectively.

**glScale** produces a general scaling along the *x*, *y*,
and *z* axes. The three arguments indicate the desired scale
factors along each of the three axes.

voidglTranslatef(GLfloatx,

GLfloaty,

GLfloatz)

*x*,*y*,*z*- Specify the
*x*,*y*, and*z*coordinates of a translation vector.

**glTranslate** moves the coordinate system origin to the point
specified by (*x*, *y*, *z*).

We will begin our OpenGL 3-d viewing by constructing a cube. We have to specify 6 polygonal faces, but each vertex will be repeated three times (since it is shared by three faces). If we do a brute-force construction listing all the points our code will repetitious and hard to change. We will list the 8 vertices in an array and then refer to them only by index. We'll also make a unit cube whose vertex coordinates can double as colors (so that we can distinguish the faces when we view the cube). Here's the idea:

typedef GLfloat point3[3];

point3 p[8]={

{0,0,0}, //black

{0,0,1}, //blue

{1,0,1}, //magenta

{1,0,0}, //red

{0,1,0}, //green

{0,1,1}, //green+blue

{1,1,1}, //white

{1,1,0} //yellow

};

void drawPoint(int i){

glVertex3fv(p[i]);

}

void drawFace(int i1,int i2,int i3,int i4){

glBegin(GL_POLYGON);

glColor3fv(p[i1]);

drawPoint(i1);

drawPoint(i2);

drawPoint(i3);

drawPoint(i4);

glEnd();

}

Our display function will include the code:

drawFace(0,3,2,1); //bottom = black,

drawFace(1,2,6,5); //front = blue

drawFace(2,3,7,6); //right side = magenta

drawFace(3,0,4,7); //back side = red

drawFace(4,5,6,7); //top = white

drawFace(5,4,0,1); //left side = yellow

We can move the cube around to see different perspectives.