background image

~ 1 ~ 

 

POLITECHNIKA WROCŁAWSKA 

Sprawozdanie 

Generowanie modelu góry z wykorzystaniem 

funkcji Weierstrassa 

 

Gwidon  Jóźwiak, 171864

 

2010-11-17 

 

 

 

 

 

 

background image

~ 2 ~ 

 

Moim zadaniem było zaproponowanie i zaimplementowanie algorytmu generującego model 

góry za pomocą funkcji Weierstrassa. Postanowiłem dokonać tego obracając wygenerowany wykres 

wokół osi OX. Oczywiście obracanie wykresu w zbyt małych odstępach byłoby dość trudne i 

czasochłonne do wykonania, a po za tym powodowałoby duże opuźnienie. Dlatego wygenerowałem 

tylko 7 wykresów co 

30 . Po wygenerowaniu wykresów (chmóry punktów) rysowałem siatkę łącząc 

kolejne punkty w odpowiedniej kolejności. 

Funkcja draws przyjmuje parametr a, będący parametrem funkcji Weierstrassa.  Poniżej 

zamieszczam kod programu. 

/********************************************************************

*****************/ 

 
 
// Program rysujący siatkę (model) góry przy pomocy funkcji 

Weierstrassa wykorzystujący funkcje biblioteki OpenGL 

 

  
 

/********************************************************************

*****************/ 

 

#include

 

<windows.h> 

#include

 

<cstdlib> 

#include

 

<ctime> 

#include

 

<cmath> 

#include

 

<gl/gl.h> 

#include

 

<gl/glut.h> 

 

typedef

 

float

 point3[3]; 

typedef

 

float

 point2[2]; 

point2 tab2D[100]; 
point3 tab[7][100]; 

static

 GLfloat theta[] = {0.0, 0.0, 0.0}; 

// trzy kąty obrotu 

 
/********************************************************************

*****************/ 

 
//funkcja zwracająca wartość (y) funkcji weierstrassa w punkcie x 

float

 weierstrass(

float

 a, 

float

 x) 


 

float

 wynik = 0; 

 

for

int

 k = 1 ; k<=20 ; k++ ) 

 

 

 

wynik += sin(3.14*pow(k,a)*x)/(3.14*pow(k,a)); 

 

 

return

 wynik; 


 

// funkcja generująca współrzędne 2D (wykres funkcji weierstrassa) 

void

 generuj_tab2D( 

float

 a ) 


 

float

 x = 0; 

 

float

 s = 0.01; 

 

float

 mn = 10; 

 

for

int

 i = 0 ; i<100 ; i++ ) 

background image

~ 3 ~ 

 

 

 

 

tab2D[i][0] = x*mn; 

 

 

tab2D[i][1] = mn*weierstrass(a,x); 

 

 

x += s; 

 


 

// funkcja obracająca wykres wokół OX (rzutowanie na 3D) 

void

 generuj_3D() 


 

for

int

 j = 0 ; j<7 ; j++ ) 

 

 

 

for

int

 i = 0 ; i<100 ; i++ ) 

 

 

 

 

 

tab[j][i][0] = tab2D[i][0]; 

 

 

 

// generowanie współrzędnych dla kolejnych kątów 

obrotu 

 

 

 

// zaczynając od 0 skacząc co 30 

 

 

 

switch

( j ) 

 

 

 

 

 

 

case

 0 : 

 

 

 

 

tab[j][i][1] = 0; 

 

 

 

 

tab[j][i][2] = (-1)*tab2D[i][1]; 

 

 

 

 

break

 

 

 

case

 1 : 

 

 

 

 

tab[j][i][1] = tab2D[i][1]/2; 

 

 

 

 

tab[j][i][2] = (-5)*tab2D[i][1]/6; 

 

 

 

 

break

 

 

 

case

 2 : 

 

 

 

 

tab[j][i][1] = 5*tab2D[i][1]/6; 

 

 

 

 

tab[j][i][2] = (-1)*tab2D[i][1]/2; 

 

 

 

 

break

 

 

 

case

 3 : 

 

 

 

 

tab[j][i][1] = tab2D[i][1]; 

 

 

 

 

tab[j][i][2] = 0; 

 

 

 

 

break

 

 

 

case

 4 : 

 

 

 

 

tab[j][i][1] = 5*tab2D[i][1]/6; 

 

 

 

 

tab[j][i][2] = tab2D[i][1]/2; 

 

 

 

 

break

 

 

 

case

 5 : 

 

 

 

 

tab[j][i][2] = 5*tab2D[i][1]/6; 

 

 

 

 

tab[j][i][1] = tab2D[i][1]/2; 

 

 

 

 

break

 

 

 

case

 6 : 

 

 

 

 

tab[j][i][1] = 0; 

 

 

 

 

tab[j][i][2] = tab2D[i][1]; 

 

 

 

 

break

 

 

 

 

 

 


 

//rysowanie siatki złożonej z prostokątów 
//nie definiuję funkcji rysującej wypełnione postokąty, 
//ponieważ przy wypełnieniu nie będzie widoczna przestrzenność góry 
//wypełnianie prostokątów ma sens dopiero, gdy wprowadzone zostanie 

światło 

void

 draws( 

float

 a ) 


 

generuj_tab2D(a); 

background image

~ 4 ~ 

 

 

generuj_3D(); 

 

for

int

 j = 0 ; j<7 ; j++ ) 

 

 

 

for

int

 i = 0 ; i<99 ; i++ ) 

 

 

 

 

 

// rysowanie wykresu o konkretnym koncie (kąt 

zależny od j) 

 

 

 

glBegin(GL_LINES); 

 

 

 

 

glVertex3fv(tab[j][i]); 

 

 

 

 

glVertex3fv(tab[j][i+1]); 

 

 

 

