3/01/04

Today we looked 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      dx
0 1 0 dy
0 0 1 dz
0 0 0 1

Scaling:

sx      0       0      0  
0 sy 0 0
0 0 sz 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
, y, z
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);

void glScalef(GLfloat x,
GLfloat y,
GLfloat z)
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.

void glTranslatef(GLfloat x,
GLfloat y,
GLfloat z)
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.