Grafika 3D - Fizyka UMK

advertisement
Wykład z grafiki komputerowej II (3D)
Jacek Matulewski (e-mail: [email protected])
http://www.fizyka.umk.pl/~jacek/dydaktyka/3d/
Grafika 3D
Współrzędne jednorodne
Wersja: 15 listopada 2007
Transformacje
Podstawowe pojęcia grafiki 3D:
• Transformacje – określane we współrzędnych sceny 3D
translacja (glTranslatef), obrót (glRotatef)
skalowanie (glScalef), pochylenie
złożenie – dowolna macierz 4x4 (glMultMatrixf)
• Transformacje muszą być ustalone
przed narysowaniem wierzchołka, np..:
glRotatef(45.0f, 0.0f, 1.0f, 0.0f); //kąt, kierunek osi
glVertex3f(…);
Transformacje
• Współrzędne jednorodne (homogenous coordinates)
• Wprowadzone w 1946 przez E. Maxwella (rzutowanie)
• W 1965 L. Roberts użył ich do zunifikowania zapisu
wszystkich transformacji: translacji, obrotów,
skalowanie i pochylania
• Opis punktów n-wymiarowej przestrzeni za pomocą
n+1 współrzędnych
• Obcinanie we współrzędnych jednorodnych może
odbywać się w sześcianie zamiast w ściętym
ostrosłupie (znacznie efektywniejsze numerycznie)
Transformacje
• We współrzędnych kartezjańskich (2D)
obrót i translacja mogą być zapisane:
oxy   x0  t x   oxx x0  o yx y0  t x 
  



o yy   y0  t y  o yx x0  o yy y0  t y 
 x0   oxx
 x
ˆ
 y   O  y   T  o
 
 0
 yx
• We współrzędnych jednorodnych:
 x
 x0  oxx
 y   H  y   o
 
 0   yx
 1 
 1   0
oxy
o yy
0
t x   x0   oxx x0  o yx y0  t x 
t y   y0   o yx x0  o yy y0  t y 

1   1  
1
Macierze w C++
• Należy pamiętać, że macierze w C++ zapisywane są
kolumnami (M[nr kolumny+rozmiar*nr wiersza])
• Oznacza to, że macierz 0 4 8 C 
1 5 9 D 


2 6 A E 


3 7 B F 
możemy zadeklarować instrukcją
float I[16]={0,
1, 2,
I[4][4]={{0,
1, 3,
2, 3},
4,{4,
5, 5,
6, 6,
7, 7},
8,{8,
9, A,
B, B},
9, A,
C,{C,
D,D,
E, E,
F};F}};
W OpenGL
macierze 1D
Macierze w C++
• Jeżeli chcemy ułatwić sobie życie, możemy
zdefiniować funkcję wykonującą transpozycję:
0 1 2 3
0
4 5 6 7
1


 8 9 A B
2



C
D
E
F


3
C
5 9 D
6 A E

7 B F
4
8
Macierze w C++
float* Transpozycja(float* M,int rozmiar=4)
{
for(int kolumna=0;kolumna<rozmiar;++kolumna)
for(int wiersz=kolumna+1;wiersz<rozmiar;++wiersz)
{
float tmp=M[kolumna+rozmiar*wiersz];
M[kolumna+rozmiar*wiersz]=M[wiersz+rozmiar*kolumna];
M[wiersz+rozmiar*kolumna]=tmp;
}
return M;
}
Funkcja glMultMatrix
Funkcja OpenGL glMultMatrixf wykonuje mnożenie
bieżącej macierzy M (np. model-widok) przez macierz H
podaną w argumencie tj. M → M·H (postmultiplication)
Przykład użycia – mnożenie przez macierz jednostkową
1
0

0

0
0 0 0
1 0 0
0 1 0

0 0 1
W szablonie zmiany wprowadzać
w funkcji TForm1::RysujScene
przed rysowaniem figury
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float I[16]={1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1};
glMultMatrixf(Transpozycja(I));
Funkcja glMultMatrix
Efekt mnożenia przez macierz I: żadnych zmian
Skalowanie
Macierz skalowania we współrzędnych jednorodnych
sx
0

0

0
0
0
sy
0
0
sz
0
0
0
0
0

