СиАОД_1-4.docx
.pdf
задание 3 Рекурсия
Цель работы
Реализовать генерацию заданного типа фрактала с применением рекурсивных функций. Добавить возможность задания глубины фрактала. Оценить глубину рекурсии. Построить таблицу зависимости времени построения от глубины фрактала.
Вариант 18
Реализовать генерацию фрактала «Дерево Пифагора»
Выполнение
Напишем программу для построения фрактала, основная функция расчета фрактала будет рекурсивная, для отрисовки фрактала будем использовать OpenGL.
#include <stdlib.h> #include <cmath> #include <GL/glut.h>
static int tic = 0; static int dir = 1; static int maxDepth = 1;
void drawtree(int n) { if (n > 0) {
//////////////////////////
// stack of matrices glPushMatrix();
glTranslatef(-0.5, 1.0, 0);
31
glRotatef(45, 0.0, 0.0, 1.0);
// 1/sqrt(2)=0.707 glScalef(0.707, 0.707, 0.707);
// recursion drawtree(n - 1);
glPopMatrix();
////////////////////////////
glPushMatrix(); glTranslatef(0.5, 1.0, 0); glRotatef(-45, 0.0, 0.0, 1.0); glScalef(0.707, 0.707, 0.707); drawtree(n - 1); glPopMatrix();
// draw a cube glutSolidCube(1); glutSolidCube(1);
}
}
void treeInit(int n) { // draw a red tree
float r = (sin(tic * 0.1)) / 2; // Generates a value between 0 and 1 float g = (cos(tic * 0.1) + 1) / 2;
float b = (sin(tic * 0.2)) / 2; glColor3f(r, g, b);
drawtree(n);
}
32
void timer(int v) {
if (tic > 19 && dir) { dir = 0;
}
if (tic < 1 && !dir) { dir = 1;
}
if (dir == 1) { tic++;
}
if (dir == 0) { tic--;
}
// u += 0.01; glLoadIdentity(); glutPostRedisplay();
glutTimerFunc(10000 / 60.0, timer, v);
}
void display(void) |
{ |
|
|
glClearColor(1.0, |
1.0, 1.0, 1.0); // Set background color to white |
||
glClear(GL_COLOR_BUFFER_BIT); |
// Clear |
the color buffer |
|
glLoadIdentity(); |
|
// Reset |
the modelview matrix |
|
|
|
|
//Adjust the camera position to look slightly downwards towards the tree gluLookAt(0.0, 0.0, 2.0, // Camera is above and looking down
0.0, 0.0, 0.0, // Looking at the center of the scene 0.0, 10.0, 0.0); // Up is in positive Y direction
//Apply a uniform scale to make the tree fit better
33
glScalef(0.5, 0.5, 0.5);
// Move the tree down along the Y axis glTranslatef(0.0, -1.5,
0.0); // Adjust the second parameter to move the tree lower treeInit(maxDepth);
//treeInit(tic); // Initialize and draw the tree with current color settings
glFlush(); // Flush the OpenGL commands std::exit(0);
}
void reshape(int w, int h) { // reshaoe to aspect ratio
glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity();
gluPerspective(80, (GLfloat)w / (GLfloat)h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
maxDepth = std::atoi(argv[1]);
glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE); glutInitWindowSize(900, 700); glutInitWindowPosition(300, 100); glutCreateWindow("Pythagoras Tree"); glutReshapeFunc(reshape); glutTimerFunc(1000, timer, 0); glutDisplayFunc(display);
34
glutMainLoop(); return 0;
}
}
}
void treeInit(int n) { // draw a red tree
float r = (sin(tic * 0.1)) / 2; // Generates a value between 0 and 1 float g = (cos(tic * 0.1) + 1) / 2;
float b = (sin(tic * 0.2)) / 2; glColor3f(r, g, b);
drawtree(n);
}
void timer(int v) {
if (tic > 19 && dir) { dir = 0;
}
if (tic < 1 && !dir) { dir = 1;
}
if (dir == 1) { tic++;
}
if (dir == 0) { tic--;
}
35
// u += 0.01; glLoadIdentity(); glutPostRedisplay();
glutTimerFunc(10000 / 60.0, timer, v);
}
void display(void) |
{ |
|
|
glClearColor(1.0, |
1.0, 1.0, 1.0); // Set background color to white |
||
glClear(GL_COLOR_BUFFER_BIT); |
// Clear |
the color buffer |
|
glLoadIdentity(); |
|
// Reset |
the modelview matrix |
|
|
|
|
//Adjust the camera position to look slightly downwards towards the tree gluLookAt(0.0, 0.0, 2.0, // Camera is above and looking down
0.0, 0.0, 0.0, // Looking at the center of the scene 0.0, 10.0, 0.0); // Up is in positive Y direction
//Apply a uniform scale to make the tree fit better
glScalef(0.5, 0.5, 0.5);
// Move the tree down along the Y axis glTranslatef(0.0, -1.5,
0.0); // Adjust the second parameter to move the tree lower treeInit(maxDepth);
//treeInit(tic); // Initialize and draw the tree with current color settings
glFlush(); // Flush the OpenGL commands std::exit(0);
}
void reshape(int w, int h) { // reshaoe to aspect ratio
glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION);
36
glLoadIdentity();
gluPerspective(80, (GLfloat)w / (GLfloat)h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
maxDepth = std::atoi(argv[1]);
glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE); glutInitWindowSize(900, 700); glutInitWindowPosition(300, 100); glutCreateWindow("Pythagoras Tree"); glutReshapeFunc(reshape); glutTimerFunc(1000, timer, 0); glutDisplayFunc(display);
glutMainLoop(); return 0;
}
37
Замеры времени
~/book/mtusi/algorithms_and_data_struct/lab_5_recursion $ time ./a.out 25
real 0m28.578s
user 0m37.655s
sys 0m1.604s
~/book/mtusi/algorithms_and_data_struct/lab_5_recursion $ time ./a.out 20
real 0m0.883s user 0m1.022s sys 0m0.085s
time ./a.out 10 real 0m0.097s user 0m0.038s sys 0m0.027s
фрактал глубиной 10 :
38
построение фрактала глубиной 25:
фрактал глубиной 5:
39
фрактал глубиной 15 с изменением угла
так как все создавалось в opengl можно посмотреть на дерево под углом
40
