WOJSKOWA AKADEMIA TECHNICZNA
GRAFIKA KOMPUTEROWA
SPRAWOZDANIE
Z
ZADANIA LABORATORYJNEGO NR 2
Temat: Przekształcenia geometryczne
Grupa szkoleniowa: I1Y3S1
Sprawozdanie wykonała: Karolina Dembek
Prowadzący ćwiczenie: dr inż. Marek Salamon
Treść zadania
Napisać program przedstawiający obiekty zbudowane z prymitywów przestrzennych udostępnianych przez biblioteki GLU i GLUT:
Scenę przedstawiającą układ słoneczny złożony ze słońca i krążącej wokół niego planety i jej księżyca wiedząc, że:
promień słońca = 3;
promień planety = 1;
promień księżyca = 0.3;
promień orbity planety = 12;
promień orbity księżyca = 3;
prędkość kątowa planety = (0.1 do 0.3) stopnia/klatkę (kierunek CCW);
prędkość kątowa księżyca = 0.5 stopni/klatkę (kierunek CW);
spin planety = 1 stopień na klatkę (CW).
Orbity planety i księżyca leżą:
w płaszczyźnie równoległej do płaszczyzny YZ o środku w punkcie (-15, 15, 0):
z osią pojazdu równoległą do osi 0Z i środkiem w punkcie (0.0, y, 20.0).
Użytkownik za pomocą klawiatury powinien mieć możliwość wprowadzania zmian następujących parametrów:
Prędkości kątowej planety w zakresie [0–0.3] stopni/klatkę animacji z krokiem 0.1.
Odległości obserwatora od obiektu,
Sposób rozwiązania zadania
Aby zamodelować zadany czołg należy wykorzystać następujące funkcje rysujące kwadryki (z biblioteki GLU):
gluCylinder -do utworzenia kół, wieżyczki oraz lufy,
gluDisk -do utworzenia podstaw dla cylindrów („felgi”, „dach” i spód wieżyczki)
oraz funkcję rysującą bryły przestrzenne (z biblioteki GLUT):
glutWireCube -do utworzenia „korpusu” modelowanego obiektu.
„Podłożem” dla modelowanego obiektu jest płaszczyzna XZ, zatem wszystkie modelowane elementy znajdują się po nieujemnej stronie osi Y. Do rozmieszczania elementów na scenie należało wykorzystać funkcję glTranslatef, która dokonuje translacji o zadany w parametrach wektor. Do utworzenia korpusu należy, oprócz funkcji glutWireCube tworzącej elementy, użyć funkcji glScalef , która odpowiednio „rozciągnie” ustawienie układu by sześcian o boku 1 był przeskalowany do żądanych rozmiarów. Należy pamiętać aby przed tworzeniem każdego elementu (łącznie z przekształceniami geometrycznymi potrzebnymi do jego utworzenia i umiejscowienia) użyć funkcji glPushMatrix() , która „zapisze” bieżący stan układu a po utworzeniu użyć funkcji glPopMatrix() , która „odtworzy” poprzednie ustawienie układu. W celu umożliwienia animacji wieżyczki oraz lufy, funkcja rysująca przyjmuje dwa parametry, pierwszy z nich to kąt obrotu wieży, drugi to kąt podniesienia lufy. Inkrementując zmienną globalną, podaną jako pierwszy parametr, po wyświetleniu każdej klatki uzyska się efekt animacji. Zmieniając wartość o którą jest inkrementowana ta zmienna można zmieniać prędkość oraz kierunek animacji. Wykorzystując funkcję obsługi klawiatury można sterować prędkością obrotu wieżyczki oraz kierunkiem obrotu. Natomiast zmieniając wartość zmiennej globalnej podanej jako drugi parametr funkcji rysującej można ustalać kąt podniesienia lufy. Ten efekt również uzyskujemy używając funkcji obsługi klawiatury. Zmiana tych kątów sprowadza się tak naprawdę do użycia sparametryzowanej funkcji glRotatef przed narysowaniem obiektu, który ma być obrócony.
Aby możliwa była owa funkcjonalność należało utworzyć zmienną globalną o nazwie OBSERWATOR_ODLEGLOSC i ustawić jej wartość początkową (np. -20), następnie znaleźć fragment kodu:
glTranslatef(0, 0, -40);
glRotatef(rotObsX, 1, 0, 0);
glRotatef(rotObsY,0,1,0);
po czym w wywołaniu funkcji glTranslatef zmienić wartość -40 na wcześniej zadeklarowaną zmienną OBSERWATOR_ODLEGLOSC . Dzięki temu zabiegowi zmieniając wartość zmiennej oddalamy lub przybliżamy odległość obserwatora od środka sceny. Należy zauważyć, że zmienna powinna przyjmować wartości ujemne, gdyż wartość 0 oznacza położenie obserwatora w środku układu, a wartości dodatnie oddalają obserwatora lecz w taki sposób iż jest on „plecami” do sceny, czyli do naszego modelu. Ostatnim krokiem jest dodanie obsługi zmiany odległości za pomocą klawiatury aby można było manipulować odległością obserwatora
w trakcie działania programu.
Do stworzenia układu planet z polecenia indywidualnego korzystałam z funkcji glutSolidSphere (GLdouble radius, GLint slices, GLint stacks), która służy do tworzenia szkieletu kuli, przy czym parametry: radius to promień kuli, slices to liczba południków, zaś stacks to liczba równoleżników kuli. Resztę zastosowań funkcji, z których korzystałam opisałam przy opisie czołgu.
Uzyskane wyniki
Układ planet wraz z czołgiem:
Układ przy standardowym widoku:
Układ obiektów z przybliżeniem:
Oraz układ oddalony:
Kod źródłowy związany z zadaniem
Odległość obserwatora odbiektu:
switch(klawisz)
{
case '+':
OBSERWATOR_ODLEGLOSC+=1;
break;
case '-':
OBSERWATOR_ODLEGLOSC-=1;
break;
Kod opisujący czołg:
void Rysuj()
{
GLUquadricObj *kwadryka;
glColor3f (0.1,0.7,0.2);
glPushMatrix();
glTranslatef(0,1.9,20);
glRotatef(-90,0,1,0);
//korpus
glPushMatrix();
glScalef(10.0, 1.4, 2.0);
glutWireCube(1.0);
glPopMatrix();
glPushMatrix();
glTranslatef(0,1.1,0);
glScalef(10.0, 0.8, 4.0);
glutWireCube(1.0);
glPopMatrix();
//kola przednie
kwadryka = gluNewQuadric();
glPushMatrix();
glTranslatef(-3.5, -0.7, 1.0);
gluCylinder(kwadryka, 1, 1, 1, 30, 6);
gluDisk(kwadryka,0,1,10,10);
glTranslatef(0,0,1);
gluDisk(kwadryka,0,1,10,10);
glPopMatrix();
gluDeleteQuadric(kwadryka);
kwadryka = gluNewQuadric();
glPushMatrix();
glTranslatef(-3.5, -0.7, -2.0);
gluCylinder(kwadryka, 1, 1, 1, 30, 6);
gluDisk(kwadryka,0,1,10,10);
glTranslatef(0,0,1);
gluDisk(kwadryka,0,1,10,10);
glPopMatrix();
gluDeleteQuadric(kwadryka);
//kola tylne
kwadryka = gluNewQuadric();
glPushMatrix();
glTranslatef(3.5, -0.7, 1.0);
gluCylinder(kwadryka, 1, 1, 1, 30, 6);
gluDisk(kwadryka,0,1,10,10);
glTranslatef(0,0,1);
gluDisk(kwadryka,0,1,10,10);
glPopMatrix();
gluDeleteQuadric(kwadryka);
kwadryka = gluNewQuadric();
glPushMatrix();
glTranslatef(3.5, -0.7, -2.0);
gluCylinder(kwadryka, 1, 1, 1, 30, 6);
gluDisk(kwadryka,0,1,10,10);
glTranslatef(0,0,1);
gluDisk(kwadryka,0,1,10,10);
glPopMatrix();
gluDeleteQuadric(kwadryka);
//wiezyczka i lufa
kwadryka = gluNewQuadric();
glPushMatrix();
glTranslatef(1.5, 1.5,0);
glRotatef(obrotWiezyczki, 0, 1, 0);
glRotatef(-90, 1, 0, 0);
gluCylinder(kwadryka, 2.0, 1.0 , 1.1, 20, 5);
gluDeleteQuadric(kwadryka);
kwadryka = gluNewQuadric();
glPushMatrix();
glTranslatef(0, 0, 0.55);
glRotatef(katLufy, 0, 1, 0);
glRotatef(-90, 0, 1, 0);
gluCylinder(kwadryka, 0.15, 0.15, 4.5, 8, 8);
glPopMatrix();
gluDeleteQuadric(kwadryka);
glPopMatrix();
glPopMatrix();
// Poczatek tworzenia ukladu wspolrzednych
glBegin(GL_LINES);
// Os X
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-30.0, 0.0, 0.0);
glVertex3f(30.0, 0.0, 0.0);
// Os Y
glColor3f(0.0,1.0,0.0);
glVertex3f(0.0, -30.0, 0.0);
glVertex3f(0.0, 30.0, 0.0);
// Os Z
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0, 0.0, -30.0);
glVertex3f(0.0, 0.0, 30.0);
// Koniec tworzenia ukladu wspolrzednych
glEnd();
glClearColor(0,0,0,0);
}
Układ planet:
void planety()
{
glPushMatrix();
glColor3f(1,1,0);
glTranslatef(-15,15,0);
glRotatef(90,0,1,0);
glutSolidSphere(3,15,15);
glRotatef(pkp,0,0,1);
glTranslatef(12,0,0);
glPushMatrix();
glRotatef(-sp,0,0,1);
glColor3f(0,1,0);
glutSolidSphere(1,15,15);
glPopMatrix();
glRotatef(-pkk,0,0,1);
glTranslatef(-3,0,0);
glPushMatrix();
glColor3f(0.5,0.5,0.5);
glutSolidSphere(0.3,15,15);
glPopMatrix();
glPopMatrix();
pkp+=(0.1+aaa);
sp--;
pkk+=(0.5+aaa);
glClearColor(0,0,0,0);
}
Wnioski z przeprowadzonego ćwiczenia
Ćwiczenie wykonane na laboratoriach ilustrowało jak wykorzystując gotowe prymitywy przestrzenne dostępne w bibliotekach GLU i GLUT zamodelować bardziej złożone obiekty 3D. Użycie gotowych prymitywów pozwoliło zaoszczędzić dużo kodu programu a co za tym idzie dużo czasu programisty. Świadczy to
o przydatności a nawet niezbędności korzystania z takich bibliotek jak wyżej wymienione przy tworzeniu trójwymiarowych modeli. Do ważnych funkcji należą również funkcje pozwalające na wykonywanie przekształceń w przestrzeni 3D takich jak obrót o kąt wokół osi, skalowanie w trzech wymiarach, czy translacja o wektor czyli mówiąc prościej przesunięcie w przestrzenie trójwymiarowej. Te podstawowe funkcje są niezbędne do modelowania złożonych obiektów. Funkcjami godnymi uwagi są również funkcje działające na stosie macierzy przekształceń. Za pomocą tych funkcji można w prosty sposób „zapisywać” i „odczytywać” ustawienia układu współrzędnych. Łącząc działania funkcji przekształceń i funkcji działających na stosie macierzy przekształceń można w stosunkowo łatwy sposób tworzyć animacje wybranych elementów zamodelowanych obiektów co daje jeszcze większe możliwości modelowania i zastosowania dla takich modeli.