1
glScalef(0.5,1,2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float S[16]={0.5,0,0,0,
0,1,0,0,
0,0,2,0,
0,0,0,1};
glMultMatrixf(Transpozycja(S));
Skalowanie
Macierz skalowania jednorodnego we wszystkich kier.
1
0

0

0
0 
1 0 0 
0 1 0 

0 0 1/ s
0 0
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float S[16]={1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,2};
glMultMatrixf(Transpozycja(S));
Odbicie
Odbicie = „ujemne skalowanie”
 1
0

0

0
0 
1 0 0 
0 1 0 

0 0 1 / s
0 0
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float S[16]={-1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1};
glMultMatrixf(Transpozycja(S));
Obrót
Macierz obrotu we współrzędnych jednorodnych
rozkładana jest na obroty wokół osi (kąty Eulera):
cos 
 sin 

 0

 0
 sin 
0 0 Obrót o kąt  wokół osi Z
0 0
1 0

0 1
cos 
0
1
0 cos 

0 sin 

0
0
0
0
0
 sin 
cos 
0
Obrót wokół osi X
0
0
0

1
 cos 
 0

 sin 

 0
kąt 
0 0°sin 
cos 
01

130° 0
0
0.8660

045°cos  0.7071
0

060° 0
10.5
90° osi Y
Obrót wokół
0
sin 
0
0.5
0.7071
0.8660
1
Obrót
Obrót wokół osi Z o kąt 45°
0.7071  0.7071
0.7071
0.7071

 0
0

0
 0
0 0
0 0
1 0

0 1
glRotatef(45,0,0,1);
float
Rz[16]={0.7071,-0.7071,0,0,
0.7071, 0.7071,0,0,
0,0,1,0,
0,0,0,1};
glMultMatrixf(Transpozycja(Rz));
Obrót
Obrót wokół osi X o kąt :
0
1
0 cos 

0 sin 

0
0
0
 sin 
cos 
0
0
0
0

1
#include <math.h>
float
constconst
float a=20;
a=20;
float
glRotatef(a,1,0,0);
const ar=a*M_PI/180.0f;
float Rx[16]=
{1,0,0,0,
0,cos(ar),-sin(ar),0,
0,sin(ar),cos(ar),0,
0,0,0,1};
glMultMatrixf(Transpozycja(Rx));
Pochylenie
• Macierz pochylenia (ang. skew)
• Elementy pozadiagonalne
• Nie ma odpowiednika w funkcjach OpenGL
 1 1 00
0.2
 0.2 11
 0 0 0.4
0

 0 0 00
0 0
0 0
1 0

0 1
Translacja
• Macierz translacji we współrzędnych jednorodnych
1
0

0

0
0 0 1t x.5 

1 0 t0y.5

0 1 t z1 

0 0 11 
glTranslatef(1.5,0.5,1);
float
T[16]={1,0,0,1.5,
0,1,0,0.5,
0,0,1,1,
0,0,0,1};
glMultMatrixf(Transpozycja(T));
Składanie transformacji
• Złożenie translacji w kier. X i obrotu wokół osi Z
cos 
 sin 

 0

 0
 sin 
cos 
0
0
0 t0xcos
1 0
0 1
0 0t xsin
 
1 0 00 0
  
0 1 10 0
0 tx 
0 0 
1 0

0 1
• Złożenie translacji w kier. X i obrotu wokół osi Z
cos 0

1
0sin 1

0 0 0

0 0 0
0 sint x  cos
0 t x   sin 
0cos0  sin
0 0  cos 

1 00   1 0 0  0
 

0 01   0 0 1  0
0 0
0 0
1 0

0 1
Obrót wokół wyznaczonego punktu
Obrót o 45° w płaszczyźnie XY wokół punktu (2,0,0):
1) Translacja o wektor [2,0,0]
2) Obrót wokół osi Z o 45°
3) Przesunięcie o wektor [-2,0,0]
glTranslatef(2,0,0);
glRotatef(45,0,0,1);
glTranslatef(-2,0,0);
Obrót wokół wyznaczonego punktu
Obrót o 45° w płaszczyźnie XY wokół punktu (2,0,0):
1) Translacja o wektor [2,0,0]
2) Obrót wokół osi Z o 45°
3) Przesunięcie o wektor [-2,0,0]
1
0

0

0
0 0 t x  cos
cos sin
sin
1 0 0  sin
sin cos
cos

0 1 0   00
00
 
0 0 1   00
00
00 t0x (1 1cos0 )0  t x 
00 00 t x 0sin 1 0 0 

11 00 0 0 1 0 
 


00 11 0
1 0 0 1 
Rzutowania
• Rzutowanie równoległe na płaszczyznę XY (glOrtho)
1
0

0

0
0 0 0  x   x 
1 0 0  y   y 

0 0 0  z   0 
   
0 0 1  1   1 
• Rzutowanie perspektywiczne (glFrustum)
1
0

0

0
0
0
1
0
0
0
0 1d
0
0
0

0
Download