COMPUTER GRAPHICS
USING OPEN GL SECOND EDITION
F. S. HILL, JR.
2.3.5 Filling Polygons
OpenGL supports filling general polygons with a pattern or
color. The restriction is the the polygons must be convex.
DEFINITION: Convex polygon: A polygon is convex if a line
connecting any two points of the polygon lies entirely within it.
CHAPTER 4: Vector Tools for Graphics
REVIEW OF VECTORS
- Geometrically, vectors are objects having length and direction.
They represent various physical entities such as force, displacement,
and velocity.
4.2.1 Operation with Vectors
- Vectors can be added and they can be multiplied by a scalar.
If a = (2, 5, 6), b = (-2, 7, 1) and scalar s = 6:
a + b = (0, 12, 7) and sa = (12, 30, 36).
4.2.2 Linear Combinations of Vectors
- A linear combination of m vectors
v1, v2, ...,
vm, is a vector of
the form
w =
a1v1,
a2v2, ...,
amvm
where
a1, a2,
..., am are scalars.
- An affine combination is a restriction on a linear
combination of vectors in that the scalers or coefficients
a1, a2, ..., am
must add up to unity: a1 +
a2 + ... + am = 1.
- A convex combination is a further restriction in that the
coefficients must be nonnegative. Therefore,
0 ≤ ai ≤ 1 for i = 1, ..., m.
- 0.3a + 0.7b is convex.
- The set of all convex combinations is
v = (1 - a)v1 + av2
for all v1 and v2.
- For three vectors,
q = a1v1 + a2v2
+ (1 - a1 - a2)v3
where a1 plus a2 does not exceed unity.
- A convex linear combination of two vectors defines a line, three vectors determines
a triangular plane.
4.2.3 The Magnitude of a Vector; Unit Vectors
-
By the Pythagorean theorem
______________________
the magnitude of vector |w| = √
w1²
+ w2² + ...
+ wn²
Normalizing a vector
means scaling it to a length of
unity, |
|
|
|
- Example: if a = ( 3, -4 ), then | a | = ( 32,
-42 )½ = 5 and â = (
3 / 5, -4 / 5 ). This unit vector is
a direction.
THE DOT PRODUCT
- The dot product of two vectors, (a1,
a2) and (b1, b2),
is the scalar a1b1
+ a2b2. For example, the dot product of:
- (3, 4) and (1, 6) = 3 × 1 + 4 × 6 = 3 + 24 = 27
- (2, 3) and (9, -6) = 2 × 9 + 3 × -6
= 18 - 18 = 0
- The general definition of the dot product:
- The dot product d of two n-dimensional vectors
v = (v1, v2, ... vn)
and w = (w1, w2, ... wn)
is denoted as v • w and has the value
- Example, the dot product of
- (2, 3, 1) and (0, 4, -1) = 2 × 0 + 3 × 4 + 1
× -1 = 0 + 12 - 1 = 11.
- (2, 2, 2, 2) • (4, 1, 2, 1.1) = 2 × 4 + 2 ×
1 + 2 × 2 + 2 × 1.1 = 8 + 2 + 4 + 2.2 = 16.2.
4.3.2 The Angle Between Two Vectors
-
For vectors b and c at angles Φb
and Φc:
b = Xb,
Yb
= |b| cos Φb,
|b| sin Φb
and
c = |c|
cos Φc,
|c| sin Φc
- The dot product of these is
b•c = |b||c| cos
Φc cos Φb
+ |b||c| sin Φb
sin Φc
= |b||c| cos
(Φc - Φb)
- We now have the angle between them
b•c = |b||c| cos
(θ)
-
Divide both sides by |b||c| and use the
unit vector notation
^
b = b/|b| to obtain
^ ^
cos(&theta) = b•c
- EXAMPLE: Find the angle between b = (3, 4) and c = (5, 2).
|b| = √3²+4²
= √9+16 = √25 = 5
|c| = √5²+2²
= √25+4 = √29 = 5.385
^
b = (3/5, 4/5) = (0.60, 0.80)
^
c = (0.9285, 0.3714)
^ ^
b•c = 0.6 × 0.9285 + 0.8 × 0.3714
= 0.5571 + 0.2971 = 0.8542 = cos(θ)
θ = 31.3287°.
4.3.3 The Sign of b • c, and Perpendicularity
- Cos(θ) is positive if |θ|
less than 90°, zero if |θ| equal to 90°,
and negative if |θ| greater than 90°.
- DEFINITION: Vectors b and c are perpendicular
if b•c = 0.
- Other names for perpendicular are orthogonal and normal.
- The 2D vectors (1, 0) and (0, 1) are mutually perpendicular unit vectors.
- DEFINITION: The standard unit vectors in 3D have components
i = (1, 0, 0), j = (0, 1, 0), and k = (0, 0, 1).
- Using these definitions we can write any 3D vector such as
(a, b, c) = ai + bj +
ck.
- EXAMPLE: v = (2, 5, -1)
is the same as 2(1, 0, 0) + 5(0, 1, 0) - 1(0, 0, 1)
= 2i + 5j - k
4.3.4 The 2D "Perp" Vector
- Suppose a vector a has components (ax,
ay). If you exchange the x and y
components, negate one of them and dot this to the original, the
result is zero.
(ax, ay) •
(-ay, ax) = 0
- This is also a•a⊥ = 0
- For convenience we use the symbol ⊥ (pronounced "perp") to designate
a normal or perpendicular angle.
- DEFINITION: Let a = (ax,ay). Then
a⊥ = (-ay,ax)
is the counterclockwise perpendicular to a.
4.3.5 Orthoganal Projections and the Distance from a Point to a Line
- Given two points A and C and a vector v,
how do you decompose it into components of length
K and M? One solution is
c = Kv +
Mv⊥.
- To solve for two unknowns you have to set one variable to
zero. If we multiply both sides by v we get
c•v = Kv•v
+ Mv⊥•v. Now
Mv⊥•v = 0 so we get
- Similarly if we "dot" both sides with v⊥ we get
- Putting it all together we have
- The part along v is know as the orthogonal projection of c
onto the vector v.
- Further, the second term, the distance from C to vector v
THE CROSS PRODUCT OF TWO VECTORS
- The cross product or the vector product of two vectors is
another vector that is perpendicular to both the given vectors. It is only
defined for three-dimensional vectors.
- Given the 3D vectors a = (ax, ay,
az ) and b = (bx, by,
bz ), their cross product is denoted a ×
b.
- It is defined in terms of the standard unit vectors, i,
j, and k:
a × b = ( aybz
- azby )i
+ ( azbx -
axbz )j
+ ( axby -
aybx )k
- As this is difficult to remember it is often written as
| | |
i | j |
k |
| |
a × b = |
ax |
ay |
az |
| bx |
by |
bz |
4.5.1 Coordinate Systems and Coordinate Frames
- A coordinate frame consists of a specific point, γ, called the
origin, and three mutually perpendicular unit vectors (axes), a,
b, and c. This frame resides at some point γ within the
"world".
- To represent the vector v, we find three numbers ( v1,
v2, v3 ) such that
and say that v "has the representation" (v1,
v2, v3 ) in this system.
- To represent a point P, we view its location as an offset from the
origin by a certain amount.
- The homogeneous representation of graphics appends a 0 as the
fourth component of a vector and a 1 as the fourth component of a point.
- Using matrix multiplication we can formally write any v and P as
v = ( a,
b, c, γ ) |
( |
v1 | ) |
v2 |
v3 |
0 |
P = ( a,
b, c, γ ) |
( |
P1 | ) |
P2 |
P3 |
1 |
4.5.2 Affine Combinations of Points
- Consider forming a linear combination of two points P and R using scalars
ƒ and g. We have If
ƒ and g are not affine (sum to unity) and we move
between coordinate frames, the sum, E', does not have uniform values and
distortion results.
If E = ƒP + gR is shifted by u, P is shifted
to P + u, R is shifted to R + u and E' = E + u.
Instead we have
- Another interesting thing is to form a point A offset by vector
v and scale it to t. If v is the difference between
another point, v = B - A
P = A + t( B - A )
= tB + ( 1 - t )A
The centroid
(center of gravity) of triangle D, E, F is |
C = |
D + E + F |
3 |
4.5.3 Linear Interpolation of Two Points
The affine combination of points P =
A( 1 - t ) + tB
performs a linear interpolation between points A
and B. The x, y, or z-component
Pcomponent(t) provides a value that is
fraction t of the way between A and B.
This is a sufficently important enough operation to warrant a
name, lerp, and a simple implementation:
GLdouble lerp( GLdouble a, GLdouble b, GLdouble t )
{ return a + ( b - a ) * t;
}
This leads to "tweening" or in-between points.
Point3D tween( Point3D A,
Point3D B, GLdouble t ) |
{ | Point3D tmp
= new Point3D; |
| tmp.x = lerp( A.x, B.x, t ); |
| tmp.y = lerp( A.y, B.y, t ); |
| tmp.z = lerp( A.z, B.z, t ); |
| return tmp; |
} | | |
4.5.4 "Tweening" for Art and Animation
void drawTween( Point3D A[ ],
Point3D B[ ], int n, float t ) |
{ | for( int i = 0;
i < n; i++ ) |
| { | Point3D
P; |
| | P = tween( A[ i ],
B[ i ], t ); |
| | if( i == 0 ) |
| | | moveTo(
P.x, P.y ); |
| | else |
| | | lineTo(
P.x, P.y ); |
| } | | |
} | | | |
4.5.6 Representing Lines and Planes
- A line is defined by two points, say, C and B.
It is infinite in length, passing through the points and extending forever
in both directions. A line segment, or segment for short, is
defined by its endpoints. It extends only from one to the other. Its
parent line is the infinite line that
passes through its endpoints. A ray is "semi-infinite".
It is specified by a point and a direction, starting at that point and
extending infinitely far in a given direction.
- In computer graphics the most important representaion of lines is the
parametric form. As the parameter t varies,
the point P trace out all points on the straight line defined by
C and B. The line is L and b = B -
C.
- To develop the point normal or implicit form of a line
we start with a familiar form,where
f and g are constants. Every point ( x, y ) that
satisfies this equation is on the line. Unfortunatly, a 3D line requires
two equations.
- This can also be written as a dot product, For every point on a line a
certain dot product must have the same value.
- Suppose we know that line L passes through points C
and B. If we can find a vector n that is perpendicular
to L, then for any point R = ( x, y ) on L,
the vetor R - C must be perpendicular to n. We
have the following condition on R:
This is the point normal equation for the line, expressing the
fact that a certain dot product must turn out to be zero for every
point R on the line.
- To find a suitable n, let b = R - C
denote the vector from C to B. b⊥
will serve as the desired n, as will any scalar of
b⊥.
If C = ( 3, 4 ) and B = ( 5, -2 ), then
b = B - C = ( 2, -6 ) and
b⊥ = ( 6, 2 ). Choosing
C as the point on the line,
( 6, 2 ) • ( ( x, y ) -
( 3, 4 ) ) = 0
( 6x + 2y ) - ( 6×3 + 2×4 ) = 0
6x + 2y = 26
- Object faces are polygons that lie in parent planes. Planes also have
three forms.
- Three points in the plane, C, B, and A.
- The parametric form consists of a point C and two
nonparallel vectors a and b. If we are given three
noncollinear points A, B, and C in the plane,
we take a = A - C and b = B -
C. The parametric form for this plane is the point C
plus any two multiples of a and b.
- A plane is specified by any point B = ( bx,
by, bz ), and the direction n =
( nx, ny, nz ) normal or
perpendicular to the plane. For any point R = ( x, y,
z ) in the plane, the vector from R to B must be
perpendicular to n:
This is the point normal equation of the plane.
If plane P passes through ( 1, 2, 3 ) with normal vector
( 2, -1, -2 ), the point normal is
( 2, -1, -2 ) • ( ( x, y, z ) - ( 1, 2, 3 ) ) = 0
( 2x - y - 2z ) - ( 2×1 -
1×2 - 2×3 ) = 0
2x - y - 2z = -6
FINDING THE INTERSECTION OF TWO LINE SEGMENTS
One line segment has endpoints A and B, the other C and
D. Let b = B - A. Then
and if d = D - C,
The parametere t and u must be different. For the parent lines to
intersect there must be specific values of t and u for which the
two equations are equal:
Define c = C - A.
Now we have two equations in two unknowns. If we dot both sides with
d⊥ to eliminate the term in d.
d⊥ • bt =
d⊥ • c + d⊥ • du
d⊥ • bt =
d⊥ • c + 0
d⊥ • bt =
d⊥ • c
If d⊥ • b is zero, the lines are parallel.
If it is not zero
Then we dot both sides with b⊥.
u = |
b⊥ • c |
| or, as
b⊥ is antisymmetric |
|
u = |
b⊥ • c |
-b⊥ • d |
d⊥ • b |
This is the formula for the parent lines, not the segments. For that, if the
segments intersect at a point I, we substituting the value of t
I = A + b |
( |
d⊥ •
c |
) |
d⊥ • b |
This is the intersection point.
4.6.1 The Circle through Three Points
Besides a triangle and a plane, three points designate a circle. This is the
ex-circle or circumscribed circle of the triangle. The center
must lie on the perpendicular bisector of each side of the triangle.
L( t ) = ½( A + B ) +
( B - A )⊥t
Lets call the points A, B, and C, and define three vectors as:
a = B - A;
b = C - B;
c = A - C;
The perpendicular bisector of AB is the midpoint of AB
and the direction perpendicular to it. The midpoint is A + a/2. The
perpendicular to AB is a⊥. The perpendicular
bisector is now
For AC we have
The center lies where these two perpendicular bisectors meet
where a + b + c = 0. To eliminate u we dot both sides with c
t = ( 1/2 )( b • c )/( a⊥
• c ).
Therefore
|
center = A + |
1 |
( |
a + a⊥ |
b • c |
) |
2 |
a⊥ • c |
|
|
radius = |
| a | |
√ |
( |
b • c |
) |
² | + 1 |
2 | a&perp • c |
|
INTERSECTIONS OF LINES WITH PLANES; CLIPPING
Consider a ray starting at point A, with parametric description
We want to know where it intersects an object with point normal form
The hit occurs at time t = thit. At this value of t
the ray and the plane have the same coordinates. Solve for this time,
n • ( A + cthit - B ) = 0
can be rewritten as
n • ( A - B ) + n
• cthit = 0
which is a linear equation in thit
thit = |
n • ( B - A ) |
n • c |
If n • c = 0 they are parallel. Otherwise, the coordinates of the hit are
A2.1.2 Multiplying Two Matrices
Two matrices can be multiplied if they conform, or, the number of columns of the first
equals the number of rows of the second. Then, the terms of the product are the dot
product of each row of the first with each column of the second.
= | ( |
6×2 - 1×0 + 3×6 - 5×-3 |
|
2×2 + 1×0 + 1×6 + 8×-3 |
) |
6×8 - 1×1 + 3×-4 - 5×0 |
2×8 + 1×1 + 1×-4 + 8×0 |
6×0 - 1×5 + 3×7 - 5×1 |
2×0 + 1×5 + 1×7 + 8×1 |
In forming a product of two matrices A and B, the order in which the
matrices are taken makes a difference. For the expression AB, we say
"A premultiplies B" or "A is
postmultiplied by B".
CHAPTER 5: Transformations of Objects
5.2.3 Geometric Effects of Elementary 2D Affine Transformations
Translation | Scaling |
|
|
Rotation | Shearing |
( |
cos(θ) | -sin(θ) |
0 | ) |
sin(θ) | cos(θ) | 0 |
0 | 0 | 1 |
|
|
5.2.4 The Inverse of an Affine Transformation
Translation | Scaling |
|
( |
1 / Sx | 0 |
0 |
) |
0 | 1 / Sx |
0 |
0 | 0 | 1 |
|
Rotation | Shearing |
( |
cos(θ) | sin(θ) |
0 | ) |
-sin(θ) | cos(θ) |
0 |
0 | 0 | 1 |
|
|
5.2.5 Composing Affine Transformations
The order that multiple tranformations occur in matters. Multiplying matrices in
different orders gives different results. The representation used, if point P
is to be multiplied first by matrice M1, then by matrice
M2, it will be represented as
or
If you want to compose or concate matrices first,
or
M = M4( M3( M2(
M1() ) ) ).
5.2.6 Examples of Composing 2D Transformations
- So far all the rotations have been around the origin. Suppose we want to rotate or
pivot around point V. We have to translate V back to the origin, then rotate,
then translate back.
( |
1 | 0 |
Vx |
)( |
cos(θ) | -sin(θ) |
0 |
)( |
1 | 0 |
-Vx |
) |
0 | 1 |
Vy |
sin(θ) |
cos(θ) | 0 |
0 | 1 |
-Vy |
0 | 0 | 1 |
0 | 0 | 1 |
0 | 0 | 1 |
= ( |
cos(θ) | -sin(θ) |
dx |
) |
sin(θ) | cos(θ) |
dx |
0 | 0 | 1 |
- Scaling and shearing use the same "shift-transform-unshift"
sequence.
- A reflection around an axis other than x, y, or
z has to be shifted to x, y, or z,
transformed and unshifted. Call the axis of reflection x +
β. The final matrix is:
= ( |
cos(2β) | sin(2β) |
0 |
) |
sin(2β) | -cos(2β) |
0 |
0 | 0 | 1 |
- In 2D, successive rotations are additive. That will not be the case
in 3D.
5.2.7 Some Useful Properties of Affine Transformations
- Affine Transformations Preserve
- Affine combinations of points
- Lines and planes
- Parallelism of lines and planes
- Relative ratios
- The columns of the matrix reveal the transformed coordinate
frame.
- If an affine plane is scaled, area ×=
Scalingx × Scalingy
3D AFFINE TRANSFORMATIONS
P = γ + Pxi
+ Pyj + Pzk = |
( | Px |
) |
Py |
Pz |
1 |
5.3.1 The Elementary 3D Transformations
Translation |
( |
1 | 0 | 0 |
m14 |
) |
0 | 1 | 0 |
m24 |
0 | 0 | 1 |
m34 |
0 | 0 | 0 |
1 |
Shearing |
( |
1 | 0 | 0 |
0 |
) |
f | 1 | 0 |
0 |
0 | 0 | 1 |
0 |
0 | 0 | 0 |
1 |
Scaling |
( |
Sx | 0 |
0 | 0 |
) |
0 | Sx |
0 | 0 |
0 | 0 |
Sz | 0 |
0 | 0 |
0 | 1 |
ROTATIONS: In two dimensions you rotate about a point. In 3D you must also
specify an axis. Remember, the rotation direction we are using is "left
handed". Positive values of β cause a counterclockwise (CCW)
rotation about an axis as one looks inward from a point on the positive axis
toward the origin.
An x-roll:
Rx(β) |
( |
1 | 0 | 0 |
0 |
) |
0 | cos(β) |
-sin(β) | 0 |
0 | sin(β) |
cos(β) | 0 |
0 | 0 | 0 |
1 |
A y-roll:
Ry(β) |
( |
cos(β) | 0 |
sin(β) | 0 |
) |
0 | 1 |
0 | 0 |
-sin(β) | 0 |
cos(β) | 0 |
0 | 0 |
0 | 1 |
A z-roll:
Rz(β) |
( |
cos(β) | -sin(β) |
0 | 0 |
) |
sin(β) | cos(β) |
0 | 0 |
0 | 0 | 1 |
0 |
0 | 0 | 0 |
1 |
Note that 12 of the terms in each matrix are the zeros and ones of the
identity matrix. They occur in the row and column that correspond to the
axis about which the rotation is being made.
5.3.3 Combining Rotations
- Unlike 2D transformations, when you combine rotations around different
axis, the order that you do them in matters. Doing rotations in different orders
gives different results. The terminology is that 3D rotations do not commute.
- Euler says we can combine transformations to make rotations
around any arbitrary axis. There are two ways, first:
- Perform two rotations so that u becomes aligned with the
x-axis.
- Do a z-roll through the angle β.
- Undo the two alignment rotations to restore u to its original
direction.
Ru(β) = Ry(-θ)
Rz(φ) Rx(β)
Rz(-φ) Ry(θ)
- Second, establish a 2D coordinate system in the plane of rotation with 2
orthogonal vectors. Everything is expressed as a linear combination
of those vectors.
Ru(β) = |
( |
c+(1-c)ux² |
(1-c)uyux-suz |
(1-c)uzux+suy |
0 |
) |
(1-c)uxuy-suz |
c+(1-c)uy² |
(1-c)uzuy-sux |
0 |
(1-c)uxuz-suy |
(1-c)uyuz+sux |
c+(1-c)uz² |
0 |
0 | 0 | 0 | 1 |
where c = cos(β), s = sin(β), and (ux,
uy, uz) are the components of the unit
vector u.
5.3.4 Summary of Properties of 3D Affine Transformations
- Affine transformations preserve affine combinations of points. If
a + b = 1, then aP + bQ is a meaningful 3D point and
T(aP + bQ) = aT(P) + bT(Q).
- Affine transformations preserve lines and planes. Straightness is preserved:
The image T(L) of a line L in 3D space is another straight line;
the image T(W) of a of a plane W in 3D space is another plane.
- Parallelism of lines and planes is preserved. If W and Z
are parallel lines (or planes), then T(W) and T(Z) are also
parallel.
- Relative Ratios Are Preserved. If P is a fraction ƒ of the way
from point A to point B, then T(P) is the same fraction ƒ of
the way from point T(A) to T(B).
- The Columns of the Matrix Reveal the Transformed Coordinate Frame. If the
columns of M are the vectors m1, m2, and
m3 and the point m4, the transformation maps the frame
(i,j,k,γ) to the frame (m1, m2,
m3, m4).
- Effect of Transformations of the Volumes of Figures. If the 3D object D has
volume V, then the image T(D) of D has volume |det M|V,
where |det M| is the absolute value of the determinant of M.
- Every Affine Transformation Is Composed of Elementary Operations. A 3D affine
transformation may be decomposed into elementary transformations, in several ways.
CHANGING COORDINATE SYSTEMS
Transforming Points
To apply a sequence of transformations T1(),
T2(), T3() (in that order) to a point
P, form the matrix:
Then P is transformed to MP. To compose each successive
transformation Mi, you must premultiply by
Mi.
Transforming the Coordinate System
To apply a sequence of transformations T1(),
T2(), T3() (in that order) to the
coordinate system, form the matrix:
Then a point P expressed in the transformed system has coordinates MP
in the original system. To compose each additional transformation Mi,
you must postmultiply by Mi.
USING AFFINE TRANSFORMATIONS IN A PROGRAM
- We have already set up matricies for Window to Viewport mappings. Now we set up
matrix modelview.
- The three operations that work on the modelview matrix are glScaled(), glTranslated(),
and glRotated()
- These operations only compose a transformation with the current transformation. To initialize
we need an identity transformation. That is glLoadIdentity().
- In program code, the operations are called in opposite order to the way they are
applied. To rotate an object then translate it, the code is:
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
object.init();
glTranslated();
glRotated();
object.draw();
5.5.1 Saving the CT for Later Use
To save the current transformation use glPushMatrix() and glPopMatrix().
DRAWING 3D SCENES WITH OPENGL
5.6.1 An Overview of the Viewing Process and the Graphics Pipeline.
The graphics pipeline starts with three matrices.
- The modelview matrix provides what this text calls the CT or
current transformation. It has two functions. It handles the
rotations, scaling, and translation of the objects current transformation.
Then it handles the camera position. We will refer to the M-model
and the V-view portions of the VM matrix.
- The projection matrix reduces everything to a cube, -1 to 1
in every direction. Then clipping takes place.
- The viewport matrix maps objects into the final screen viewport.
5.6.2 Some OpenGL Tools for Modeling and Viewing
Three Functions are Used to Set Modeling Transformations.
- First, glMatrixMode( GL_MODELVIEW ); establishes the modelview
matrix as "current". Then it is modified with:
- glScaled( sx, sy, sz ); Postmultiply the current matrix,
CT, by a matrix that performs a scaling by sx in x, sy
in y, and sz in z. Put the result back into the current
matrix.
- glTranslated( dx, dy, dz ); Postmultiply the current matrix, CT,
by a matrix that performs a translation by dx in x, dy
in y, and dz in z. Put the result back into the current
matrix.
- glRotated( angle, ux, uy, uz );
Postmultiply the current matrix, CT, by a matrix that performs a rotation
through angle degrees about the axis that passes through the origin
and the point (ux, uy,
uz). Put the result back into the current matrix. The
equation used is in section 5.3.3.
Setting the Camera in OpenGL (for a Parallel Projection).
- glOrtho( left, right, bottom, top, near, far ); establishes
a parallelipiped view volume that extends from left to right
in x, bottom to top in y, and -near to
-far in z. The function creates a projection matrix and
postmultiplies the current matrix by it.
- Since this definition operates in eye coordinates, the camera's eye
is at the origin. Hence, near and far are down the negative
z-axis. Using a value of 2 for the near means to place the near plane
at z = -2.
- The folowing code sets the projection matrix:
glMatrixMode( GL_PROJECTION ); // make the projection matrix
current
glLoadIdentity(); // set it to the identy matrix
glOrtho( left, right, bottom, top, near, far ); // multiply it by the
new matrix
Positioning and Aiming the Camera.
- gluLookAt( eye.x, eye.y, eye.z, look.x, look.y, look.x, up.x,
up.y, up.z ); creates the view matrix and postmultiplies the
current matrix by it.
- Eye and look are straight forward, but it also takes an approximate
upwards direction. The camera angle won't always be up and down.
- We want this to set the V (view) part of the modelview matrix
VM. It is invoked before any modeling transformations are added,
since subsequent tranformations will postmultiply the modelview matrix.
glMatrixMode( GL_MODELVIEW ); |
// make the modelview matrix current |
glLoadIdentity(); | // start with a
unit matrix |
gluLookAt( |
eye.x, eye.y, eye.x, | // eye
position |
|
look.x, look.y, look.z, | // "look
at" point |
|
up.x, up.y, up.z ); | // approximate upwards
direction |
EXAMPLE: We want to look down at a scene. We set camera eye at (4, 4, 4),
looking at the origin with look = (0, 1, 0). The upwards direction is (0, 1, 0).
We want the view volume to have a width of 6.4 and height of 4.8 so its
aspect ration is 640 / 480. We want the near 1 and far at 50.
glMatrixMode( GL_PROJECTION ); // set the view volume
glLoadIdentity();
glOrtho( -3.2, 3.2, -2.4, 2.4, 1, 50 );
glMatrixMode( GL_MODELVIEW ); // place and aim the camera
glLoadIdentity();
glLookAt( 4, 4, 4, 0, 1, 0, 0, 1, 0 );
To examine matricies, create and copy an array
GLfloat mat[ 16 ];
glGetFloatv( GL_MODELVIEW_MATRIX, mat );
5.6.3 Drawing Elementary Shapes Provided by OpenGL
- glutWireCube( GLdouble size ); // each side is of length size
- glutWireSphere( GLdouble radius, GLint nSlices, nStacks )
- glutWireTorus( GLdouble inRad, outRad, GLint nSlices, nStacks )
- glutWireTeapot( GLdouble size )
- glutSolidCube( GLdouble size )
- glutSolidSphere( GLdouble radius, GLint nSlices, nStacks )
- glutSolid etc.
- glutWireTetrahedron()
- glutWireOctahedron()
- glutWireDodecahedron()
- glutWireIcosahedron()
- glutWireCone( GLdouble basRad, height, GLint nSlices, nStacks )
- Tapered cylinders: When the topRad is 1, there is no taper. When
it is 0, it is identical to a cone.
GLUquadricObj * qobj = gluNewQuadric();
gluQuadricDrawStyle( qobj, GLU_LINE );
gluCylinder( qobj, basRad, topRad, height, nSlices, nStacks );
- Solid objects in 3D require shading. The object surface has properties. This
is covered in Chapter 8 so the functions are only listed in this chapter.
glMaterialfv( GL_FRONT, GL_AMBIENT, GLfloat [ 4 ] );
glMaterialfv( GL_FRONT, GL_DIFFUSE, GLfloat [ 4 ] );
glMaterialfv( GL_FRONT, GL_SPECULAR, GLfloat [ 4 ] );
glMaterialfv( GL_FRONT, GL_SHININESS, GLfloat );
6.2.2 Finding the Normal Vectors
The normal of the face is the cross product of all the vectors,
or for graphics, a more efficient way is to use Newell's method:
| | N-1 | |
| mx = |
Σ |
(yi - ynext(i))(zi + znext(i)) |
| | i=0 | |
| | N-1 | |
| my = |
Σ |
(zi - znext(i))(xi + xnext(i)) |
| | i=0 | |
| | N-1 | |
| mz = |
Σ |
(xi - xnext(i))(yi + ynext(i)) |
| | i=0 | |
where next(j) = (j+1) mod N. This allows the wrap around from the
last vertex to the first ( [0] ).
6.4.4 Building Segmented Extrusions: Tubes and Snakes
-
If we stack extrusions end to end, and twist the individual extrusions,
we make tubes of assorted shapes. Each extrusion is called a waist
of the tube. It is fairly simple to think of the tube as wrapped around a
curve or spine. As an example, lets examine the parametric representation
of the curve
C(t) = ( cos(t), sin(t), bt )
for some constant b.
- Create a Frenet frame at each value of ti. The
vector T(ti) that is tangent to the curve is computed.
Then two vectors N(ti) and B(ti),
which are perpendicular to T(ti) and to each other,
are computed. This supplies a matrix M with columns directly
of N(t), B(t),
T(t), and C(t), for each value of t.
Mi = ( N(ti) |
B(ti) | T(ti) |
C(ti) ).
-
If C(t) is differerentiable it's derivative,
C′(t), is tangent to the
curve. If C(t) has componets
Cx(t), Cy(t), Cz(t), the derivative is simply
C′(t) = ( C′x(t), C′y(t), C′z(t) ).
We normalize this to unit length to obtain T(t).
- If we form the cross product of C′(t) with any
noncollinear vector we must obtain a vector perpendicular to T(t)
and therefore perpendicular to the spine of the curve. A good choice is the second
derivative, acceleration. Again, normalize to obtain a "unit
binormal" vector.
B(t) = |
C′(t) ×
C″(t) |
| C′(t) × C″(t) | |
- Obtain a vector perpendicular to both T(t) and B(t)
by using the cross product again:
- The values are:
N(t) = ( - cos(t), - sin(t), 0 )
B(t) = |
( b sin(t), -b cos(t), 1 ) |
√ 1 + b² |
T(t) = |
( - sin(t), cos(t), b ) |
√ 1 + b² |
C(t) = ( cos(t), sin(t), bt )
- If C(t) is complicated it may be awkward to form successive
derivatives. It is possible to approximate them numerically by using
C′ ≅ |
C(t + ε) - C(t - ε) |
2ε |
C″ ≅ |
C(t - ε) - 2C(t)
+ C(t + ε) |
ε² |
6.4.5 "Discretely" Swept
Surfaces of Revolution |
|
If we employ pure rotations for the affine transformations
and place all spine points at the origin, we are circularly sweeping a shape about
an axis. This is called a surface of revolution. Here we show a profile
and the resulting swept surface that approximates a martini glass. |
MESH APPROXIMATIONS TO SMOOTH OBJECTS
- So far our meshes tend to be "data intensive"--specified by
listing the vertices of each face individually. Now we want to build meshes
defined by formulas rather than data. We need to be able to shade them. The
proper algorithm (Gouraud shading) requires us to find the proper normal
vector at each vertex of each face.
- The basic approach is to "polygonalize" or
"tesselate" the surface into a collection of flat faces small
enough to gracefully change direction.
6.5.2 The Normal Vector to a Surface
- Parametrically the normal direction to each vertex is the vector
from the origin to the surface point. This can be found using partial
derivatives.
n( u0, v0 ) = |
( |
∂p | × | ∂p |
)| | |
∂u | ∂v |
u=u0, v=v0 |
and then can be normalized to unit-length.
- Implicitly it would be found using the gradient, ∇F, of F
n( x0, y0,
z0 ) = ∇F|x=x0,
y=y0, z=z0 = |
( |
∂F, | | ∂F, |
| ∂F |
)| | |
∂x | ∂y | ∂z |
x=x0,
y=y0, z=z0 |
and then normalized.
6.5.7 Surfaces of Revolutions
A surface of revolution is formed by a rotational sweep of a profile
curve C around an axis. If the surface is given by:
P(u, v) = ( X(v)cos(u),
X(v)sin(u), Z(v) )
where X and Z are functions, then the normal vector can be given by:
| • |
| • |
| • | |
n(u, v) = X(v) ( |
Z | (v)cos(u), |
Z | (v)sin(u), - |
X | (v) ) |
where the dot denotes the first derivative of the function.
CHAPTER 7: Three-Dimensional Viewing
THE CAMERA REVISITED
- So far we have seen only parallel projections. The view volume
is a parallepiped bounded by six walls, including a near and a far
plane. OpenGL also supports perspective views of 3D scenes. It is
similar to the camera used before, except its view volume has a
different shape.
- The eye is at the apex of a rectangular pyramid, the view
volume. The eye is looking into the pyramid. The opening
is set by the view angle θ. Two planes are defined
perpendicular to the axis of the pyramid, the near plane
and the far plane. Where the planes intersect the pyramid,
they form retangular windows. The windows have a certain aspect
ratio, which can be set in OpenGL.
- The view volume is bounded by these planes. Anything outside is
clipped off and points inside are projected onto the viewplane
at corresponding point P'.
7.2.1 Setting the View Volume
- Recall that the shape of the camera view volume is encoded in the
projection matrix of the graphics pipeline. It can be set using
gluPerspective() and it's four parameters.
glMatrixMode( GL_PROJECTION ); | //
make the projection matrix current |
glLoadIdentity(); | // start with
a unit matrix |
gluPerspective( viewAngle, aspectRatio, N, F );
| // load appropriate values |
- The parameter viewAngle, given in degrees, sets the angle between the top
and bottom walls of the pyramid.
- The parameter aspectRatio sets the aspect ratio of any window parallel to
the xy-plane.
- N is the distance from the eye to the near plane and F is the
distance to the far plane. N and F values should be positive.
- i.e.: gluPerspecive( 60.0, 1.5, 0.3, 50.0 )
establishes the view volume to have a vertical opening of 60°, with a window
aspect ratio of 1.5 and planes at z = -0.3 and z = -50.0.
7.2.2 Positioning and Pointing the Camera
Changing the aim and position of the camera is the same as performing rotations and
translations. These are a part of the modelview matrix, not the projection
matrix. Position and orientation are set exactly the same as parallel-projection.
The only difference is that the camera resides in the projection matrix which
determines the shape of the view volume.
glMatrixMode( GL_MODELVIEW ); | //
make the modelview matrix current |
glLoadIdentity(); | // start with
a unit matrix |
gluLookAt( eye.x, eye.y, eye.z, look.x, look.y,
look.z, up.x, up.y, up.z );
| // load appropriate values |
The General Camera with Arbitrary Orientation and Position
- When we move and rotate this camera we need to describe this
motion precisely to determine the resulting modelview matrix.
- We will attach an explicit coordinate system to the camera. This
coordinate system has its origin at the eye and has three axes, usually
called the u-, v-, and n-axes, that define its
orientation. Its directions are given by vectors u,
v, and n. Because by default, the camera looks down
the negative z-axis, we say in general that the camera looks down
the negative n-axis, in the direction -n. The direction
u points off "to the right of" the camera, and the direction
v points "upward".
- Position is easy to describe, but orientation is difficult. Aviation
uses the terms pitch, heading, yaw, and roll.
Pitch is the angle of the longitudinal axis (running from tail to
nose and having directin -n) makes with the horizontal plane (is
it pointed up or down). Roll is rotation about the longitudinal
axis. Heading is the direction headed in. Given n, heading
and pitch can be expressed as -n in spherical coordinates. The
vector -n has longitude and latitude given by angles θ and
φ, respectively. Heading is given by the longitude of -n
and pitch is given by the latitude of -n.
- Pitch is rotation about the u-axis. Roll is rotation about the
n-axis. The common term to change heading is yaw. Yawing
left or right rotates about the v-axis.
- gluLookAt() is great for setting up the
initial camera but it works with Cartesian coordinates, whereas orientation
deals with angles and rotations. OpenGL doesn't give direct access to
u, v, and n so we need to write code that does.
BUILDING A CAMERA IN A PROGRAM
In order to have fine control over camera movements, we create
and manipulate our own camera in a program, we create a
Camera class.