CG Module 3....
CG Module 3....
Module 3
The application program generally applies a sequence of transformations to each object to size, orient, and
position it within a frame that is appropriate for the particular application. For example, if we were using an
instance of a square for a window in an architectural application, we would scale it to have the correct proportions
and units, which would probably be in feet or meters. The origin of application coordinates might be a location
in the center of the bottom floor of the building. This application frame is called the world frame and the values
are in world coordinates.
Object and world coordinates are the natural frames for the application program. However, the image that is
produced depends on what the camera or viewer sees. Virtually all graphics systems use a frame whose origin is
and whose axes are aligned with the sides of the camera. This frame is called the
Geometric Objects and Transformations Module 3
camera frame or eye frame. Because there is an affine transformation that corresponds to each change of frame,
there are 4 × 4 matrices that represent the transformation from model coordinates to world coordinates and from
world coordinates to eye coordinates.
Once objects are in eye coordinates, OpenGL must check whether they lie within the view volume. If an object
does not, it is clipped from the scene prior to rasterization. OpenGL can carry out this process most efficiently if
it first carries out a projection transformation that brings all potentially visible objects into a cube centered at the
origin in clip coordinates.
After this transformation, vertices are still represented in homogeneous coordinates. The division by the w
component, called perspective division, yields three-dimensional representations in normalized device
coordinates.
The final transformation takes a position in normalized device coordinates and, taking into account the viewport,
creates a three-dimensional representation in window coordinates. Window coordinates are measured in units of
pixels on the display but retain depth information. If we remove the depth coordinate, we are working with two-
dimensional screen coordinates.
OpenGL starts with two frames: the eye frame and the object
frame. The model-view matrix positions the object frame relative to the eye frame. Thus, the model-view matrix
converts the homogeneous- coordinate representations of points and vectors to their representations in the eye
frame. Because the model-view matrix is part of the state of the system, there is always a current camera frame
and a current object frame. OpenGL provides matrix stacks, so we can store model-view matrices or, equivalently,
Geometric Objects and Transformations Module 3
frames.
Initially, the model-view matrix is an identity matrix, so the object frame and eye frame are identical. Thus, if we
do not change the model-view matrix, we are working in eye coordinates. As we saw in Chapter 2, the camera is
at the origin of its frame, as shown in Figure 4.26(a). The three basis vectors in eye space correspond to (1) the
up direction of the camera, the y direction; (2) the direction the camera is pointing, the negative z direction; and
(3) a third orthogonal direction, x, placed so that the x, y, z directions form a right-handed coordinate system. We
obtain other frames in which to place objects by performing homogeneous coordinate transformations that define
new frames relative to the camera frame.
Geometric Objects and Transformations Module 3
If we regard the camera frame as fixed and the modelview matrix as positioning the object frame relative to the
camera frame, then the model-view matrix,
moves a point (x, y, z) in the object frame to the po d) in the camera frame. Thus, by making
da
suitably large positiv in front of the camera by moving the world frame relative to the camera frame, as shown in
Figure 4.26(b). Note that, as far as the user who is working in world coordinates is concerned, she is positioning
objects as before. The model-view matrix takes care of the relative positioning of the object and eye frames. This
strategy is almost always better than attempting to alter the positions of the objects by changing their vertices to
place them in front of the camera.
Vertices will flow through a number of transformations in the pipeline, all of which will use our
homogeneouscoordinate representation. At the end of the pipeline awaits the rasterizer. At this point, we can
assume it will do its job automatically, provided we perform the preliminary steps correctly.
We start by assuming that the vertices of the cube are available through an array of vertices; for example, we
could use the following:
We can adopt a more object-oriented formif we first define a three-dimensional point type as follows:
typedef GLfloat point3[3]; The
vertices of the cube can be specified as follows:
OpenGL represents all vertices internally in four-dimensional homogeneous coordinates. Function calls using a
three-dimensional type, such as glVertex3fv, have the values placed into a four-dimensional form within the
graphics system.
Geometric Objects and Transformations Module 3
We can then use the list of points to specify the faces of the cube. For example, one face is
and we can define the other five faces similarly. Note that we have defined three-dimensional polygons with
exactly the same mechanism that we used to define two-dimensional polygons.
3.2.2 Inward- and Outward-Pointing Faces
We have to be careful about the order in which we specify our vertices when we are defining a three-dimensional
polygon. We used the order 0, 3, 2, 1 for the first face. The order 1, 0, 3, 2 would be the same, because the final
vertex in a polygon definition is always linked back to the first. However, the order 0, 1, 2, 3 is different. Although
it describes the same boundary, the edges of the polygon are traversed in the reverse order 0, 3, 2, 1 as shown in
Figure 4.29. The order is important because each polygon has two sides. Our graphics systems can display either
or both of them.
In our example, the order 0, 3, 2, 1 specifies an outward face of the cube whereas the order 0, 1, 2, 3 specifies the
back face of the same polygon. Note that each face of an enclosed object, such as our cube, is an inside or outside
face, regardless of from where we view it, as long as we view the face from outside the object. By specifying
front and back carefully, we will be able to eliminate (or cull) faces that are not visible or to use different attributes
to display front and back faces.
Geometric Objects and Transformations Module 3
If we think of the cube as a polyhedron, we have an object the cube that is composed of six faces. The faces are
each quadrilaterals that meet at vertices; each vertex is shared by three faces. In addition, pairs of vertices define
edges of the quadrilaterals; each edge is shared by two faces. These statements describe the topology of a six-
sided polyhedron. All are true, regardless of the location of the vertices that is, regardless of the geometry of the
object.
Geometric Objects and Transformations Module 3
The data specifying the location of the vertices contain the geometry and can be stored as a simple list or array,
such as in vertices[8] the vertex list. The toplevel entity is a cube; we regard it as being composed of six faces.
Each face consists of four ordered vertices. Each vertex can be specified indirectly through its index. This data
structure is shown in Figure 4.30.
Vertex arrays provide a method for encapsulating the information in our data structure such that we can draw
polyhedral objects with only a few function calls.
They allow us to define a data structure using vertices and pass this structure to the implementation. When the
objects defined by these arrays need to be drawn, we can ask OpenGL to traverse the structure with just a few
function calls.
There are three steps in using vertex arrays. First, we enable the functionality of vertex arrays. Second, we tell
OpenGL where and in what format the arrays are. Third, we render the object. The first two steps can be part of
the initialization; the third is typically part of the display callback.We illustrate for the cube.
Geometric Objects and Transformations Module 3
OpenGL allows many different types of arrays, including vertex, color, color index, normal, and texture
coordinate, corresponding to items that can be set between a glBegin and a glEnd. Any given application usually
requires only a subset of these types. For our rotating cube, we need only colors and vertices. We enable the
corresponding arrays as follows:
Note that, unlike most OpenGL state information, the information for vertex arrays resides on the client side, not
the server side hence the function name glEnable- ClientState. The arrays are the same as before and can be set
up as globals:
The first three arguments state that the elements are three-dimensional colors and vertices stored as floats and that
the elements are contiguous in the arrays. The fourth argument is a pointer to the array holding the data. Next, we
have to provide the information in our data structure about the relationship between the vertices and the faces of
the cube. We do so by specifying an array that holds the 24 ordered vertex indices for the six faces:
Thus, the first face is determined by the indices (0, 3, 2, 1), the second by (2, 3, 7, 6), and so on.Note that we have
put the indices in an order that preserves outward-facing polygons. The index array can also be specified as a
global.
Geometric Objects and Transformations Module 3
Now we can render the cube through use of the arrays. When we draw elements of the arrays, all the enabled
arrays (in this example, colors and vertices) are rendered. We have a few options regarding how to draw the
arrays. We can use the following function:
Thus, once we have set up and initialized the arrays, each time that we draw the cube, we have only six function
calls. We can rotate the cube as before; glDrawElements uses the present state when it draws the cube.
We can do even better though. Each face of the cube is a quadrilateral. Thus, if we use GL_QUADS, rather than
GL_POLYGON, we can draw the cube with the single function call
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);
because GL_QUADS starts a new quadrilateral after each four vertices.
Q = T(P)
for points, or
v = R(u)
for vectors. If we can use homogeneous coordinates, then we can represent both vectors and points as
fourdimensional column matrices and we can define the transformation with a single function,
q = f (p),
v = f (u),
that transforms the representations of both points and vectors in a given frame.
This formulation is too general to be useful, as it encompasses all single-valued mappings of points and vectors.
In practice, even if we were to have a convenient description of the function f , we would have to carry out the
Geometric Objects and Transformations Module 3
transformation on every point on a curve. For example, if we transform a line segment, a general transformation
might require us to carry out the transformation for every point between the two endpoints.
f is a linear function if and only if, for vertices (or vectors) p and q,
Using homogeneous coordinates, we work with the representations of points and vectors. A linear transformation
then transforms the representation of a given point (or vector) into another representation of that point (or vector)
and can always be written in terms of the two representations, u and v, as a matrix multiplication: v = Cu, where
C is a square matrix. Comparing this expression with the expression.
When we work with homogeneous coordinates, A is a 4 × 4 matrix that leaves unchanged the fourth (w)
component of a representation. The matrix C is of the form
and is the transpose of the matrix M that we derived in Section 4.3.4. The 12 values can be set arbitrarily, and we
say that this transformation has 12 degrees of freedom. However, points and vectors have slightly different
representations in our affine space. Any vector is represented as
Geometric Objects and Transformations Module 3
3.4.1 Translation
Translation is an operation that displaces points by a fixed distance in a given direction, as shown in Figure 4.34.
To specify a translation, we need only to specify a displacement vector d, because the transformed points are
given by
for all points P on the object. Note that this definition of translation makes no reference to a frame or
representation. Translation has three degrees of freedom because we can specify the three components of the
displacement vector arbitrarily.
Geometric Objects and Transformations Module 3
3.4.2 Rotation
Rotation is more difficult to specify than translation because we must specify more parameters. We start with the
simple example of rotating a point about the origin in a two-dimensional plane, as shown in Figure 4.35. Having
Geometric Objects and Transformations Module 3
specified a particular point the origin we are in a particular frame. Atwo-dimensional point at (x, y) in this frame
is rotated about the origin by an a can obtain the standard equations describing
this rota ) in polar form:
Expanding these terms using the trigonometric identities for the sine and cosine of the sum of two angles, we find
2. Knowing that the two-dimensional plane is part of three-dimensional space, we can reinterpret this
rotation in three dimensions. In a right-handed system, when we draw the x- and y-axes in the standard
way, the positive z-axis comes out of the page. Our definition of a positive direction of rotation is
counterclockwise when we look down the positive z-axis toward the origin. We use this definition to
define positive rotations about other axes.
3. Rotation in the two-dimensional plane z = 0 is equivalent to a three-dimensional rotation about the z-axis.
Points in planes of constant z all rotate in a similar manner, leaving their z values unchanged.
Rotation and translation are known as rigid-body transformations. No combination of rotations and translations
can alter the shape or volume of an object; the ently,
rotation and translation alone cannot give us all possible affine transformations. The transformation shown in
Figure 4.38 are affine, but they are not rigid-body transformations.
Geometric Objects and Transformations Module 3
3.4.3 Scaling
Scaling is an affine non rigid-body transformation by which we can make an object bigger or smaller. Figure
4.39 illustrates both uniform scaling in all directions and scaling in a single direction. We need nonuniform scaling
to build up the full set of affine transformations that we use in modeling and viewing by combining a
Geometric Objects and Transformations Module 3
because we can specify an arbitrary fixed point and three independent scaling factors.
Geometric Objects and Transformations Module 3
Instead, we work with representations in homogeneous coordinates and with expressions such
as
3.5.1 Translation
Translation displaces points to new positions defined by
displacing by a distance d, then
This method of representing translation using the addition of column matrices does not combine well with our
representations of other affine transformations. However, we can also get this result using the matrix
multiplication:
independent parameters. It might appear that using a fourth fixed element in the homogeneous representation of
a point is not necessary. However, if we use the three-dimensional forms it is not possible to find a 3×3 matrix D
such that for the given displacement vector d. For this reason, the use of
Geometric Objects and Transformations Module 3
homogeneous coordinates is often seen as a clever trick that allows us to convert the addition of column matrices
We can obtain the inverse of a translation matrix either by applying an inversion algorithm or by noting that if
we displace a point by the vector d, we can return to the
method, we find that
3.5.2 Scaling
For both scaling and rotation, there is a fixed point that is unchanged by the transformation. We let the fixed point
be the origin, and we show how we can concatenate transformations to obtain the transformation for an arbitrary
fixed point.
A scaling matrix with a fixed point of the origin allows for independent scaling along the coordinate axes. The
three equations are
We obtain the inverse of a scaling matrix by applying the reciprocals of the scale factors:
Geometric Objects and Transformations Module 3
3.5.3 Rotation
We first look at rotation with a fixed point at the origin. There are three degrees of freedom corresponding to our
ability to rotate independently about the three coordinate axes. We have to be careful, however, because matrix
multiplication is not a commutative operation (Appendix C). Rotation about the x-axis by an angle
y rotation about the y- oes not give us the same result as the one that we obtain if we reverse
the order of the rotations.
We can find the matrices for rotation about the individual axes directly from the results of the two-dimensional
rotation. We saw that the two-dimensional rotation was actually a rotation in three dimensions about the z-axis
and that the points remained in planes of constant z. Thus, in three dimensions, the equations for rotation about
the z-
We can derive the matrices for rotation about the x- and y-axes through an identical argument. If we rotate about
the x-axis, then the x values are unchanged, and we have a two-dimensional rotation in which points rotate in
planes of constant x; for rotation about the y-axis, the y values are unchanged. The matrices are
Geometric Objects and Transformations Module 3
The signs of the sine terms are consistent with our definition of a positive rotation in a right-handed system.
Suppose that we let R denote any of our three rot can always be undone by a
In addition, noting that all the cosine terms are on the diagonal and the sine terms are off-diagonal, we can use
the trigonometric identities as a product of individual rotations about the three axes
Using the fact that the transpose of a product is the product of the transposes in the reverse order, we see that for
A matrix whose inverse is equal to its transpose is called an orthogonal matrix. Normalized orthogonal matrices
correspond to rotations about the origin.
Geometric Objects and Transformations Module 3
3.5.4 Shear
Although we can construct any affine transformation from a sequence of rotations, translations, and scalings,
there is one more affine transformation the shear transformation that is of such importance that we regard it as a
basic type, rather than deriving it from the others. Consider a cube centered at the origin, aligned with the axes
and viewed from the positive z-axis, as shown in Figure 4.42. If we pull the top to the right and the bottom to the
left, we shear the object in the x direction. Note that neither the y nor the z values are changed by the shear, so
we can call this operation x shear to distinguish it from shears of the cube in other possible directions. Using
simple trigonometry on Figure 4.43, we see that each shear is characterized by
this shear are
Geometric Objects and Transformations Module 3
We can obtain the inverse by noting that we need to shear in only the opposite direction; hence,
without parentheses. Note that here the matrices A, B, and C (and thus M) can be arbitrary 4×4 matrices, although
in practice they will most likely be affine. The order in which we carry out the transformations affects the
efficiency of the calculation. In one view, shown in Figure 4.44, we can carry out A, followed by B, followed by
C an order that corresponds to the grouping q = (C(B(Ap))).
Geometric Objects and Transformations Module 3
If we are to transform a single point, this order is the most efficient because each matrix multiplication involves
multiplying a column matrix by a square matrix. If we have many points to transform, then we can proceed in
two steps. First, we calculate
M = CBA.
Then, we use this matrix on each point
q = Mp.
This order corresponds to the pipeline shown in Figure 4.45, where we compute M first, then load it into a pipeline
transformation unit. If we simply count operations, we see that although we do a little more work in computing
M initially, because M may be applied to tens of thousands of points, this extra work is insignificant compared
with the savings we obtain by using a single matrix multiplication for each point. We now derive examples of
computing M.
4.48(a). We can rotate it about the z- orient it, as shown in Figure 4.48(b).We then rotate the
y-axis, as shown in a top view in Figure 4.49. Finally, we rotate the cube by an angle
about the x-axis, as shown in a side view in Figure 4.50. Our final rotation matrix is R = RxRyRz .
Geometric Objects and Transformations Module 3
can obtain the desired size, orientation, and location by applying an affine transformation the instance
transformation to the prototype. We can build a simple database to describe a scene from a list of object identifiers
(such as 1 for a cube and 2 for a sphere) and of the instance transformation to be applied to each object.
The instance transformation is applied in the order shown in Figure 4.52.Objects are usually defined in their own
frames, with the origin at the center of mass and the sides aligned with the model frame axes. First, we scale the
object to the desired size. Then we orient it with a rotation matrix. Finally, we translate it to the desired orientation.
Hence, the instance transformation is of the form M = TRS.
Modeling with the instance transformation works well not only with our pipeline architectures but also with the
display lists. A complex object that is used many times can be loaded into the server once as a display list.
Displaying each instance of it requires only sending the appropriate instance transformation to the server before
executing the display list.
The vector about which we wish to rotate the cube can be specified in various ways. One way is to use two points,
p1 and p2, defining the vector u = p2 p1.
Note that the order of the points determines the posit and that even though we draw
u as passing through p0, only the orientation of u matters. Replacing u with a unit-length vector
in the same direction simplifies the subsequent steps. We have already seen that moving the fixed point to the
origin is a helpful technique. Thus, our first transformation
After the initial translation, the required rotation problem is as shown in Figure 4.54.
Our previous example (see Section 4.9.2) showed that we could get an arbitrary rotation from three rotations
about the individual axes. This problem is more difficult because we do not know what angles to use for the
individual rotations. Our strategy is to carry out two rotations to align the axis of rotation, v, with the z-axis. Then
we ca -axis, after which we can undo the two rotations that did the aligning. Our final
rotation matrix will be of the form