Transformation

parakeetincurableSoftware and s/w Development

Dec 13, 2013 (3 years and 7 months ago)

73 views

Chi
-
Cheng Lin, Winona State University

CS430

Computer Graphics

Programming with
Affine Transformations

2

Topics


Affine Transformations in OpenGL


Saving Current Transformation


Drawing 3D Scenes with OpenGL


OpenGL Functions for Modeling and
Viewing

3

Affine Transformations in OpenGL


CT: current transformation


Simplified graphics pipeline






OpenGL maintains so
-
called modelview
matrix


Every vertex passed down the graphics
pipeline is multiplied by this matrix

CT

Window
-
to
-
Viewport

Transformation

World Window

V

Q

V

Q

S

S

Viewport

Model (Master)

Coordinate System

World

Coordinate System

Screen

Coordinate System

4

Affine Transformations in OpenGL


OpenGL is a 3D graphics package


Transformations are 3D


How does it work in 2D?


2D drawing is done in the
xy
-
plane,
z

coordinate is 0.


Translation:
d
z

= 0


Scaling:
S
z

= 1


Rotation:
z
-
roll

y

x

z

5

Affine Transformations in OpenGL


Fundamental Transformations


Translation: glTranslated(dx, dy, dz)


for 2D: glTranslated(dx, dy, 0)


Scaling: glScaled(sx, sy, sz)


for 2D: glScaled(sx, sy, 1.0)


Rotation: glRotated(angle, ux, uy, uz)


for 2D: glRotated(angle, 0, 0, 1)


Transformations does not set CT
directly, a matrix is
postmultiplied

to CT


CT = CT


M

6

Affine Transformations in OpenGL


Canvas functions


void Canvas:: initCT(void)


{




glMatrixMode(GL_MODELVIEW);




glLoadIdentity();


}


void Canvas:: scale2D(double sx, double sy)


{




glMatrixMode(GL_MODELVIEW);




glScaled(dx, dy, 1.0);


}

7

Affine Transformations in OpenGL


Canvas functions


void Canvas:: translate2D(double dx, double dy)


{




glMatrixMode(GL_MODELVIEW);




glTranslated(dx, dy, 0);


}


void Canvas:: rotate2D(double angle)


{




glMatrixMode(GL_MODELVIEW);




glRotated(angle, 0.0, 0.0, 1.0);


}

8

Transformations Example


Draw a house. Draw another house by
rotating it through
-
30
°

and then
translating it through (32, 25)


cvs.initCT();


house();


cvs.translate2D(32, 25);


cvs.rotate2D(
-
30.0);


house();

9

Transformations Example

10

Transformations Example


Think of it in two different ways


Q

=
T
(32, 25)
R
(
-
30)
P




CT = CT


T
(32, 25)


R
(
-
30)


Translate the coordinate system through
(32, 25) and then rotate it through

30
°


The code generated by these two ways
is identical.


More examples


Examples 5.5.1, 5.5.2, 5.5.3, and 5.5.4

11

Saving Current Transformation


We can save and restore CTs using
glPushMatrix() and glPopMatrix()


Manipulation of a stack of CT

CT
3

CT
2

CT
1

Before

CT
3

CT
2

CT
1

CT
4

After

pushCT()

After

rotate2D()

CT
3

CT
2

CT
1

CT
4
= CT
3



Rot

CT
3

CT
2

CT
1

After

popCT()

12

Saving Current Transformation


Canvas functions


void Canvas:: pushCT(void)


{




glMatrixMode(GL_MODELVIEW);




glPushMatrix();


}


void Canvas:: popCT(void)


{




glMatrixMode(GL_MODELVIEW);




glPopMatrix();


}

13

Saving CT Examples


Example 5.5.5


Example 5.5.6


Master coordinate system: where an object
is defined


Modeling transformation: transforms an
object from its master coordinate system
to world coordinate system to produce an
instance


Instance: a picture of an object in the
scene

14

Drawing 3D Scenes with OpenGL


The concept of “camera” (eye) is used
for 3D viewing


Our 2D drawing is a special case of 3D
drawing

y

x

z

eye

window

near plane

far plane

Viewport