glEnd(); 

 

 

 

//jeżeli nie jest to ostatni wykres to łączymy 

kolejne punkty (x) sąsiedniego (o większym koncie) wykresu 

 

 

 

if

( j<6 ) 

 

 

 

 

 

 

 

glBegin(GL_LINES); 

 

 

 

 

 

glVertex3fv(tab[j][i]); 

 

 

 

 

 

glVertex3fv(tab[j+1][i]); 

 

 

 

 

glEnd(); 

 

 

 

 

 

 


 

//funkcja obracająca górę 

void

 spinGora() 


 
    theta[0] -= 0.5; 
    

if

( theta[0] > 360.0 ) theta[0] -= 360.0; 

 
    theta[1] -= 0.5; 
    

if

( theta[1] > 360.0 ) theta[1] -= 360.0; 

 
    theta[2] -= 0.5; 
    

if

( theta[2] > 360.0 ) theta[2] -= 360.0; 

 

_sleep(10);  

//dodane w celu wolniejszego obracania

 

    glutPostRedisplay(); 

//odświeżenie zawartości aktualnego okna 


 

/********************************************************************

*****************/ 

 
// Funkcaja określająca, co ma być rysowane 
// (zawsze wywoływana, gdy trzeba przerysować scenę) 
 
 

  
 

void

 RenderScene(

void


 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    

// Czyszczenie okna aktualnym kolorem czyszczącym 

 

    glLoadIdentity(); 
    

// Czyszczenie macierzy bieżącej 

 

 

    glColor3f(1.0f, 1.0f, 1.0f); 

// Ustawienie koloru rysowania 

na biały  

 

background image

~ 5 ~ 

 

 

 

 

glRotatef(theta[0], 1.0, 0.0, 0.0); 

 
 

glRotatef(theta[1], 0.0, 1.0, 0.0); 

 
 

glRotatef(theta[2], 0.0, 0.0, 1.0); 

 
    draws(3); 
 
    glFlush(); 
    

// Przekazanie poleceń rysujących do wykonania 

 

  
 
    glutSwapBuffers(); 
    

//  

 

 } 
 

/********************************************************************

*****************/ 

 
// Funkcja ustalająca stan renderowania 
 

  
 

void

 MyInit(

void


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

// Kolor czyszcący (wypełnienia okna) ustawiono na czarny 
 


 

/********************************************************************

*****************/ 

 
// Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych 
// w przypadku zmiany rozmiarów okna. 
// Parametry vertical i horizontal (wysokość i szerokość okna) są 
// przekazywane do funkcji za każdym razem gdy zmieni się rozmiar 

okna. 

 

  
 

void

 ChangeSize(GLsizei horizontal, GLsizei vertical ) 


 
    GLfloat AspectRatio; 
    

// Deklaracja zmiennej AspectRatio  określającej proporcję 

    

// wymiarów okna  

 

  
 
    

if

(vertical == 0)  

// Zabezpieczenie przed dzieleniem przez 0 

 

        vertical = 1; 
 
  
 
    glViewport(0, 0, horizontal, vertical); 

background image

~ 6 ~ 

 

    

// Ustawienie wielkościokna okna widoku (viewport) 

    

// W tym przypadku od (0,0) do (horizontal, vertical) 

 

  
 
    glMatrixMode(GL_PROJECTION); 
    

// Przełączenie macierzy bieżącej na macierz projekcji 

 

  
 
    glLoadIdentity(); 
    

// Czyszcznie macierzy bieżącej            

 

  
 
    AspectRatio = (GLfloat)horizontal/(GLfloat)vertical; 
    

// Wyznaczenie współczynnika  proporcji okna 

    

// Gdy okno nie jest kwadratem wymagane jest określenie tak 

zwanej 

    

// przestrzeni ograniczającej pozwalającej zachować właściwe 

    

// proporcje rysowanego obiektu. 

    

// Do okreslenia przestrzeni ograniczjącej służy funkcja 

    

// glOrtho(...)             

 

  
 
    

if

(horizontal <= vertical) 

 
        glOrtho(-7.5,7.5,-7.5/AspectRatio,7.5/AspectRatio,10.0, -

10.0);  

 
    

else 

 

        glOrtho(-7.5*AspectRatio,7.5*AspectRatio,-7.5,7.5,10.0,-

10.0);                       

 
    glMatrixMode(GL_MODELVIEW); 
    

// Przełączenie macierzy bieżącej na macierz widoku modelu                                   

 

    glLoadIdentity(); 
    

// Czyszcenie macierzy bieżącej 

 


 

/********************************************************************

*****************/ 

 
// Główny punkt wejścia programu. Program działa w trybie konsoli 
 

  
 

void

 main(

void

{       
 

glutIdleFunc(spinGora); 

 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH); 
 
    glutInitWindowSize(300, 300); 
 
    glutCreateWindow(

"Układ współrzędnych 3-D"

); 

                   

background image

~ 7 ~ 

 

    glutDisplayFunc(RenderScene); 
    

// Określenie, że funkcja RenderScene będzie funkcją zwrotną 

    

// (callback function).  Bedzie ona wywoływana za każdym razem 

    

// gdy zajdzie potrzba przeryswania okna 

 

  
 
    glutReshapeFunc(ChangeSize); 
    

// Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną 

    

// zazmiany rozmiaru okna                         

 

  
 
    MyInit(); 
    

// Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie 

    

// inicjalizacje konieczne  przed przystąpieniem do renderowania 

 

    glEnable(GL_DEPTH_TEST); 
    

// Włączenie mechanizmu usuwania powierzchni niewidocznych 

 

    glutMainLoop(); 
    

// Funkcja uruchamia szkielet biblioteki GLUT 

 


 
  
 

/********************************************************************

*****************/