~ 1 ~
POLITECHNIKA WROCŁAWSKA
Sprawozdanie
Generowanie modelu góry z wykorzystaniem
funkcji Weierstrassa
Gwidon Jóźwiak, 171864
2010-11-17
~ 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++ )
~ 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);
~ 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
~ 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);
~ 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"
);
~ 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
}
/********************************************************************
*****************/