WOJSKOWA AKADEMIA TECHNICZNA
SPRAWOZDANIE Z PRZEDMIOTU
Grafika Komputerowa
Laboratorium nr 3 „Przekształcenia geometryczne”
Prowadzący zajęcia:
dr inż. Marek Salamon
Słuchacz:
Paulina Kot
Grupa: I7X1N1
Treść zadania:
Napisać program przedstawiający obiekt zbudowany z prymitywów przestrzennych udostępnianych przez biblioteki GLU i GLUT. Użytkownik za pomocą klawiatury powinien mieć możliwość wprowadzenia zmian następujących parametrów:
Kąta obrotu lampy
Kąta podniesienia ramienia
W programie uwzględnić możliwość interakcyjnej zmiany położenia obserwatora poprzez podanie następujących parametrów:
Odległości obserwatora od obiektu,
Orientacji obserwatora względem osi 0X, 0Y, 0Z.
UWAGA: Obserwator jest zawsze zwrócony przodem w kierunku obiektu.
Sposób rozwiązania zadania:
Projektowanie lampy rozpoczęłam od zainicjalizowania elementów składowych lampki zamodelowanych jako kwadrygi. Kolejno przedstawię te elementy:
Zainicjowanie ścian bocznych walca będącego podstawą lampki
podstawaS = gluNewQuadric();
gluQuadricDrawStyle(podstawaS, GLU_LINE);
Zainicjowanie górnej podstawy walca
podstawaDyskG = gluNewQuadric();
gluQuadricDrawStyle(podstawaDyskG, GLU_LINE);
Zainicjowanie dolnej podstawy walca
podstawaDyskD = gluNewQuadric();
gluQuadricDrawStyle(podstawaDyskD, GLU_LINE);
Zainicjowanie scian bocznych walca górnej części klosza
czescKlosza = gluNewQuadric();
gluQuadricDrawStyle(czescKlosza, GLU_LINE);
Zainicjowanie górnej podstawy walca
czescDyskG = gluNewQuadric();
gluQuadricDrawStyle(czescDyskG, GLU_LINE);
Zainicjowanie dolnej podstawy walca
czescDyskD = gluNewQuadric();
gluQuadricDrawStyle(czescDyskD, GLU_LINE);
Zainicjowanie ścian bocznych stożka będącego kloszem
klosz = gluNewQuadric();
gluQuadricDrawStyle(klosz, GLU_LINE);
Zainicjowanie górnej podstawy walca
kloszDyskG = gluNewQuadric();
gluQuadricDrawStyle(kloszDyskG, GLU_LINE);
Zainicjowanie ścian bocznych stożka będącego kloszem
wlacznik = gluNewQuadric();
gluQuadricDrawStyle(wlacznik, GLU_LINE);
Następnie przeszłam do tworzenia podstawy lampy używając funkcji gluCylinder(); oraz ustawiając jej odpowiednie parametry. Aby „zamknąć” powierzchnię podstawy wykorzystałam funkcję gluDisk();
Kod tworzenie podstawa lampki
glPushMatrix(); skopiowanie macierzy na wierzchołek stosu
glColor3f(1,0,0); ustawienie koloru (czerwony)
glRotatef(-90.0,1,0,0); rotacja o kat -90' ->zgodne z ruchem wskazówek zegara, wokół osi równoległej do wektora(x,y,z)->x
gluCylinder(podstawaS,2.5,2.5,0.5,20,4); Cylinder bez podstaw, wskaźnik do kwadryki, Rdolna2.5=Rgórnej, h=0.5, podziały
gluDisk(podstawaDyskD,0.0,2.5,20,4); dolna podstawa ->koło z wnętrzem otwartym, wskaźnik do kwadryki, R mniejszy, Rwiększy, podział i koncentracja
glTranslatef(0.0,0.0,0.5); translacja o wektor (x,y,z),z=0.5
gluDisk(podstawaDyskG,0.0,2.5,20,4); górna podstawa -> koło z wnętrzem otwartym, wskaźnik do kwadryki, R mniejszy, Rwiększy, podział i koncentracja
glPopMatrix(); zdjęcie macierzy z wierzchołka stosu
Kolejnym krokiem było utworzenie nóżki lampy. W tym wypadku należało najpierw odpowiednio zeskalować poprzez glScalef(0.5, 5.0, 0.5), oraz przesunąć a następnie wywołać ten sześcian funkcją gluSolidWire (1);
Kod tworzenie ramienia wspierającego (dolne)
glPushMatrix(); skopiowanie macierzy na wierzchołek stosu
glColor3f(1,0,0); ustawienie koloru (czerwony)
glTranslatef(0.0,3.0,0.0); translacja o wektor (x,y,z),y=3
glScalef(0.5,5.0,0.5); skalowanie wzdłuż osi (wymiary z zadania)
glutWireCube(1); wywołanie sześcianu
glPopMatrix(); zdjęcie macierzy z wierzchołka stosu
Kod rotacji ramienia, umieszczenie na miejsce (na górze)
glTranslatef(-0.5,5,0.0); translacja o wektor (x,y,z),x=-0.5,y=5
glRotatef(obrotRamienia1, 1, 0, 0); rotacja o kat
glRotatef(obrotLampki,0,1,0); rotacja o kat
Podobne przekształcenia przeprowadzam dla ramienia lampki
Kod tworzenie ramienia (górne)
glPushMatrix(); skopiowanie macierzy na wierzchołek stosu
glTranslatef(0.0,0.0,-2.0); translacja o wektor (x,y,z),z=-2.0
glScalef(0.25,0.25,5.0); skalowanie wzdłuż osi (wymiary z zadania)
glutWireCube(1); wywołanie sześcianu
glPopMatrix(); zdjęcie macierzy z wierzchołka stosu
Ostatnimi do zaprojektowania były już sama lampka z kloszem. Po przesunięciu na odpowiednie miejsca zostały wywołane dwa cylindry.
Kod górnej części klosza
glColor3f(1,0,0); ustawienie koloru (czerwony)
glPushMatrix(); skopiowanie macierzy na wierzchołek stosu
glRotatef(-90.0,1,0,0); rotacja o kat
glTranslatef(0.0,4.5,-0.5); translacja o wektor (x,y,z),y=4.5,z=-0.5
Cylinder bez podstaw, wskaźnik do kwadryki, Rdolna2.5=Rgórnej, h=1, podziały
gluCylinder(czescKlosza,0.25,0.25,1.0,20,4);
gluDisk(czescDyskD,0.0,0.25,20,4); dolna podstawa ->koło z wnętrzem otwartym, wskaźnik do kwadryki, R mniejszy, R większy, podział i koncentracja
glTranslatef(0.0,0.0,1.0); translacja o wektor (x,y,z),z=1.0
gluDisk(czescDyskG,0.0,0.25,20,4); górna podstawa ->koło z wnętrzem otwartym, wskaźnik do kwadryki, R mniejszy, R większy, podział i koncentracja
glPopMatrix(); zdjęcie macierzy z wierzchołka stosu
Kod klosza (główny)
glPushMatrix(); skopiowanie macierzy na wierzchołek stosu
glRotatef(-90.0,1,0,0); rotacja o kat
glTranslatef(0.0,4.5,-1.5); translacja o wektor (x,y,z),y=4.5,z=-1.5
Cylinder bez podstaw, wskaźnik do kwadryki, Rdolna2.5=Rgórnej, h=1, podziały
gluCylinder(klosz,1.0,0.5,1.0,20,4);
glTranslatef(0.0,0.0,1.0); translacja o wektor (x,y,z),y=1
gluDisk(kloszDyskG,0.0,0.5,20,4); górna podstawa ->koło z wnętrzem otwartym, wskaźnik do kwadryki, R mniejszy, R większy, podział i koncentracja
glPopMatrix(); zdjęcie macierzy z wierzchołka stosu
Poniżej przedstawiam printscrena z wynikami:
Poniżej przedstawiam obsługę klawiatury:
Poruszanie ramienia
Kod źródłowy
void ObslugaKlawiatury(unsigned char klawisz, int x, int y)
{
switch(klawisz)
{
case '2':
rotRamienia1 = (rotRamienia1 < 45.0) ? rotRamienia1 + 1.0 : rotRamienia1;
break;
case '@':
rotRamienia1 = (rotRamienia1 > -15.0) ? rotRamienia1 - 1.0 : rotRamienia1;
break;
}
if(klawisz == 27)
exit(0);
}
Obserwator odległości:
Kod źródłowy (fragmęt)
case '+':
odleglosc = (odleglosc<100.0) ? odleglosc+1.0 : odleglosc;
break;
case '-':
odleglosc = (odleglosc/wysokosc>1.0) ? odleglosc-1.0 : odleglosc;
break;
Przedstawiam poniżej printscreen'y z wynikami
Obniżenie ramienia:
Podwyższenie ramienia:
Obserwator odległości „z dala”:
Obserwator odległości „z bliska”:
W następnym etapie należało uwzględnić w programie możliwość położenia obserwatora orientacji względem osi 0X, 0Y, 0Z. poniżej przedstawiam kod źródłowy (fragmęt) odpowiadający za zmianę obserwatora orientacji:
Kod źródłowy
void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y)
{
switch(klawisz)
{
case GLUT_KEY_UP:
wysokosc = (wysokosc < odleglosc) ? wysokosc + 0.5 :wysokosc;
break;
case GLUT_KEY_DOWN:
wysokosc = (wysokosc > -180.0) ? wysokosc - 0.5 :wysokosc;
break;
case GLUT_KEY_LEFT:
rotObsY = (rotObsY > -180.0) ? rotObsY - 1.0 : rotObsY;
break;
case GLUT_KEY_RIGHT:
rotObsY = (rotObsY < 180.0) ? rotObsY + 1.0 : rotObsY;
break;
}
}
Wyniki przedstawiają printscreen'y:
Obserwator „z góry”
Obserwator „z dołu”
Obserwator „z lewego boku”
Obserwator „z prawego boku”