view volume

15

Drawing 3D Scenes with OpenGL


Camera to produce parallel view of a 3D
scene

16

Drawing 3D Scenes with OpenGL


Simplified OpenGL graphics pipeline

VM

P

clip

V
p

modelview

matrix

projection

matrix

viewport

matrix

17

Drawing 3D Scenes with OpenGL


Modelview matrix = CT


Object transformation + camera transformation


Applying model matrix
M

then viewing matrix
V

18

Drawing 3D Scenes with OpenGL


Projection matrix


Shifts and scales view volume into a
standard cube

(extension from

1 to 1)


Distortion can be compensated by viewport
transformation later

19

Drawing 3D Scenes with OpenGL


Viewport matrix


Maps surviving portion of objects into a 3D
viewport after clipping is performed


Standard cube




block w/
x

and
y

extending across viewport
and
z

from 0 to 1

20

OpenGL Modeling and Viewing Functions


Modeling transformation


Translation: glTranslated(dx, dy, dz)


Scaling: glScaled(sx, sy, sz)


Rotation: glRotated(angle, ux, uy, uz)


Camera for parallel projection


glMatrixMode(GL_PROJECTION);


glLoadIdentity();


glOrtho(left, right, bottom, top, near, far)


Example


near=2: near plane is 2 units in front of eye


far=20: far plane is 20 units in front of eye

21

OpenGL Modeling and Viewing Functions


Positioning and aiming camera


glMatrixMode(GL_MODELVIEW);


glLoadIdentity();


glutLookAt(eye.x, eye.y, eye.z, // eye position





look.x, look.y, look.z, //
look at

point


up.x, up.y, up.z) // up vector


Up vector is often set to (0, 1, 0)


glutLookAt() builds a matrix that converts
world coordinates into eye coordinates.

22

Set up a Typical Camera
-

Example



glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(
-
3.2, 3.2,
-
2.4, 2.4, 1, 50)

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glutLookAt(4, 4, 4,





0, 1, 0,





0, 1, 0)

(4, 4, 4)

(0, 1, 0)

23

Transformation Matrix for LookAt


Camera coordinate system


Axes:
u
,
v
,
n



n

=
eye



look


u
=
up


n


v

=
n



u


Origin:
eye

(looking in the direction

n
)


Transformation matrix






















1
0
0
0
n
v
u
eye
n
n
n
eye
v
v
v
eye
u
u
u
z
y
x
z
y
x
z
y
x
V
24

Transformation Matrix for LookAt

25

Elementary 3D Shapes Provided by
OpenGL


Cube


glutWireCube(GLdouble size)


size = length of a side


Sphere


glutWireSphere(GLdouble radius, GLint
nSlices, GLint nStacks)


Approximated by polygonal faces


nSlices = #polygons around
z
-
axis


nStacks = #bands along
z
-
axis

26

Elementary 3D Shapes Provided by
OpenGL


Torus


glutWireTorus(GLdouble inRad, GLdouble
outRad, GLint nSlices, GLint nStacks)


Approximated by polygonal faces


Teapots


glutWireTeapot(GLdouble size)



There are solid counterparts of the wire
objects

27

Plantonic Solids Provided by OpenGL


Tetrahedron


glutWireTetrahedron()


Octahedron


glutWireOctahedron()


Dodecahedron


glutWireDodecahedron()


Icosahedron


glutWireIcosahedron()


All of them are centered at the origin

28

Plantonic Solids Provided by OpenGL

29

Cone Provided by OpenGL


Cone


glutWireCone(GLdouble baseRad,
GLdouble height, GLint nSlices, GLint
nStacks)


Axis coincides with the
z
-
axis


Base rests on
xy
-
plane and extends to
z
= height


baseRad: radius at
z

= 0

30

Tapered Cylinder Provided by OpenGL


Tapered cylinder


gluCylinder(GLUquadricObj *qobj,
GLdouble baseRad, GLdouble topRad,
GLdouble height, GLint nSlices, GLint
nStacks)


Axis coincides with the
z
-
axis


Base rests on
xy
-
plane and extends to
z
= height


baseRad: radius at
z

= 0


topRad: radius at
z

