GK sprawozdanie3

WOJSKOWA AKADEMIA TECHNICZNA

Laboratorium z przedmiotu

Grafika Komputerowa

SPRAWOZDANIE

Laboratorium nr 3 – przekształcenia geometryczne

Piotr Rusinowski

I7X6S1

Prowadzący

dr inż. Marek Salamon

  1. Opis zadania

  1. Napisać program przedstawiający program zbudowany z prymitywów przestrzennych udostępnionych przez biblioteki GLU i GLUT. Użytkownik za pomocą klawiatury powinien mieć możliwość wprowadzenia zmian następujących parametrów:

    • Kąt obrotu wieży w zakresie [0;360] stopni;

    • Kąt podniesienia armaty w zakresie [0;60] stopni;

  2. W programie uwzględnić możliwość zmiany położenia obserwatora poprzez podanie następujących parametrów:

    • Odległość obserwatora od obiektu;

    • Orientacji obserwatora w zakresie [0;360] stopni względem osi OX, OY, OZ;

  1. Sposób rozwiązania

Najpierw zacząłem od deklaracji wskaźników na dwie kwadryki, których potem będę używał w programie:

GLUquadricObj *kwadryka;

GLUquadricObj *kwadrykadyskD;

Następnym krokiem było utworzenie „ciała” czołgu czyli jego środkowej części od której potem miałem punkt odniesienia do tworzenia pozostałych części czołgu. Pierwszo funkcją glPushMatrix odkładamy bieżące przekształcenie na stos, by zachować wejściowy stan macierzy widoku modelu. Następnie funkcją glScalef skalujemy nasze ciało czołgu do podanych wymiarów, a potem funkcją glutWireCube rysujemy kwadrat, który będzie przeskalowany. W ten sposób uzyskaliśmy „zawieszenie” czołgu. W następnym kroku wracamy do wejściowej macierzy widoku modelu funkcją glPopMatrix, by móc dokończyć tworzenie ciała poprzez dodanie prostopadłościanu na nasze zawieszenie. Znów odkładamy nasze przekształcenie na stos by móc je wykonać. Nasz prostopadłościan który utworzymy w identyczny sposób przesuwamy funkcją glTranslatef, żeby znalazł się na naszym zawieszeniu. Po utworzeniu ciała czołgu znów wracamy do stanu macierzy widoku modelu wejściowego, aby dokonywać kolejnych przekształceń.

glPushMatrix();

glScalef(10.0, 1.40, 2.0);

glutWireCube(1.0);

glPopMatrix();

glPushMatrix();

glTranslatef(0,1.1,0);

glScalef(10.0, 0.8, 4.0);

glutWireCube(1.0);

glPopMatrix();

Po utworzeniu ciała czołgu bierzemy się za tworzenie kół. Z racji tego, że koła są walcami musimy skorzystać z funkcji gluNewQuadric. Przypisujemy tą funkcje do zmiennych kwadryka i kwadrykadyskD. Następnie tak jak wcześniej odkładamy bieżące przekształcenie na stos. Ustawiamy nasze koło w odpowiednie miejsce funkcją glTranslatef i rysujemy funkcją gluCylinder obramowanie walca w oparciu o wymiary i zdefiniowaną wcześniej zmienną kwadryka. Następnie funkcją gluDisk rysujemy podstawy walca by stworzyć całe koło. Po wykonaniu tej operacji znów wracamy do stanu macierzy widoku modelu wejściowej. Następne koła rysujemy w identyczny sposób przesuwając je tylko w odpowiednie miejsca funkcją glTranslatef. Dlatego też pozwoliłem sobie ominąć opisywanie tworzenia następnych kół.

kwadryka = gluNewQuadric();

kwadrykadyskD = gluNewQuadric();

glPushMatrix();

glTranslatef(-3.5, -0.7, 1.0);

gluCylinder(kwadryka, 1, 1, 1, 12, 3);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glTranslatef(0, 0, 1.0);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glPopMatrix();

gluDeleteQuadric(kwadryka);

