Матрица статей        Список статей        Всячина        Контакты       

Генерация фрактальных деревьев

Одним из приложений теории фракталов является генерация фрактальных деревьев. Ниже приведены программы, которые генерируют фрактальные деревья.

Приведённая ниже программа строит плоские деревья. (Программа написана по мотивам программы со страницы Fractal Tree Drawing for SVGA ). Идея проста. Строится ствол дерева случайной длины, от него строятся несколько ветвей тоже случайной длины, при этом толщина уменьшается, далее от каждой ветки строится еще несколько веток (хотя от некоторых ничего не строится совсем), и цикл повторяется. При этом на каждом шаге проверяется длина ветки, если она меньше некоторой заранее определенной величины, то заместо веток рисуется лист, и для этой ветки процесс прекращается. При этом можно изменять самые разные параметры, от ветвистости, толщины ствола и веток, до угла наклона веток и цвета листьев.


Фрактальные деревья Фрактальные деревья

program FracTree;
uses Graph, CRT;
procedure 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 
			SetColor(10) 
		else 
			SetColor(2);   {4, 14}
	    	for i := 0 to 3 do
			Line(x + i, y, x1, y1)
		end
	else
	begin
		{Генерация веток}
		SetColor(6);
		for i := 0 to (p div 6) do
			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;

var
	gd, gm: Integer;
begin
	Randomize;
	gd := Detect;
	InitGraph(gd, gm, 'c:\bp\bgi');
	Tree(320, 480, 3*pi/2, 200);
	ReadKey;
	CloseGraph;
end.

Ниже представлены варианты трёхмерных фрактальных деревьев, полученных примерно по такому же алгоритму.


Трёхмерные фрактальные деревья Трёхмерные фрактальные деревья

Ниже приведена основная часть программы на Java, c помощью которой эти изображения и были получены.

package tree;

import base.*;
import java.awt.*;

public class Tree extends Solid
{
	Colorer treeColorer = new SimpleColorer(Color.RED, Color.ORANGE);
	Colorer leafColorer = new SimpleColorer(new Color(0, 127, 0), Color.YELLOW);

	// Создать конус
	public static Solid createCone(double height, double radius, int countQuadrangles, Colorer colorer)
	{
		Solid solid = new Solid();
		double phi1, phi2;
	
		for (int i = 0; i < countQuadrangles; ++i)
		{
			phi1 = 2 * Math.PI / countQuadrangles * i;
			phi2 = 2 * Math.PI / countQuadrangles * (i + 1);
			Vector[] vertexes = new Vector[3];
			vertexes[0] = new Vector(radius * Math.cos(phi1), radius * Math.sin(phi1), 0);
			vertexes[1] = new Vector(radius * Math.cos(phi2), radius * Math.sin(phi2), 0);
			vertexes[2] = new Vector(0.0, 0.0, height);
			solid.add(new Triangle(vertexes, colorer));
		}
		
		return solid;
	}	
	
	public static Solid createLeaf(double size, Colorer colorer)
	{
		Solid solid = new Solid();
		Vector[] vertexes = new Vector[3];
		vertexes[0] = new Vector(0.0, 0.0, 0.0);
		vertexes[1] = new Vector(0.0, size / 3.0, size / 2.0);
		vertexes[2] = new Vector(0.0, 0, size);
		solid.add(new Triangle(vertexes, colorer));
		vertexes = new Vector[3];
		vertexes[0] = new Vector(0.0, 0, size);
		vertexes[1] = new Vector(0.0, -size / 3.0, size / 2.0);
		vertexes[2] = new Vector(0.0, 0.0, 0.0);
		solid.add(new Triangle(vertexes, colorer));
		return solid;
	}		
	
	
	void branch(int n, double size, double radius, Transform T)
	{
		if (--n > 0)
		{
			int count = (int)((n == 1) ? (size / 8 + 1) : (size / 25));
			for (int i = 0; i < count ; ++i)
			{
				double r = (Math.random() * 0.9 + 0.1) * size;
				branch(n, (size - r) * 0.7, (size - r) / 25.0,
					Transform.createTranslateZ((size - r) / 30.0).composite(
					Transform.createRotateY(Math.PI / 3.0).composite(
					Transform.createRotateZ(2.0 * Math.PI * Math.random()).composite(
					Transform.createTranslateZ(r).composite(
					T)))));
			}
			for (int i = 0; i < 5 ; ++i)
			{
				double r = (Math.random() * 0.1) * size;
				branch(1, 0, 0,
					Transform.createTranslateZ((size - r) / 30.0).composite(
					Transform.createRotateY(Math.PI / 3.0).composite(
					Transform.createRotateZ(2.0 * Math.PI * Math.random()).composite(
					Transform.createTranslateZ(r).composite(
					T)))));
			}			
			addAll(T.apply(createCone(size, radius, 10, treeColorer)));
		}
		else
			addAll(T.apply(createLeaf(20, leafColorer)));
	}
	
	Tree()
	{
		branch(4, 600.0, 60.0, Transform.createTranslateZ(-300));
	}
}

Скачать:

Смотрите также:

Ссылки: