SPR-ANKI, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2


WOJSKOWA AKADEMIA TECHNICZNA

LABORATORIUM GRAFIKI KOMPUTEROWEJ

SPRAWOZDANIE

Temat: Modelowanie obiektów 3D

Data realizacji ćwiczenia: 06.04.2005

Prowadzący: dr inż. Marek Salamon

Wykonawca: Anna Pokrzywa

grupa C02A

I Zadanie laboratoryjne:

Wykorzystując wybrane funkcje modelowania geometrycznego biblioteki OpenGL/Glut napisać program przedstawiający perspektywiczny obraz bryły 3D o poniższych parametrach:

- stożek w trybie GL_TRIANGLE_STRIP o promieniu dolnej podstawy 2 i jej środku w punkcie (0,0,0), oraz promieniu górnej podstawy 1 i wysokości 1.

- podstawy figury zamodelować w trybie GL_TRIANGLE_FUN

-przewidzieć możliwość zmiany liczby podziałów pionowych i poziomych

II Sposób rozwiązania zadania :

Do realizacji swojego ćwiczenia laboratoryjnego wykorzystałam, udostępnione w trakcie zajęć, programy rysujące walec i sześcian w trój-wymiarze.

Zaimplementowany przeze mnie algorytm wykorzystywał następujące zmienne :

Poszczególne wartości zmiennych wyznaczyłam z następujących zależności:

Pętla odpowiedzialna za narysowanie dolnej podstawy stożka:

(1) glBegin(GL_TRIANGLE_FAN) ;

(2) glVertex3f(0.0 , 0.0 , 0.0) ;

(3) for(i=0 ; i*dAlfa <= 360.0L ; i++)

{

(4) glVertex3f(r*cos(DEG2RAD(i*dAlfa)) , 0.0 , r*sin(DEG2RAD(i*dAlfa)));

}

(5) glEnd();

W pierwszej linii kodu zostaje zadeklarowana metoda, którą wykorzystałam do narysowania dolnej podstawy stożka (1). Deklaracja taka posiada poniższy schemat:

glBegin(nazwa_prymitywa) ; - rozpoczęcie bloku tworzenia prymitywa

Przyjętym przeze mnie prymitywem była metoda GL_TRIANGLE_FAN. Polega ona na łączeniu trzech punktów:

-pierwszego zadeklarowanego

- ostatniego zadeklarowanego

- aktualnie deklarowanego

w trójkąt. W następnej linii kodu (2), w punkcie o współrzędnych (0,0,0), deklaruje położenie środka dolnej podstawy stożka. W tym celu wykorzystuję funkcję `glVertex3f', tworzącą wierzchołek trójwymiarowy, o współrzędnych typu Glfloat (x,y,z). Kolejno wykonywana jest pętla (3), w której definiowane są punkty, leżące na okręgu podstawy. Współrzędne tych punktów zmieniają się zależnie od wartości zmiennej `i', określającej aktualnie rysowany wycinek pionowy. Ponad to do wyznaczenia powyższych współrzędnych wykorzystuję zależności wynikające z funkcji trygonometrycznych kątów. Przy czym należy pamiętać o zamianie wartości kątów ze stopni na radiany, a także o fakcie iż tylko dwie współrzędne ulegają zmianie. Wysokość pozostaje stała i wynosi zero. Punkty definiowane w pętli (4) są łączone ze środkiem podstawy - punktem (0,0,0). Otrzymany obraz wygląda następująco:

0x08 graphic

Rys.1

Poleceniem glEnd( ); (5) kończony jest blok tworzenia prymitywa.

Pętla odpowiedzialna za narysowanie górnej podstawy stożka:

glBegin(GL_TRIANGLE_FAN) ;

glVertex3f(0.0 , h , 0.0) ;

for(i=0 ; i*dAlfa <= 360.0L ; i++)

{

glVertex3f(r2*cos(DEG2RAD(i*dAlfa)) , h , r2*sin(DEG2RAD(i*dAlfa)));

}

glEnd();