Gdy mamy już utworzone ciało i koła czołgu zabieramy się do tworzenia jego wiezyczki i lufy. Tak samo jak przy tworzeniu kół zaczynamy przypisania zmiennej kwadryka funkcji glNewQuadric, oraz odkładamy nasze bieżące przekształcenie na stos. Funkcją translatef wybieramy odpowiednie położenie dla naszej wieżyczki. Następnie funkcją glRotatef zapewniamy, że nasza wieżyczka będzie się obracała. Sam warunek na kąt obrotu jest zapisany przy definiowaniu klawiszy obsługi odpowiednio ustalając zakres możliwości zmiany zmiennej obrotWiezyczki. Wiezyczke tworzymy funkcją gluCylinder ustalając odpowiedni promień wewnętrzny i zewnętrzny, by powstał obły trapez. Po wykonaniu wiezyczki zabieramy się za lufę w podobny sposób najpierw odpowiednio ustawiając miejsce rysowania funkcją glTranslatef, a samą lufę wykonujemy funkcją gluCylinder dobierając odpowiednie promienie. Tak samo jak w przypadku wiezyczki obrót zapewniamy funkcją glRotatef uzależniając ją od zmiennej katlufy ( warunek na kąt także jest zapisany przy obsłudze klawiszy). Projektowanie kończymy jak zawsze powrotem do stanu macierzy widoku modelu wejściowej.

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, 10, 3);

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();

Obsługa klawiszy uzyskujemy wykorzystując funkcje switch - case. Definiujemy, że jeżeli naciśniemy klawisz ‘j’ to nasza wieżyczka obróci się w prawą stronę. Analogicznie robimy to dla klawisza ‘l’ na obrót w stronę lewą. Uzyskujemy ten efekt dzięki inkrementacji wartości obrótWiezyczki o wartość dObrotWiezyczki (obie zadeklarowane są wcześniej w programie) – obrót w prawą stronę, oraz analogiczną dekrementację wartości obrotWiezyczki dla obrotu w lewą stronę. Efekt obrotu bardzo dobrze ilustruje rysunek.

double obrotWiezyczki = 0.0, katLufy = 0.0, dObrotWiezyczki = 3.0,

dKatLufy = 2.0, // wartości 3.0 przy dObrotWiezyczki oraz 2.0 przy dKatLufy oznaczają zakres zmiany kąta odpowiednio o 3 i 2 stopnie

……

switch(klawisz){

……

case 'j':

obrotWiezyczki+=dObrotWiezyczki;

break;

case 'l':

obrotWiezyczki-=dObrotWiezyczki;

break;

Identycznie sprawa ma się w przypadku deklarowania przycisków na kąt wzniesienia lufy. Wartość kat lufy jest albo inkrementowana o wartość dKatlufy ( unoszenie się lufy po naciśnięciu przycisku ‘i’), lub dekrementowana ( opadanie lufy po naciśnięciu przycisku ‘k’). W przypadku tych klawiszy musimy narzucić na nie warunki by lufa nie opadała poniżej kąta 0 stopni ( warunek: katLufy >= 0.0) lub nie wznosiła się powyżej kąta 60 stopni (warunek: katLufy < 60.0). Realizację przedstawia rysunek.

case 'k':

if (katLufy >= 0.0)

katLufy-=dKatLufy;

break;

case 'i':

if (katLufy < 60.0)

katLufy+=dKatLufy;

break;

W przypadku definiowania obsługi kalwiszy mających na celu przybliżanie, oddalanie oraz zmiane położenia obserwatora względem osi OX, OY, OZ także posłuży na funkcja switch-case.

  1. Wyniki

Otrzymaliśmy w ten sposób trójwymiarowy czołg z możliwością obrotu jego wierzyczki o 360 stopni w kierunku poziomym oraz lufy o 60 stopni w kierunku pionowym. Za pomocą odpowiednich przycisków możemy także zmieniać położenie obserwatora. O to zdjęcie wyniku naszego projektu:

  1. Kod programu

#include <math.h>

#include <string.h>

#include <stdio.h>

#include <GL/glut.h>

/* Definicja stalych */

#define DLUGOSC_BOKU 5.0

#define OBSERWATOR_ODLEGLOSC 50.0

#define OBSERWATOR_OBROT_X 0.0

#define OBSERWATOR_OBROT_Y 0.0

#define OBSERWATOR_OBROT_Z 0.0

#define OBSERWATOR_FOV_Y 30.0

#define pi 3.1415

////////////////////////////////////////////////////////////////////////////////////////////

/* Zmienne globalne*/

double bok = DLUGOSC_BOKU; // Długosc boku szescianu

int szerokoscOkna = 800;

int wysokoscOkna = 600;

float lpodz = 25.0;

GLfloat Range = OBSERWATOR_ODLEGLOSC;

/* Katy obrotu figury */

GLfloat rotatex = OBSERWATOR_OBROT_X ;

GLfloat rotatey = OBSERWATOR_OBROT_Y;

GLfloat rotatez = OBSERWATOR_OBROT_Z;

GLfloat

angle1 = 1,

angle2 = 1,

angle3 = 1;

/* Wpółrzędne położenia obserwatora */

GLdouble eyex = 0;

GLdouble eyey = 0;

GLdouble eyez = 0;

/* Współrzędne punktu w którego kierunku jest zwrócony obserwator*/

GLdouble centerx = 0;

GLdouble centery = 0;

GLdouble centerz = -100;

/* Skladowe koloru */

GLfloat red = 1.0, green = 1.0, blue = 1.0;

double obrotWiezyczki = 0.0, katLufy = 0.0, dObrotWiezyczki = 3.0,

dKatLufy = 2.0, alfa=0, beta=0;

/* Prototypy funkcji */

void Rysuj();

void UstawParametryWidoku(int szer, int wys);

void WyswietlObraz(void);

void ObslugaKlawiatury(unsigned char klawisz, int x, int y);

void DrawString (GLfloat x, GLfloat y, char *string);

void ShowInstructions(bool Test);

//////////////////////////////////////////////////////////////////////////////////////////

/*Funkcja rysująca*/

void Rysuj()

{

GLUquadricObj *kwadryka;

GLUquadricObj *kwadrykadyskD;

glColor3f (0.0,0.0,0.0);

//cialo

glPushMatrix();

glScalef(10.0, 1.40, 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();

kwadrykadyskD = gluNewQuadric();

glPushMatrix();

glTranslatef(-3.5, -0.7, 1.0);

gluCylinder(kwadryka, 1, 1, 1, 12, 3);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glTranslatef(0, 0, 1.0);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glPopMatrix();

gluDeleteQuadric(kwadryka);

kwadryka = gluNewQuadric();

kwadrykadyskD = gluNewQuadric();

glPushMatrix();

glTranslatef(-3.5, -0.7, -2.0);

gluCylinder(kwadryka, 1, 1, 1, 12, 3);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glTranslatef(0, 0, 1.0);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glPopMatrix();

gluDeleteQuadric(kwadryka);

//kola tylne

kwadryka = gluNewQuadric();

kwadryka = gluNewQuadric();

kwadrykadyskD = gluNewQuadric();

glPushMatrix();

glTranslatef(3.5, -0.7, 1.0);

gluCylinder(kwadryka, 1, 1, 1, 12, 3);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glTranslatef(0, 0, 1.0);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glPopMatrix();

gluDeleteQuadric(kwadryka);

kwadryka = gluNewQuadric();

kwadrykadyskD = gluNewQuadric();

glPushMatrix();

glTranslatef(3.5, -0.7, -2.0);

gluCylinder(kwadryka, 1, 1, 1, 12, 3);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glTranslatef(0, 0, 1.0);

gluDisk(kwadrykadyskD,0.0,1,12,3);

glPopMatrix();

gluDeleteQuadric(kwadryka);

//wieza z lufą

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, 10, 3);

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();

}

//////////////////////////////////////////////////////////////////////////////////////////

/* Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu */

void UstawParametryWidoku(int szer, int wys)

{

// Zapamietanie wielkosci widoku

szerokoscOkna = szer;

wysokoscOkna = wys;

// Ustawienie parametrow viewportu

glViewport(0, 0, szerokoscOkna, wysokoscOkna);

// Przejscie w tryb modyfikacji macierzy rzutowania

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(OBSERWATOR_FOV_Y,

(float)szerokoscOkna/(float)wysokoscOkna, 1.0, 1000.0);

/* Zakomentowac od tad do wypelnien prymitywow */

// Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych

glMatrixMode(GL_MODELVIEW);

// Zmiana macierzy znajdujacej sie na wierzcholku stosu na macierz jednostkowa

glLoadIdentity();

// Wyswietlanie wielokatow w postaci obrysow.

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

}

//////////////////////////////////////////////////////////////////////////////////////////

/* Funkcja generujaca pojedyncza klatke animacji */

void WyswietlObraz(void)

{

double r;

// Wyczyszczenie bufora ramki i bufora glebokosci

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

// Okreslenie wielkosci widoku, wlaczenie rzutowania perspektywicznego

// i zainicjowanie stosu macierzy modelowania

UstawParametryWidoku(szerokoscOkna, wysokoscOkna);

//r=Range*cos(beta*pi/180);

//gluLookAt(r*sin(alfa*pi/180), Range*sin(beta*pi/180),

(r*sin(alfa*pi/180), 0, 0, 0, 0, 1, 0);

//gluLookAt(alfa, beta, alfa, 0, 0, 0, 0, 1, 0);

// Ustalenie polozenia obserwatora

glTranslatef(0, 0, -Range);

glRotatef(rotatex, 1, 0, 0);

glRotatef(rotatey, 0, 1, 0);

glRotatef(rotatez, 0, 0, 1);

// Generacja obrazu:

Rysuj();

// Przelaczenie buforow ramki

glutSwapBuffers();

}

//////////////////////////////////////////////////////////////////////////////////////////

/* Funkcja obslugi klawiatury */

void ObslugaKlawiatury(unsigned char klawisz, int x, int y)

{

switch(klawisz)

{

case 'j':

obrotWiezyczki+=dObrotWiezyczki;

break;

case 'l':

obrotWiezyczki-=dObrotWiezyczki;

break;

case 'k':

if (katLufy >= 0.0)

katLufy-=dKatLufy;

break;

case 'i':

if (katLufy < 60.0)

katLufy+=dKatLufy;

break;

case 'x':

rotatex ++ ;

break;

case 's':

rotatex -- ;

break;

case 'c':

rotatey ++ ;

break;

case 'd':

rotatey -- ;

break;

case 'z':

rotatez ++ ;

break;

case 'a':

rotatez -- ;

break;

case 'o':

Range ++ ;

break;

case 'p':

Range -- ;

break;

case 27:

exit(0);

break;

}

}

///////////////////////////////////////////////////////////////////////////////////////////

/* Funkcja wyswietlajaca napis */

void DrawString (GLfloat x, GLfloat y, char *string)

{

// położenie napisu

glRasterPos2f (x,y);

// wyświetlenie napisu

int len = strlen (string);

for (int i = 0; i < len; i++)

glutBitmapCharacter (GLUT_BITMAP_9_BY_15,string [i]);

}

//////////////////////////////////////////////////////////////////////////////////////////

/* Funkcja wyswietlajaca instrukcje */

void ShowInstructions(bool Test)

{

if(Test)

{

char napis[] = "Kursor gora\\doł - X.\n";

char napis2[] = "Kursor lewo\\prawo - Y.";

char napis3[] = "Page Up\\Page Down - Z.";

DrawString(0, 0.1, napis);

DrawString(0, 0.5, napis2);

DrawString(0, 55, napis2);

}

}

//////////////////////////////////////////////////////////////////////////////////////////

/* Glowna funkcja programu */

int main(int argc, char **argv)

{

// Zainicjowanie biblioteki GLUT

glutInit(&argc, argv);

// Ustawienie trybu wyswietlania

glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);

// Ustawienie polozenia dolenego lewego rogu okna

glutInitWindowPosition(100, 100);

// Ustawienie rozmiarow okna

glutInitWindowSize(szerokoscOkna, wysokoscOkna);

// Utworzenie okna

glutCreateWindow("LAB_2");

// Odblokowanie bufora glebokosci

glEnable(GL_DEPTH_TEST);

// Ustawienie funkcji wykonywanej na danych w buforze glebokosci

glDepthFunc(GL_LEQUAL);

// Ustawienie wartosci czyszczacej zawartosc bufora glebokosci

glClearDepth(1000.0);

// Ustawienie koloru czyszczenia bufora ramki

glClearColor (1.0f, 1.0f, 1.0f, 1.0f);

// Zarejestrowanie funkcji (callback) wyswietlajacej

glutDisplayFunc(WyswietlObraz);

// Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy

// zmieniane sa rozmiary okna

glutReshapeFunc(UstawParametryWidoku);

// Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje

// zadnych zadan

glutIdleFunc(WyswietlObraz);

// Zarejestrowanie funkcji obslugi klawiatury

glutKeyboardFunc(ObslugaKlawiatury);

// Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow

// w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci)

glutMainLoop();

return 0;

}

  1. Wnioski

Program LOGO!Soft pozwala na wygodne projektowanie układów sterowani. Praca w nim była bardzo kształcąca, ponieważ pozwala nam na zaprogramowanie sterownika od podstaw. Należy jednak uważać, ponieważ bramki AND mają 3 wejścia i trzeba dokładnie wypełnić wszystkie pola. Jednak nawet gdy się o tym zapomnimy program nie dopuści do zakończenia pracy bez uzupełnienia wymaganych pól.


Wyszukiwarka

Podobne podstrony:
Opała GK sprawozdanie lab4, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
GK sprawozdanie 2
LAB4 GK SPRAWOZDANIE
gk sprawozdanie lab1
sprawozdanie3, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
sprawozdanie oswietlenie, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
sprawozdanie(1), s3 - GK - grafika komputerowa
2 definicje i sprawozdawczośćid 19489 ppt
PROCES PLANOWANIA BADANIA SPRAWOZDAN FINANSOWYC H
W 11 Sprawozdania
Wymogi, cechy i zadania sprawozdawczośći finansowej
Analiza sprawozdan finansowych w BGZ SA
W3 Sprawozdawczosc
1 Sprawozdanie techniczne
GK 9 Przekształcenia geometryczne

więcej podobnych podstron