= height

31

Tapered Cylinder Provided by OpenGL


A family of shapes distinguished by the
value of topRad


To draw, we have to


Deifne a new quadric object


Set drawing style


GLU_LINE: wire frame


GLU_FILL: solid rendering


Draw the object

32

Tapered Cylinder Provided by OpenGL


Example


wire frame cylinder


GLUquadricObj *qobj;


qobj = gluNewQuadric();


gluQuadricDrawStyle(qobj, GLU_LINE);


gluCylinder(qobj, baseRad, topRad,




height, nSlices, nStacks);





Study Example 5.6.2

33

34

35

#include <gl/glut.h>

//<<<<<<<<<<<<<<<<<<< axis >>>>>>>>>>>>>>

void axis(double length)

{ // draw a z
-
axis, with cone at end


glPushMatrix();


glBegin(GL_LINES);



glVertex3d(0, 0, 0); glVertex3d(0,0,length); // along the
z
-
axis


glEnd();


glTranslated(0, 0,length
-
0.2);


glutWireCone(0.04, 0.2, 12, 9);


glPopMatrix();

}

36

//<<<<<<<<<<<<<< displayWire >>>>>>>>>>>>>>

void displayWire(void)

{


glMatrixMode(GL_PROJECTION); // set the view volume
shape


glLoadIdentity();


glOrtho(
-
2.0*64/48.0, 2.0*64/48.0,
-
2.0, 2.0, 0.1, 100);


glMatrixMode(GL_MODELVIEW); // position and aim the
camera


glLoadIdentity();


gluLookAt(2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);


// to obtain the picture shown in Figure 5.59 we have to


// change the eye location as follows


// gluLookAt(1.0, 1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

37


glClear(GL_COLOR_BUFFER_BIT); // clear the screen



glColor3d(0,0,0); // draw black lines



axis(0.5);






// z
-
axis


glPushMatrix();


glRotated(90, 0, 1, 0);


axis(0.5);





// x
-
axis


glRotated(
-
90, 1, 0, 0);


axis(0.5);





// y
-
axis


glPopMatrix();




glPushMatrix();


glTranslated(0.5, 0.5, 0.5); // big cube at (0.5, 0.5, 0.5)


glutWireCube(1.0);


glPopMatrix();

38


glPushMatrix();



glTranslated(1.0,1.0,0);

// sphere at (1,1,0)


glutWireSphere(0.25, 10, 8);


glPopMatrix();





glPushMatrix();



glTranslated(1.0,0,1.0);

// cone at (1,0,1)


glutWireCone(0.2, 0.5, 10, 8);


glPopMatrix();




glPushMatrix();


glTranslated(1,1,1);


glutWireTeapot(0.2); // teapot at (1,1,1)


glPopMatrix();

39


glPushMatrix();


glTranslated(0, 1.0 ,0); // torus at (0,1,0)


glRotated(90.0, 1,0,0);


glutWireTorus(0.1, 0.3, 10,10);


glPopMatrix();



glPushMatrix();


glTranslated(1.0, 0 ,0); // dodecahedron at (1,0,0)


glScaled(0.15, 0.15, 0.15);


glutWireDodecahedron();


glPopMatrix();


40


glPushMatrix();


glTranslated(0, 1.0 ,1.0); // small cube at (0,1,1)


glutWireCube(0.25);


glPopMatrix();



glPushMatrix();


glTranslated(0, 0 ,1.0); // cylinder at (0,0,1)


GLUquadricObj * qobj;


qobj = gluNewQuadric();


gluQuadricDrawStyle(qobj,GLU_LINE);


gluCylinder(qobj, 0.2, 0.2, 0.4, 8,8);


glPopMatrix();


glFlush();

}

41

//<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>

void main(int argc, char **argv)

{


glutInit(&argc, argv);


glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );


glutInitWindowSize(640,480);


glutInitWindowPosition(100, 100);


glutCreateWindow("Transformation testbed
-

wireframes");


glutDisplayFunc(displayWire);


glClearColor(1.0f, 1.0f, 1.0f,0.0f); // background is white


glViewport(0, 0, 640, 480);


glutMainLoop();

}