CG Module 3.....
CG Module 3.....
159
4.4 Frames in OpenGL
Let’s consider what happens when a user specifies a vertex in a program through
the function glVertex3f(x,y,z). This vertex may be specified directly in the
application program or indirectly through an instantiation of some basic object, as
we discussed in Chapter 3. In most applications, we tend to specify or use an object
with a convenient size, orientation, and location in its own frame called the model
or object frame. For example, a cube would typically have its faces aligned with
axes of the frame, its center at the origin, and have a side length of 1 or 2 units. The
coordinates in the corresponding function calls are in object or model coordinates.
Each object must be brought into an application that might contain hundreds or
thousands of individual objects. 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. Note that if we do not model with predefined
objects or apply any transformations before we execute the glVertex function, object
and world coordinates are the same.
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 the center of the camera’s
184 Chapter 4 Geometric Objects and Transformations
lens1 and whose axes are aligned with the sides of the camera. This frame is called
the 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. In OpenGL, these transformations are concatenated
together into the model-view transformation, which is specified by the model-view
matrix. Usually, the use of the model-view matrix instead of the individual matrices
does not pose any problems for the application programmer. In Chapter 9, where we
discuss programmable pipelines, we will see situations where we must separate the
two transformations.
OpenGL uses three other representations that we will need later, but, for
completeness, we introduce them here. 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 clipcoordinates. We will study
this transformation in Chapter 5. 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.
From the application programmer’s perspective, 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, 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. In Section 4.5,
we learn how to define these transformations; in Section 5.3, we use them to position
the camera relative to our objects. Because frame changes are represented by model-
view matrices that can be stored, we can save frames and move between frames by
changing the current modelview matrix.
1
. For a perspective view, the center of the lens is the center of projection (COP) whereas for an orthogonal
view (the default), the direction of projection is aligned with the sides of the camera.
185
When first working with multiple frames, there can be some confusion about
which frames are fixed and which are varying. Because the model-view matrix po-
4.4 Frames in OpenGL
(a) ( b )
FIGURE 4.26 Camera and object frames. (a) In default positions. (b) After applying model-view matrix.
objects or move the objects away from the camera. Equivalently, we move the
camera frame relative to the object frame. 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,
A ,
moves a point (x, y, z) in the object frame to the point (x, y, z − d) in the camera frame.
Thus, by making d a suitably large positive number, we “move” the objects 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.
Let’s look at another example working directly with representations. When we
define our objects through vertices, we are working in the application frame ( or
world frame). The vertices specified by glVertex3f(x,y,z) are the representation of a
point in that frame. Thus, we do not use the world frame directly but rather implicitly
by representing points (and vectors) in it. Consider the situation illustrated in Figure
4.27.
Here we see the camera as positioned in the object frame. Using homogeneous
coordinates, it is centered at a point p = (1, 0, 1, 1)T in world coordinates and points
at the origin in the world frame. Thus, the vector whose representation in the world
frame is n = (−1, 0, −1, 0)T is orthogonal to the back of the camera and points toward
the origin. The camera is oriented so that its up direction is the same as the up
direction in world coordinates and has the representation v = (0, 1, 0, 0)T. We can
form an orthogonal coordinate system for the camera by using the cross product to
determine a third orthogonal direction for the camera, which is u = (1, 0, −1, 0)T. We
can now proceed as we did in Section 4.3.6 and derive the matrix M that converts
z
187
the representation of points and vectors in the world frame to their representations in rasterizer. At this point, we
the camera frame. The transpose of this matrix in homogenous coordinates is obtained can assume it will do its job
by the inverse of a matrix containing the coordinates of the camera, automatically, provided we
perform the preliminary steps
correctly.
Note that the origin in the original frame is now one unit in the n direction from the FIGURE 4.28 One frame of cube
origin in the camera frame or, equivalently, at the point whose representation is (0, 0, animation.
1, 1) in the camera frame. 4.5.1 Modeling the Faces
In OpenGL, we can set a model-view matrix by sending an array of 16 elements
The cube is as simple a three-
to glLoadMatrix. For situations like the preceding, where we have the representation dimensional object as we
of one frame in terms of another through the specification of the basis vectors and the might expect to model and
origin, it is a direct exercise to find the required coefficients. However, such is not display. There are a number
usually the case. For most geometric problems, we usually go from one frame to of ways, however, to model
another by a sequence of geometric transformations such as rotations, translations, it. A CSG system would
and scales. We will follow this approach in subsequent sections. But first, we will regard it as a single primitive.
look at a few simple approaches to building geometric objects. At the other extreme, the
hardware processes the cube
as an object defined by eight
vertices. Our decision to use
surface-based models
implies that we regard a cube
either as the intersection of
4.5 MODELING A COLORED CUBE six planes or as the six
polygons, called facets, that
We now have most of the basic conceptual and practical knowledge we need to build define its faces. A carefully
three-dimensional graphical applications. We will use them to produce a program that designed data structure
draws a rotating cube. One frame of an animation might be as shown in Figure 4.28. should support both the high-
However, before we can rotate the cube, we will consider how we can model it level application view of the
efficiently. Although three-dimensional objects can be represented, like cube and the low-level view
twodimensional objects, through a set of vertices, we will see that data structures will needed for the
help us to incorporate the relationships among the vertices, edges, and faces of implementation.
geometric objects. Such data structures are supported in OpenGL through a facility We start by assuming
called vertex arrays, which we introduce at the end of this section. that the vertices of the cube
After we have modeled the cube, we can animate it by using affine are available through an array
transformations. We introduce these transformations in Section 4.6 and then use them of vertices; for example, we
to alter OpenGL’s model-view matrix. In Chapter 5, we use these transformations could use the following:
again as part of the viewing process. Our pipeline model will serve us well. Vertices
will flow through a number of transformations in the pipeline, all of which will use
our homogeneous-coordinate representation. At the end of the pipeline awaits the GLfloat vertices[8][3] =
4.5 Modeling a Colored Cube 189
{{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0} ,
{1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0} ,
{1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}} ;
glBegin(GL_POLYGON);
glVertex3fv(vertices[0]); glVertex3fv(vertices[3]);
glVertex3fv(vertices[2]); glVertex3fv(vertices[1]);
glEnd();
and we can define the other five faces similarly. Note that we have defined
threedimensional polygons with exactly the same mechanism that we used to define
twodimensional polygons.
190 Chapter 4 Geometric Objects and Transformations
glBegin(GL_POLYGON)
six times, each time followed by four vertices (via glVertex) and a glEnd, or we could
use
glBegin(GL_QUADS)
followed by 24 vertices and a glEnd. Both of these methods work, but they both fail
to capture the essence of the cube’s topology, as opposed to the cube’s geometry. 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;
4.5 Modeling a Colored Cube 191
x 7, y7
4.5.4 The Color Cube
FIGURE 4.30 Vertex-list representation of a cube. We can use the vertex list to
define a color cube. We
assign the colors of the
vertices of the color solid of
polyhedron. All are true, regardless of the location of the vertices—that is, regardless Chapter 2 (black, white, red,
of the geometry of the object.2 green, blue, cyan, magenta,
Throughout the rest of this book, we will see that there are numerous advantages yellow) to the vertices. We
to building for our objects data structures that separate the topology from the define a function quad to
geometry. In this example, we use a structure, the vertex list, that is both simple and draw quadrilateral polygons
useful and can be expanded later. specified by pointers into the
The data specifying the location of the vertices contain the geometry and can be vertex list. We assign a color
stored as a simple list or array, such as in vertices[8]—the vertex list. The toplevel for the face using the index of
entity is a cube; we regard it as being composed of six faces. Each face consists of the
four ordered vertices. Each vertex can be specified indirectly through its index. This
data structure is shown in Figure 4.30. One of the advantages of this structure is that
2
. We are ignoring special cases (singularities) that arise, for example, when three or more vertices
lie along the same line or when the vertices are moved so that we no longer have nonintersecting
faces.
192 Chapter 4 Geometric Objects and Transformations
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
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
glEnableClientState. 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.
4.5 Modeling a Colored Cube 193
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:
GLubyte cubeIndices[24] = {0,3,2,1, /* Face 0 */
2,3,7,6, /* Face 1 */
0,4,7,3, /* Face 2 */
1,2,6,5, /* Face 3 */
4,5,6,7, /* Face 4 */
0,1,5,4}; /* Face 5 */
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.
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:
Here type is the type of element, such as a line or polygon, that the arrays define; n
is the number of elements that we wish to draw; format specifies the form of the data
in the index array; and pointer points to the first index to use.
For our cube, within the display callback we could make six calls to
glDrawElements, one for each face as follows:
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);
Vertex arrays are stored on the client, which minimizes the storage required on
the graphics server. Consequently, although they increase the efficiency by avoiding
many function calls, they still require data to be transferred between the client and
server each time that the data are rendered. Now that graphics cards have a significant
amount of memory, vertex data can be stored in vertex buffer objects for maximum
efficiency.
u v
R
Q = T(P)
FIGURE 4.33 Transformation.
for points, or
v = R(u)
for vectors. If we can use homogeneous coordinates, then we can represent both
vectors and points as four-dimensional 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 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.
Consider instead a restricted class of transformations. Let’s assume that we are
working in four-dimensional, homogeneous coordinates. In this space, both points
and vectors are represented as 4-tuples. 3 We can obtain a useful class of
transformations if we place restrictions on f . The most important restriction is
3
. We consider only those functions that map vertices to other vertices and that obey the rules for manipulating
points and vectors that we have developed in this chapter and in Appendix B.
196 Chapter 4 Geometric Objects and Transformations
linearity. A function f is a linear function if and only if, for any scalars α and β and
any two vertices (or vectors) p and q,
v = Cu,
C ,
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
u .
p .
v = Cu,
we see that only nine of the elements of C affect u, and thus there are only nine
degrees of freedom in the transformation of vectors. Affine transformations of points
have the full 12 degrees of freedom.
We can also show that affine transformations preserve lines. Suppose that we write a
line in the form
P(α) = P0 + αd,
where P0 is a point and d is a vector. In any frame, the line can be expressed as p(α)
= p0 + αd,
where p0 and d are the representations of P0 and d in that frame. For any affine transformation matrix
A,
Thus, we can construct the transformed line by first transforming p0 and d and using
whatever line-generation algorithm we choose when the line segment must be
displayed. If we use the two-point form of the line, p(α) = αp0 + (1− α)p1,
show how we can describe the most important affine transformations independently
of any representation. Then, we find matrices that describe these transformations by
FIGURE 4.34 Translation. (a) Object in original position. (b) Object translated.
acting on the representations of our points and vectors. In Section 4.8, we will see
how these transformations are implemented in OpenGL.
We look at transformations as ways of moving the points that describe one or
more geometric objects to new locations. Although there are many transformations
that will move a particular point to a new location, there will almost always be only
a single way to transform a collection of points to new locations while preserving
the spatial relationships among them. Hence, although we can find many matrices
that will move one corner of our color cube from P0 to Q0, only one of them, when
applied to all the vertices of the cube, will result in a displaced cube of the same size
and orientation.
4.7.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
P= P + d
for all points P on the object. Note that this definition of translation makes no reference to
y
a frame or representation. Translation has three degrees of freedom because we can specify
(x , y ) the three components of the displacement vector arbitrarily.
(x , y )
4.7.2 Rotation
x
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 FIGURE4.35 Two-dimensional in a two-dimensional plane, as shown in Figure 4.35. Having specified
a particular rotation. point—the origin—we are in a particular frame. A two-dimensional point at (x, y) in this frame is
rotated about the origin by an angle θ to the position (x, y). We can obtain the standard equations describing this rotation
by representing (x, y) and (x, y) in polar form:
4.7 Translation, Rotation, and Scaling 199
x = ρ cos φ, y = ρ
sin φ, x = ρ cos(θ
+ φ), y = ρ sin(θ +
φ).
Expanding these terms using the trigonometric identities for the sine and cosine of
the sum of two angles, we find x = ρ cos φ cos θ − ρ sin φ sin θ = x cos θ − y sin θ, y
= ρ cos φ sin θ + ρ sin φ cos θ = x sin θ + y cos θ.
4.7.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 properly
chosen sequence of scalings, translations, and rotations.
4.7 Translation, Rotation, and Scaling 201
Q = P + αv.
q = p + αv.
A .
203
4.8.1 Translation
Translation displaces points to new positions defined by a displacement vector. If we
move the point p to p by displacing by a distance d, then
p
= p + d.
x αx
⎡ ⎤ ⎡ ⎤
p , p = ⎢ ⎢ ⎣ ⎢ y ⎥ ⎥ ⎥ ⎦ , d = ⎢ ⎢ ⎢ ⎣ αy ⎥ ⎥ ⎥ ⎦ ,
zαz
10
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:
p = Tp, where
T .
T is called the translation matrix. We sometimes write it as T(αx, αy, αz) to emphasize
the three 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
q ,
204 Chapter 4 Geometric Objects and Transformations
q= ,z
it is not possible to find a 3 × 3 matrix D such that q = Dq for the given displacement
vector d. For this reason, the use of homogeneous coordinates is often seen as a
clever trick that allows us to convert the addition of column matrices in three
dimensions to matrix–matrix multiplication in four dimensions.
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 original position by a displacement of −d. By either method, we find that
T .
4.8.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 x = βxx, y = βyy, z = βzz.
= Sp,
where
S .
S .
4.8.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 θ
followed by rotation about the y-axis by an angle φ does 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 that we developed in Section 4.7.2. 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-axis by an angle θ are x = x cos θ
− y sin θ, y = x sin θ + y cos θ,
z = z; or, in matrix
form, p = Rzp,
where
Rz .
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
Rx ,
206 Chapter 4 Geometric Objects and Transformations
Ry .
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 rotation matrices. A rotation by
θ can always be undone by a subsequent rotation by −θ; hence, R−1(θ) = R(−θ).
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 cos(−θ) = cos θ sin(−θ) = −
sin θ
to find
R−1(θ) = RT(θ).
In Section 4.9.1, we show how to construct any desired rotation matrix, with a
fixed point at the origin, as a product of individual rotations about the three axes R
= RzRyRx.
Using the fact that the transpose of a product is the product of the transposes in the
reverse order, we see that for any rotation matrix,
R−1= RT.
4.8.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
207
y y
x x
z z
⎡1 cot θ 0 0 ⎤
Hx .
We can obtain the inverse by noting that we need to shear in only the opposite
direction; hence,
Hx−1(θ) = Hx(−θ).
q = CBAp,
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))).
4.9 Concatenation of Transformations 209
⎡ cos θ − sin θ 0 xf −
4.9.1 Rotation About a Fixed Point xf cos θ + yf sin θ ⎤
Our first example shows how we can alter the transformations that we defined with M
a fixed point at the origin (rotation, scaling, shear) to have an arbitrary fixed point.
We demonstrate for rotation about the z-axis; the technique is the same for the other
cases.
.
210 Chapter 4 Geometric Objects and Transformations
y y y y
pf
pf
x x x x
z z z z
y y
pf
pf
x x
z z
(a) ( b )
Consider the cube, again centered at the origin with its sides aligned with the
axes, as shown in Figure 4.48(a). We can rotate it about the z-axis by an angle α to
orient it, as shown in Figure 4.48(b). We then rotate the cube by an angle β about
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.
y y
x x
z z
(a) (b)
FIGURE 4.48 Rotation of a cube about the z-axis. (a) Cube before rotation.
(b) Cube after rotation.
x x
z z
(a) (b)
y y
z z
(a ) (b )
M = TRS.
Modeling with the instance transformation works well not only with our pipeline
architectures but also with the display lists that we introduced in Chapter 3. A
complex object that is used many times can be loaded into the server once as a
display list.
4.9 Concatenation of Transformations 213
214 Chapter 4 Geometric Objects and Transformations
Note that the order of the points determines the positive direction of rotation for θ
and that even though we draw u as passing through p0, only the orientation of u
y matters. Replacing u with a unit-length vector
αx
p2 p1
u
⎡ ⎤ v=|
v | = ⎣ αy ⎦ u
x αz
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 is the translation T(−p0), and the final one is T(p0). After the initial
z
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 can rotate
by θ about the z- axis, after which we can undo the two rotations that did the aligning.
Our final rotation matrix will be of the form
FIGURE 4.54 Movement of the
fixed point to the origin. R = Rx(−θx)Ry(−θy)Rz(θ)Ry(θy)Rx(θx).
Displaying each instance of This sequence of rotations is shown in Figure 4.55. The difficult part of the process
it requires only sending the θ
is determining x and θy.
appropriate instance
transformation to the server We proceed by looking at the components of v. Because v is a unit-length
before executing the display
list. vector, αx2 + αy2 + αz2 = 1.
4.9 Concatenation of Transformations 215
y y y
x x x x
x
z
y
z z z z
We draw a line segment direction angles are independent because cos2φ x + cos2φy +
from the origin to the point
(αx, αy, αz). This line segment cos2φz = 1.
has unit length and the
orientation of v. Next, we
draw the perpendiculars We can now compute θx and θy using these angles. Consider Figure 4.57. It shows
from the that the effect of the desired rotation on the point (α x, αy, αz) is to rotate the line
FIGURE 4.55 Sequence segment into the plane y = 0. If we look at the projection of the line segment (before
of rotations. the rotation) on the plane x = 0, we see a line segment of length d on this plane.
Another way to envision this figure is to think of the plane x = 0 as a wall and
consider a distant light source located far down the positive x-axis. The line that we
point (αx, αy, αz) to the see on the wall is the shadow of the line segment from the origin to (αx, αy, αz). Note
that the length of the shadow is less than the length of the line segment. We can say
coordinate axes, as shown in the line segment has been foreshortened to d . The desired angle of
Figure 4.56. The three
rotation is determined by the angle that this shadow makes with the z-axis. However,
direction angles—φx, φy, the rotation matrix is determined by the sine and cosine of θx. Thus, we never need
φz—are the angles between to compute θx; rather, we need to compute only
the
216 Chapter 4 Geometric Objects and Transformations
y y
z
( x, y, z) ( x, ,
y z
)
y d 1
x
x x x
y x
z
z z
We compute Ry in a similar manner. Figure 4.58 shows the rotation. This angle is clockwise about the y-axis; therefore,
we have to be careful of the sign of the sine terms in the matrix, which is
Ry(θy) .
x
x
d
y 1
(1/ 14, 2/ 14, 3/ 14), or (1/ 14, 2/ 14, 3/ 14, 1) in homogeneous coordinates. The first
part of the rotation takes this point to (0, 0√, 1, 1). We√first rota√te about the x-axis
by the angle cos . This matrix carries (1/ 14, 2/ 14, 3/ 14, 1) to
(1/√ 14, 0, √13√/14, 1), which is in the plane y = 0. The y rotation must be by the
angle − cos −1( 13/14). This rotation aligns the object with the z-axis, and now we
can rotate about the z-axis by the desired 45 degrees. Finally, we undo the first two
rotations. If we concatenate these five transformations into a single rotation matrix
R, we find that
4.9 Concatenation of Transformations 217
Rx
This matrix does not change any point on the line passing through the origin and the
point (1, 2, 3). If we want a fixed point other than the origin, we form the matrix M
= T(pf)RT(−pf).
This example is not simple. It illustrates the powerful technique of applying many simple transformations to get a
complex one. The problem of rotation about
an arbitrary point or axis arises in many applications. The major variants lie in the manner in which the axis of rotation
is specified. However, we can usually employ techniques similar to the ones that we have used here to determine
direction angles or direction cosines
218