Homogeneous Coordinates and Transformation Matrices

This appendix has the following major sections:

- "Homogeneous Coordinates"

"Transformation Matrices"

As long as *w* is nonzero, the homogeneous vertex (*x, y, z,
w*)T corresponds to the three-dimensional point (*x/w, y/w, z/w*)T.
If *w* = 0.0, it corresponds to no euclidean point, but rather to
some idealized "point at infinity." To understand this point at infinity,
consider the point (1, 2, 0, 0), and note that the sequence of points (1,
2, 0, 1), (1, 2, 0, 0.01), and (1, 2.0, 0.0, 0.0001), corresponds to the
euclidean points (1, 2), (100, 200), and (10000, 20000). This sequence
represents points rapidly moving toward infinity along the line 2*x*
= *y*. Thus, you can think of (1, 2, 0, 0) as the point at infinity
in the direction of that line.

OpenGL might not handle homogeneous clip coordinates with *w* <
0 correctly. To be sure that your code is portable to all OpenGL systems,
use only nonnegative *w* values.

After transformation, all transformed vertices are clipped so
that *x*, *y*, and *z* are in the range [-*w*, *w*]
(assuming *w* > 0). Note that this range corresponds in euclidean
space to [-1.0, 1.0].

A homogeneous plane is denoted by the row vector (*a , b, c, d*),
where at least one of *a, b, c*, or *d* is nonzero. If **q**
is a nonzero real number, then (*a, b, c, d*) and (*qa, qb, qc,
qd*) represent the same plane. A point (*x, y, z, w*)T is on the
plane (*a, b, c, d*) if *ax*+*by*+*cz*+*dw* =
0. (If *w* = 1, this is the standard description of a euclidean plane.)
In order for (*a, b, c, d*) to represent a euclidean plane, at least
one of *a*, *b*, or *c* must be nonzero. If they're all
zero, then (0, 0, 0, *d*) represents the "plane at infinity," which
contains all the "points at infinity."

If **p** is a homogeneous plane and **v** is a homogeneous vertex,
then the statement "**v** lies on plane **p**" is written mathematically
as **pv** = 0, where **pv** is normal matrix multiplication. If **M**
is a nonsingular vertex transformation (that is, a 4 × 4 matrix that has
an inverse **M**-1), then **pv** = 0 is equivalent to **pM**-1**Mv**
= 0, so **Mv** lies on the plane **pM**-1. Thus, **pM**-1 is the
image of the plane under the vertex transformation **M**.

If you like to think of normal vectors as vectors instead of as the
planes perpendicular to them, let **v** and **n** be vectors such
that **v** is perpendicular to **n**. Then, **n**T**v** = 0.
Thus, for an arbitrary nonsingular transformation **M**, **n**T**M**-1**Mv**
= 0, which means that nTM-1 is the transpose of the transformed normal
vector. Thus, the transformed normal vector is **(M**-1**)**T**n**.
In other words, normal vectors are transformed by the inverse transpose
of the transformation that transforms points. Whew!

Notice that **S**-1 is defined only if *x*, *y*, and *z*
are all nonzero.

Let v = (*x*, *y*, *z*)T, and **u** = v/||v|| = (*x*',
*y*', *z*').

Also let

Then

The **R** matrix is always defined. If *x=y=z*=0, then **R**
is the identity matrix. You can obtain the inverse of **R**, **R**-1,
by substituting -**a** for **a**, or by transposition.

The **glRotate*()** command generates a matrix for rotation about
an arbitrary axis. Often, you're rotating about one of the coordinate axes;
the corresponding matrices are as follows.

As before, the inverses are obtained by transposition.

**R** is defined as long as** l **not equal to** r**,** t
**not equal to** b**, and **n **not equal to** f**.

**R** is defined as long as** l **not equal to** r**, **t
**not equal to** b**, and **n **not equal to** f**.

[Previous chapter] [Next chapter]

See the About page for copyright, authoring and distribution information.