|
p.97, p.697
A series of three computer operations convert an object's three-dimensional coordinates to pixel positions on the screen.
The transformation process to produce the desired scene for viewing is analogous to taking a photograph with a camera.
|
1. Set up your tripod and pointing the camera at the scene --- viewing transformation.
2. Arrange the scene to be photographed into the desired composition -- modeling transformation
3. Choose a camera lens or adjust the zoom -- projection transformation
4. Determine the size of final photograph -- viewport mapping |
![]() |
To specify viewing, modeling, and projection transformations, you construct a 4 by 4 matrix M, which is then multiplied by the coordinates of each vertex v in the scene to accomplish the transformation
//cube.cpp
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity (); /* clear the matrix */
/* viewing transformation */
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glScalef (1.0, 2.0, 1.0); /* modeling transformation */
glutWireCube (1.0);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
|
|
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);:
glFrustum() -- defines the projection transformation
(
a more commonly used alternative routine is gluPerspective() )
Theorem. If the vectors V1,V2, ..., Vn form an orthonormal set, then the n x n matrix constructed by setting the j-th column equal to Vj for all 1 ≤ j ≤ n is orthogonal.
Proof. Since Vj's are orthonormal, ( MTM ) ij = Vi.Vj = dij where dij is the Kronecker delta symbol. So MT M = I. Therefore, MT = M -1 .
Theorem. If the n x n matrix M is orthogonal, then M preserves lengths and angles.
Proof. Let M be orthogonal and P, Q are two vectors. Then
Example
|
Vectors and Points
Homogeneous Representation of a Point and a Vector
A vector
A point
Properties
Any affine combination of points is a legitimate point
Let
Then
or
which is a valid point as t + (1-t) is 1. So a point plus a scaled vector is also a valid point.
| m | ||
| A = | ![]() |
ai Pi |
| i=1 |
Is A a point or a vector?
Answer:
Calculate the sum of coefficients
| m | ||
| S = | ![]() |
ai |
| i=1 |
We use the preceeding ideas to show that the three medians of the above triangle meet at a point that lies two-thirds of the way along each median. This point is the centroid.
Proof:
The point that is two-thirds of the way from A to D lies at
which yields
Since this result is symmetrical in A, B and C, it must also be two-thirds of the way along the median from B and two-thirds of the way along the median from C. Hence the three medians meet there, and G is the centroid.
This result generalizes nicely for a regular polygon with N sides: the centroid is simply the average of the location of the N vertices, another affine combination
Linear interpolation of between points R and Q:
In one dimension, it can be implemented as:
float lerp ( float q, float r, float t )
{
return q + ( r - q ) * t; //same as ( 1 - t ) * q + t * r;
}
|
Point P(t) is tween ( in-between ) at t of points Q and R if t is a fraction and P(t) is computed the way along the straight line QR.
Point2 tween( Point2 P1, Point2 P2, float t )
{
Point2 P;
P.x = P1.x + ( P2.x - P1.x ) * t;
P.y = P1.y + ( P2.y - P1.y ) * t;
return P;
}
|
Polyline R formed by points: R0, R1, .., Ri, ... Rn-1
We construct polyline P with points: Q0, Q1, .., Qi, ... Qn-1 by 'interpolating' Q and R, i.e.
When t = 1, Pi = Ri ( i.e. P = R )
So when t changes from 0, to 0.1, 0.2, ..., to 1, P begins with the shape Q and gradaully morphs to R.
|
|
Class Exercise:
F( x, y ) = 0
e.g. Straight line through points P and Q:
e.g Circle with radius R centered at origin:
F(x, y ) = x2 + y2 - R2
Advantages:
F(x, y) > 0 ( x, y ) outside curve
F(x, y) < 0 ( x, y ) inside curve
parametric Form:
e.g. A line passing through points P at t = 0, and Q at t = 1
x(t) = Px + ( Qx - Px )t
y(t) = Py + ( Qy - Py )t
e.g. ellipse with half width W, half height H
y(t) = H sin ( t ) for 0 ≤ t ≤ 2π
Advantages:
//draw the curve ( x(t), y(t) ) using // the array t[0] .... t[n-1] of "sample-times" glBegin( GL_LINES ) for ( int i = 0; i < n; ++i ) glVertex2f( x(t[i]), y(t[i]) ); glEnd(); |
P(t) = ( x(t), y(t), z(t) )
e.g circular helix
y(t) = sin ( t )
z(t) = bt
Consider two points P and Q
|
|
An affine transformation can transform point P to point Q and the transformation can be represented by a matrix M
| M = |
|
Q can be found by
|
= |
|
|
If mii = 1 and mij = for i ≠ j, we have the identity matrix:
| I = |
|
| void glLoadIdentity( void ); |
| Sets the current matrix to the 4 x 4 identity matrix |
| void glLoadMatrix{fd}(const TYPE *m); | Sets the sixteen values of the current matrix to those specified by m. |
| void glMultMatrix{fd}(const TYPE *m); | Multiplies the matrix specified by the sixteen values pointed to by m by the current matrix and stores the result as the current matrix. |
Translation
|
|
| void glTranslate{fd}(TYPE Tx, TYPE Ty, TYPE Tz); | Multiplies the current matrix by a matrix that moves (translates) an object by the given Tx, Ty, and Tz values (or moves the local coordinate system by the same amounts). |
Scaling
|
Scaling and reflection: glScalef(2.0, -0.5, 1.0); |
| void glScale{fd}(TYPE Sx, TYPE Sy, TYPE Sz); |
| Multiplies the current matrix by a matrix that stretches, shrinks, or reflects an object along the axes. Each x, y, and z coordinate of every point in the object is multiplied by the corresponding argument Sx, Sy, or Sz. With the local coordinate system approach, the local coordinate axes are stretched, shrunk, or reflected by the Sx, Sy, and Sz factors, and the associated object is transformed with them. |
Rotations
Rotation about an axis
Elementary rotations about a coordinate axis:
Suppose
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Example: Where will be the point P = ( 3, 1, 4 ) after a rotation of 30o about the y-axis.
Solution:
----------
Here θ = 30o, cos θ = 0.866, and sin θ = 0.5
The new position is given by
| Q = M.P = Ry(30o).P = |
|
3D affine transformations can be composed and the result is another 3D affine transformation
Example: What is the matrix associated with an x-roll of 45o, followed by a y-roll of 30o, followed by a z-roll of 60o,
Solution:
---------
| M = | ![]() |
|
![]() |
![]() |
|
![]() |
![]() |
|
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||
| = | ![]() |
|
![]() |
| Euler's Theorem: Any rotation ( or sequence of rotations ) about a point is equivalent to a single rotation about some axis through that point. |
| void glRotate{fd}(TYPE angle, TYPE x, TYPE y, TYPE z); |
| Multiplies the current matrix by a matrix that rotates an object (or the local coordinate system) in a counterclockwise direction about the ray from the origin through the point (x, y, z). The angle parameter specifies the angle of rotation in degrees. |
glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); draw_triangle(); /* solid lines */ glEnable(GL_LINE_STIPPLE); /* dashed lines */ glLineStipple(1, 0xF0F0); glLoadIdentity(); glTranslatef(-20.0, 0.0, 0.0); draw_triangle(); glLineStipple(1, 0xF00F); /*long dashed lines */ glLoadIdentity(); glScalef(1.5, 0.5, 1.0); draw_triangle(); glLineStipple(1, 0x8888); /* dotted lines */ glLoadIdentity(); glRotatef (90.0, 0.0, 0.0, 1.0); draw_triangle (); glDisable (GL_LINE_STIPPLE); |
![]() |
void draw_trangle( void )
{
glBegin ( GL_LINE_LOOP );
glVertex2f( 0.0, 25.0 );
glVertex2f( 25.0, -25.0 );
glVertex2f( -25.0, -25.0 );
glEnd();
}
|