Documente Academic
Documente Profesional
Documente Cultură
Lab 5
Lab 5
a0
a
1
A=
a2
a3
a4
a5
a6
a7
a8 a12
a9 a13
.
a10 a14
a11 a15
(1)
Direcia de observare
yv
Ov
zv
xv
zv
C
C
z v = znear
z v = zfar
Lucrarea 5
Volumul de vizualizare n cazul proieciei perspectiv, n OpenGL, este un trunchi de
piramid, ABCDABCD . Trunchiul de piramid de vizualizare (frustum), este determinat de
intersecia a dou plane de vizualizare, planul apropiat i planul deprtat, cu patru plane
laterale. Planul de vizualizare apropiat este i planul n care sunt proiectate toate obiectele
vizibile ale scenei. Suprafaa ABCD din planul de vizualizare apropiat (planul de proiecie)
constituie fereastra de vizualizare (view plane window). Prin urmare, trunchiul de piramid de
vizualizare este orientat spre zv i este fi definit prin urmtoarele valori:
(left, bottom) i (right, top): coordonatele colurilor ferestrei din planul din fa (ale
ferestrei de vizualizare);
znear: distana (ca valoare pozitiv) de la poziia observatorului la planul din fa;
zfar: distana (ca valoare pozitiv) de la poziia observatorului la planul din spate.
Funcia OpenGL care definete o proiecie perspectiv ca cea din figura 1 este:
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble znear, GLdouble zfar);
Colurile ferestrei 2D din planul de proiecie, (left, bottom, -znear) i (right, top, -zfar)
sunt mapate pe colurile stnga-jos i dreapta-sus ale ferestrei 2D din sistemul coordonatelor
de decupare, adic (1,1,1) i (1,1,1) . Matricea de proiecie este urmtoarea:
2 znear
right left
0
MP =
0
2 znear
top bottom
0
0
right + left
right left
top + bottom
top bottom
zfar + znear
zfar znear
1
0
.
2 zfar znear
zfar znear
0
(2)
O alt funcie care poate fi folosit pentru definirea proieciei perspectiv este:
void gluPerspective(GLdouble fovy, GLdouble aspect,
GLdouble znear, GLdouble zfar);
[0.0,180.0] ;
aspect: raportul lime/nlime al laturilor ferestrei din planul apropiat; acest raport
trebuie s corespund raportului lime/nlime asociat porii de afiare. De exemplu,
dac aspect = 2 , atunci unghiul de vizualizare pe direcia axei xv este de dou ori mai
mare dect cel pe direcia axei yv . Dac poarta de afiare are limea de dou ori mai
mare dect nlimea, atunci imaginea va fi afiat nedistorsionat.
C = C M n 1 = M n M n 1
.........................................
C = C M1 = M n M n 1 K M 2 M1
(3)
C = M = M n M n 1 K M 2 M1
P = M P = M n M n 1 K M1 P
n aceast transformare, se aplic mai nti matricea M 1 punctului P . Punctului astfel rezultat
i se aplic transformarea M 2 .a.m.d . Acest mod de calcul al matricelor compuse este folosit
n OpenGL.
Matricea curent se poate iniializa cu matricea identitate prin funcia
glLoadIndentity() sau cu o matrice oarecare, dat de un pointer la un vector de 16 valori
consecutive, prin funcia glLoadMatrix#().
glLoadMatrixd( const GLdouble *m);
glLoadMatrixf( const GLfloat *m);
Valorile din vectorul GLdouble *m (respectiv GLfloat *m) sunt atribuite n ordinea
coloan major matricei curente.
Coninutul matricei curente poate fi modificat prin multiplicare (la dreapta) cu o alt
matrice, dat printr-un vector de 16 valori de tip double sau float utiliznd funcia
glMultMatrix#().
glMultMatrixd( const GLdouble *m);
Lucrarea 5
glMultMatrixf( const GLfloat *m);
M = M n M v Mi
(4)
unde
Lucrarea 5
glPushMatrix()
glTranslate#()
glPopMatrix()
C = M
M
C = M
M
M
C = MT
M
M
C = M
M
M n +1
on +1
yn
on
o1
Mn
M n, n +1
yn +1
xn +1
zn
x
z
Putem scrie:
M n +1 = M n M n,n +1 ,
(5)
3. Aplicaii
n aplicaiile urmtoare se urmrete utilizarea stivelor matricelor de transformri geometrice.
Exemplul 1
Braul trebuie s se roteasc n jurul umrului (captul din stnga al primului segment) i
cotului. Micrile de rotaie au loc att timp ct sunt apsate anumite taste.
Lucrarea 5
Indicaii. Pentru construirea celor patru segmente (bra, antebra i cele dou degete) se poate
folosi scalarea unui cub, dar mai nti trebuie aplicat o transformare care s orienteze
corespunztor fiecare segment. Deoarece sistemul de coordonate local al modelului (cubului)
este iniial n centrul cubului, trebuie translat sistemul de coordonate local pe o muchie a
cubului (sau pe una din feele cubului), altfel, rotaiile cubului se vor face fa de centrul lui i
nu fa de punctul de pivotare. Dup apelul lui glTranslate#() (pentru stabilirea punctului
de pivotare) i glRotate#() (pentru a pivota cubul), se va efectua translaia sistemului de
coordonate n vechiul punct. Apoi cubul este scalat i trasat, n felul acesta construind primul
segment (braul). Codul pentru primul segment este:
glTranslatef (-1.0, 0.0, 0.0);
glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
glutWireCube (1.0);
glPopMatrix();
Pentru construirea celui de-al doilea segment, trebuie mutat sistemul de coordonate
local n urmtorul punct de pivotare (rotaie). Deoarece sistemul de coordonate local al
obiectului precedent a fost rotit anterior, axa x este deja de-a lungul braului. De aceea
translarea de-a lungul axei x deplaseaz sistemul de coordonate n urmtorul punct de rotaie
(ncheietura braului). Odat stabilit punctul de rotaie se poate utiliza acelai cod pentru
trasarea celui de-al doilea segment ca i pentru primul segment. Acest procedeu poate continua
pentru un numr oarecare de elemente (bra, antebra, mn, degete).
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
glTranslatef (1.5, 0.0, 0.0);
glPushMatrix();
glScalef (3.0, 0.4, 1.0);
glutWireCube (1.0);
glPopMatrix();
Folosind indicaiile de mai sus s se completeze programul de mai jos astfel nct s se
realizeze funciile cerute.
static int shoulder = 0, elbow = 30, finger=15; //unghiuri de rotatie
GLfloat x1 = 3, x2 = 5, x3 = 1; //dimensiuni segmente
GLfloat xp1 = -5; //pozitia pe x a primului punct de pivotare
void init(void)
{
..........
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 0);
glPushMatrix();
Probleme propuse
1. Modificai problema din exemplul 1 adugnd i alte segmente la bra. De exemplu,
adugai cteva degete la mn ca n fig. 5. Pivotarea se va face n jurul muchiei marginale a
unui segment.
Lucrarea 5
10