Algorytm ten jest analogiczny do algorytmu rysującego dolną podstawę opisanego powyżej . Jedyne różnice dotyczą położenia i wielkości podstawy. Jest ona rysowana na wysokości `h' i ma promień równy `r2'.

Wyznaczenie ścian bocznych stożka:

(1) for(i=0 ; floor((i+1)*dH*1.0E10) <= floor(h*1.0E10) ; i++)

{

  1. glBegin(GL_TRIANGLE_STRIP) ;

  2. for(j=0 ; j*dAlfa <= 360.0L ; j++)

{

(4) glVertex3f(r*cos(DEG2RAD)j*dAlfa)) , i*dH , r*sin(DEG2RAD(j*dAlfa)));

(5) glVertex3f((r-dR) * cos(DEG2RAD(j*dAlfa)) , (i+1)*dH , (r-dR) *

sin(DEG2RAD(j*dAlfa)));

}

(6) glEnd() ;

(7) r=r-dR ;

}

Algorytm rozpoczyna się od pętli (1) określającej, który wycinek poziomy jest aktualnie rysowany. Na każdy taki wycinek składa się `nh' podziałów pionowych. W dalszej części algorytmu określona została metoda wykorzystana do narysowania powierzchni bocznej stożka (2) - GL_TRIANGLE_STRIP. Polega ona na łączeniu ze sobą trzech ostatnio narysowanych punktów. Nowy punkt jest łączony z dwoma poprzednimi trwożąc trójkąt.

Następna, zagnieżdżona pętla (3) odpowiada za rysowanie wycinków pionowych. Wykorzystuje ona funkcję `glVertex3f' (4) i (5), tworzącą wierzchołek trójwymiarowy, o współrzędnych typu Glfloat (x,y,z). Pierwszy punkt w tej pętli zostaje zdefiniowany na wysokości h=0 i leży na obwodzie podstawy dolnej stożka. Drugi punkt jest rysowany na wysokości `dH'. Ponadto do jego wyznaczenia używam promienia `r' pomniejszonego o `dR'. Punkty są ze sobą łączone. Warunek pętli zostaje zwiększony o kąt `dAlfa' (3) i rozpoczyna się tworzenie kolejnego wycinka pionowego. Gdy warunek pętli zagnieżdżonej zostaje niespełniony - sumy kątów `dAlfa' dały wartość większą lub równą 360 stopni - oznacza to że skończone zostało rysowanie wycinka poziomego wraz ze wszystkimi składającymi się na niego wycinkami pionowymi. Obrazuje to poniższy rysunek:

0x08 graphic

Rys. 2

Tworzenie nowego wycinka poziomego zaczyna się przez dodanie wartości `dH' (1) do wysokości ostatnio tworzonego fragmentu (pętla zewnętrzna). Ponadto wartość promienia `r' pomniejszona zostaje o `dR' (7). Rozpoczyna się modelowanie kolejnego poziomego fragmentu. Pętle zewnętrzne (1) są wywoływane do momentu aż kolejne sumy `dH' będą równe wysokości `h'. Jednocześnie, ciągle pomniejszany, promień r osiągnie wartość wynoszącą `r2'. Końcowym efektem opisywanego algorytmu jest następujący obraz:

0x08 graphic

Rys. 3

Polecenie glEnd( ); (6) kończy blok tworzenia prymitywa.

Pełen algorytm rysujący stożek o promieniu dolnej podstawy 2 i jej środku w punkcie (0,0,0), oraz promieniu górnej podstawy 1 i wysokości 1 w trybie GL_TRIANGLE_STRIP:

void RysujStozek(double h, double r, int nv, int nh)

{

int i, j;

double dH, dAlfa,r2,dR;

r2 = 1.0;

dR=(r-r2)/nv;

dAlfa = 360.0L/(double)nh; - wyznaczenie kata określającego pojedynczy wycinek

pionowy

dH = h/(double)nv; - wyznaczenie wysokości pojedynczego wycinka poziomego

glBegin(GL_TRIANGLE_FAN); - początek podstawy dolnej

glVertex3f(0.0, 0.0, 0.0);

for (i = 0; i * dAlfa <= 360.0L; i++)

{

glVertex3f(r*cos(DEG2RAD(i*dAlfa)),0.0,r*sin(DEG2RAD(i*dAlfa)));

}

glEnd(); - koniec podstawy dolnej

glBegin(GL_TRIANGLE_FAN); - początek podstawy górnej

glVertex3f(0.0, h,0.0);

for (i = 0; i * dAlfa <= 360.0L; i++)

{

glVertex3f(r2*cos(DEG2RAD(i*dAlfa)),h,r2*sin(DEG2RAD(i*dAlfa)));

}

glEnd(); - koniec podstawy górnej

for (i = 0; floor((i+1)*dH*1.0E10) <= floor(h*1.0E10); i++) - początek wyznaczania

{ ścian bocznych

glBegin(GL_TRIANGLE_STRIP);

for(j = 0; j * dAlfa <= 360.0L; j++)

{ glVertex3f(r*cos(DEG2RAD(j*dAlfa)),i*dH,r*sin(DEG2RAD(j*dAlfa)));

glVertex3f((r-dR)*cos(DEG2RAD(j*dAlfa)),(i+1)*dH,((r-dR)*sin(DEG2RAD

(j*dAlfa))));

}

glEnd();

r=r-dR;

} - koniec wyznaczania ścian bocznych

}

Wynik powyższego algorytmu:

0x08 graphic

Rys. 4

III Wyniki

Celem ćwiczenia laboratoryjnego było zamodelowanie w przestrzeni trójwymiarowej stożka.

Do wyznaczenia ścian bocznych należało wykorzystać metodę GL_TRIANGLE_STRIP, natomiast do narysowania podstaw metodę GL_TRIANGLE_FAN. Ponadto należało przewidzieć możliwość zmiany liczby podziałów poziomych i pionowych.

Korzystając z liczby podziałów pionowych, uwzględniając zadaną metodę modelowania, wyznaczyłam fragmenty składające się na jeden wycinek poziomy ścian bocznych stożka (rys. 2). Podziały poziome posłużyły mi do rysowania kolejnych odcinków wysokości tworzących ściany boczne. Kolejno rysowane punkty ścian bocznych wyznaczałam w następującej kolejności:

glVertex3f(r*cos (DEG2RAD(j*dAlfa)), i*dH, r*sin (DEG2RAD(j*dAlfa)))

gdzie:

r - promień walca

i,j - zmienne pętli

dH - wysokość podziału poziomego

dAlfa - kąt podziału pionowego

Efektem tych działań jest rys. 3.

Podstawę górną i dolną wyznaczyłam w oparciu o podział pionowy, również z wykorzystaniem metody ” glVertex3f(); ” (rys. 1).

Efekt końcowy działania programu przedstawia rys. 5. Jest on wynikiem połączenia zamodelowanych podstaw i ścian bocznych stożka. Figura powstała z połączenia kolejno deklarowanych trójkątów.

Modyfikacja bryły jest możliwa poprzez zmianę wartości parametrów wysokości i promieni, oraz zwiększenie lub zmniejszenie liczby podziałów pionowych i poziomych w celu modyfikacji dokładności utworzonego obrazu. Wszelkich zmian parametrów stożka można dokonać jedynie w kodzie programu.

IV Pełen wydruk programu

Na wydruku czerwonym kolorem zaznaczyłam miejsce modyfikacji parametrów stożka. Kolorem bordowym zaznaczony jest napisany przeze mnie algorytm oraz definicje i deklaracje niezbędne do wywołania tego algorytmu.

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

// Program przedstawiajacy stożek w rzucie perspektywicznym

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

// Definicja bibliotek

#include <math.h>

#include <string.h>

#include <stdio.h>

#include <GL/glut.h>

// Definicja stalych

#define OBSERWATOR_ODLEGLOSC 20.0

#define OBSERWATOR_OBROT_X 20.0

#define OBSERWATOR_OBROT_Y 20.0

#define OBSERWATOR_FOV_Y 30.0

#define M_PI 3.1415

#define DEG2RAD(x) ((float)(x)*M_PI/180.0)

// Zmienne globalne

int szerokoscOkna = 800;

int wysokoscOkna = 600;

int podzialpionowy = 20;

int podzialpoziomy = 20;

double wysokosc = 1.0;

double promien = 1.0;

// Prototypy funkcji

void RysujStozek(double h,double r,int nv, int nh);

void UstawParametryWidoku(int szer, int wys);

void WyswietlObraz(void);

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

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

// Funkcja rysujaca stożek o promieniu dolnej podstawy

//2 i jej środku w punkcie (0,0,0) oraz promieniu gornej podstawy 1

// i wysokosci 1 w trybie GL_TRIANGLE_STRIP

void RysujStozek(double h, double r, int nv, int nh)

{

int i, j;

double dH, dAlfa,r2,dR,dR2;

r2 = 1.0;

dR=(r-r2)/nv;

// Wyznaczenie kata wyznaczajacego pojedynczy wycinek pionowy

dAlfa = 360.0L/(double)nh;

// Wyznaczenie wysokosci pojedynczego wycinka poziomego

dH = h/(double)nv;

// Podstawa dolna

glBegin(GL_TRIANGLE_FAN);

glVertex3f(0.0, 0.0, 0.0);

for (i = 0; i * dAlfa <= 360.0L; i++)

glVertex3f(r*cos(DEG2RAD(i*dAlfa)),0.0,r*sin(DEG2RAD(i*dAlfa)));

glEnd();

/* //podstawa gorna

glBegin(GL_TRIANGLE_FAN);

glVertex3f(0.0, h,0.0);

for (i = 0; i * dAlfa <= 360.0L; i++)

glVertex3f(r2*cos(DEG2RAD(i*dAlfa)),h,r2*sin(DEG2RAD(i*dAlfa)));

glEnd();

*/

// Wyznaczanie scian pocznych

for (i = 0; floor((i+1)*dH*1.0E10) <= floor(h*1.0E10); i++)

{

glBegin(GL_TRIANGLE_STRIP);

for(j = 0; j * dAlfa <= 360.0L; j++)

{

glVertex3f(r*cos(DEG2RAD(j*dAlfa)),i*dH,r*sin(DEG2RAD(j*dAlfa)));

glVertex3f((r-dR)*cos(DEG2RAD(j*dAlfa)),(i+1)*dH,((r-dR)*sin(DEG2RAD(j*dAlfa))));

}

glEnd();

r=r-dR;

}

}

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

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

// 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)

{

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

// Ustalenie polozenia obserwatora

glTranslatef(0, 0, -OBSERWATOR_ODLEGLOSC);

glRotatef(OBSERWATOR_OBROT_X, 1, 0, 0);

glRotatef(OBSERWATOR_OBROT_Y, 0, 1, 0);

// Generacja obrazu stozka

RysujStozek(wysokosc,promien,podzialpoziomy,podzialpionowy);

// Przelaczenie buforow ramki

glutSwapBuffers();

}

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

// 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("Stozek");

// 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 (0.0f, 0.0f, 0.3f, 0.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);

// Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow

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

glutMainLoop();

return 0;

}

7



Wyszukiwarka

Podobne podstrony:
KWADRYKI, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
sprawko-pieci, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
Zadania L2 I6Y3S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
sprawozdanie3, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
sprawozdanie oswietlenie, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
OpenGl, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L3 I6X4S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L3 I6Y3S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
tresc lab3 gk, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
Zadania L4 I6Y4S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L3 I6Y4S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
Opała GK sprawozdanie lab4, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L4 I6Y3S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
sprko-pieci, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
Zadanie IY4S1, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB2
Rzezba Lab4, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB4
GK LAB3, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB4
Zadania I1Y3S1, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB4

więcej podobnych podstron