Сгенерировать фрактальное дерево.
генерирование фрактального дерева основано на построении случайным образом рисунка веток и листьев. Для этого создаем функцию
void Tree(int x, int y, float a, int l)
изначально она получит координаты начала дерева (int x, int y), угол наклона основного ствола дерева (float a) и длину основной ветви (int l).
В самой функции мы будем проверять достижение минимального размера линии, которую мы уже не можем отнести к ветке по длиннее.
Внутри условия, мы вычисляем координаты конца ветки согласно переданного угла в функцию:
x1 = ceil(x + l*cos(a));
y1 = ceil(y + l*sin(a));
Далее на основании длинны ветки, мы вводим дополнительную переменную и ее обработку для сохранения некоторых веток длинными. Те ветви, что будут признаны короткими следующим условием if (p < 40) будут дополнительно обрисованы листвой. При рисовании листвы мы случайно выбираем цвет из двух близких для листвы и циклом for(i = 0; i <= 3; i++), где 3 это ширина основания листа, отрисовываем лист на основании ранее вычисленных координат line(x+i, y, x1, y1).
В случае если длинна ветви оказалась большой, мы отрисовываем вместо листа ветку с помощью цикла for( i = 0; i <= (floor(p/6)); i++), где толщина ветви зависит от ее длинны.
Дальше с помощью цикла for( i = 0; i < (9 - ceil(random(5))); i++), который позволит создать случайное количество веток или листьев из одного узла, от 4 до 9ти. Внутри цикла мы вычисляем коэффициент длины s = (random(l - ceil(l/6)) + ceil(l/6)) и угол наклона будущих побегов a1 = a + 0.16*(5 - random(10)). На основании вычисленого угла и коэффициента мы определим координаты будущих побегов
x1 = ceil(x + s*cos(a));
y1 = ceil(y + s*sin(a));
и далее запустим рекурсивно функцию дерева снова, чтоб отрисовать новые листья и ветки, согласно выбранному количеству случайным образом в цикле. При передаче мы будем изменять длину ветки, чем меньше будет ее уменьшение тем большее будет ветвление Tree(x1, y1, a1, p - 5 - random(30)).
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
void Tree(int x, int y, float a, int l)
{
int p;
int x1, y1;
float s, a1, i;
if (l > 8)
{
x1 = ceil(x + l*cos(a));
y1 = ceil(y + l*sin(a));
if (l > 150)
{
p = 100;
} else {
p = l;
}
if (p < 40)
{
if ((random(10)) > 5)
{
setcolor(2);
} else
{
setcolor(42);
};
for(i = 0; i <= 3; i++)
{
line(x+i, y, x1, y1);
};
} else
{
setcolor(4);
for( i = 0; i <= (floor(p/6)); i++)
{
line(x + i - floor(p/12), y, x1, y1);
}
};
for( i = 0; i < (9-ceil(random(5))); i++)
{
s = (random(l - ceil(l/6)) + ceil(l/6));
a1 = a + 0.16*(5 - random(10));
x1 = ceil(x + s*cos(a));
y1 = ceil(y + s*sin(a));
Tree(x1, y1, a1, p - 5 - random(30));
}
}
}
int main(void)
{
/* request auto detection */
int gdriver = DETECT, gmode, errorcode;
/* initialize graphics and local variables */
initgraph(&gdriver, &gmode, "");
/* read result of initialization */
errorcode = graphresult();
/* an error occurred */
if (errorcode != grOk)
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1);
}
randomize();
Tree(320, 480, 3*M_PI/2, 200);
getch();
closegraph();
return 0;
}
Ключевые слова:
фрактал рекурсия дерево