Фрактальное дерево

jpg.

Генерация фрактального дерева с помощью рекурсивной функции.

Сама генерация происходит при построении случайным образом листьев и веток дерева.
Для этого создаётся процедура Tree(x, y: Integer; a: Real; l: Integer).

На первом шаге эта процедура получает координаты начала дерева ((x, y: Integer), угол наклона ствола (a: Real) и длину основной ветви (l: Integer).

Во время работы процедуры проверяется длина вновь сгенерированной линии, при этом,если она слишком коротка, то мы будем считать её листом, а не веткой.
Координаты конца ветки вычисляются учитывая переданный угол "a":
x1 := Round(x + l*cos(a));
y1 := Round(y + l*sin(a));

Далее на основании длинны ветки, мы вводим дополнительную переменную и ее обработку для сохранения некоторых веток длинными. Те ветви, что будут признаны короткими следующим условием if p < 40 будут дополнительно обрисованы листвой. При рисовании листвы мы случайно выбираем цвет из двух близких для листвы и циклом for i:=0 to 3 , где 3 - это ширина основания листа, отрисовываем лист на основании ранее вычисленных координат paintbox1.Canvas.Line(x+i,y,x1,y1)
Если же длина ветви оказалась большой, мы рисуем ветку вместо листа в цикле for i := 0 to (p div 6).Здесь толщина ветки зависит от её длины.
Далее в цикле for i := 0 to 9 - Random(9) создаётся случайное число веток или листьев из одного узла (от 0 до 9),
вычисляется коэфициент длины будущих веток s := Random(l - l div 6) + (l div 6) и угол наклона будущих побегов a1 := a + 1.6 * (0.5 - Random).На основании s и a1 вычисляются длины будущих побегов:
x1 := Round(x + s * cos(a));
y1 := Round(y + s * sin(a));
Далее следует рекурсивный вызов процедуры Tree для прорисовки новых листьев и веток согласно полученному случайному количеству.Припередаче данных в процедуру Tree изменяется случайным образом длина веток. Чем меньше будет число отнимаемое от длины ветки, тем больше будет ветвление: Tree(x1, y1, a1, p - 5 - Random(30))

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, ExtCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    PaintBox1: TPaintBox;
    procedure Button1Click(Sender: TObject);
    procedure Tree(x, y: Integer; a: Real; l: Integer);
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1;
  kount:integer;
 
implementation
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 
  Tree(320, 580, 3*pi/2, 200);
end;
 
procedure TForm1.Tree(x, y: Integer; a: Real; l: Integer);
var
	x1, y1: Integer;
	p, s  : Integer;
	i     : Integer;
	a1    : Real;
begin
	if l < 8 then
		exit;
	x1 := Round(x + l*cos(a));
	y1 := Round(y + l*sin(a));
	if l > 100 then
		p := 100
	else
		p := l;
	if p < 40 then
	begin
	//Генерация листьев
		if Random > 0.5 then
                        paintbox1.Canvas.Pen.Color:=clgreen
 
		else
                        paintbox1.Canvas.Pen.Color:=rgbtocolor(90,139,5);
 
	    	for i := 0 to 3 do
 
                        paintbox1.Canvas.Line(x+i,y,x1,y1);
 
 
		end
	else
	begin
		//Генерация веток
                paintbox1.Canvas.Pen.Color:=rgbtocolor(100,3,4);
		for i := 0 to (p div 6) do
			paintbox1.Canvas.Line(x + i - (p div 12), y, x1, y1);
	end;
	//Следующие ветки
 	for i := 0 to 9 - Random(9) do
	begin
		s := Random(l - l div 6) + (l div 6);
		a1 := a + 1.6 * (0.5 - Random); //Угол наклона веток
		x1 := Round(x + s * cos(a));
		y1 := Round(y + s * sin(a));
		Tree(x1, y1, a1, p - 5 - Random(30)); //Чем меньше вычетаем, тем пышнее дерево
	end;
 
end;
 
 
 
 
 
initialization
  {$I unit1.lrs}
 
end.

Ключевые слова: 
Фрактал. Дерево. Рекурсия
ВложениеРазмер
project1.rar1.86 Мб