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

Кривая Коха

Построение кривой Коха


Кривая Коха

Процесс построения кривой Коха выглядит следующим образом: берём единичный отрезок, разделяем на три равные части и заменяем средний интервал равносторонним треугольником без этого сегмента. В результате образуется ломанная, состоящая из четырёх звеньев длины . На следующем шаге повторяем операцию для каждого из четырёх получившихся звеньев. Предельная кривая и есть кривой Коха.

Кривую Коха можно также построить с помощью двух СИФ-преобразований:

В формате FRACTINT эти преобразования запишутся следующим образом:
Curve_Koch {
	0.5  0.288675  0.288675 -0.5 0   0        0.5
	0.5 -0.288675 -0.288675 -0.5 0.5 0.288675 0.5
}

Следующая программа реализует данный метод.

program Koh;
uses CRT, Graph;
var
	gd,gm : Integer;
const
	iter = 50000;

procedure Draw;
var
	t, x, y, p : Real;
	k : LongInt;
	mx, my, rad : Integer;

begin
	mx := 10;
	my := 250;
	rad :=600;
	Randomize;
	x := 0.0;
	y := 0.0;
	for k := 1 To iter do 
	begin
		p := Random;
		t := x;
		if p <= 1/2 then 
		begin
			x :=  1/2 * x + 1/(2*sqrt(3)) * y;
			y :=  1/(2*sqrt(3)) * t - 1/2 * y;
		end
		else
		begin
			x :=  1/2 * x - 1/(2*sqrt(3)) * y +1/2;
			y :=  -1/(2*sqrt(3)) * t - 1/2 * y + 1/(2*sqrt(3));
		end;
		PutPixel(mx + Round(rad * x), my - Round(rad * y), 2);
	end;
end;

begin
	gd := Detect;
	InitGraph(gd,gm,'');
	Draw;
	ReadKey;
	CloseGraph;
end.

Кривая Коха имеет бесконечную длину. Кроме того, кривая Кох состоит из четырёх равных частей, каждая из которых подобна всей кривой с коэффициентом подобия 1/3. Отсюда следует, что каждая часть кривой имеет бесконечную длину. Также эта кривая нигде себя не пересекает, так как достраиваемые треугольники каждый раз достаточно малы и никогда не "сталкиваются" друг с другом.

Вариации на тему кривой Коха

Три копии кривой Коха, расположенные на сторонах правильного треугольника, образуют замкнутую кривую, называемую снежинкой Коха.


Снежинка Коха


Снежинка Коха

Пострение можно производить на сторонах квадрата.


Снежинка Коха

Снежинка Коха представляет собой линию бесконечной длины, ограничивающую конечную площадь.

program Koch1;

uses CRT, Graph;

var
	gd, gm: Integer;

procedure Draw(x, y, l, u : Real; t : Integer);

procedure Draw2(Var x, y: Real; l, u : Real; t : Integer);

begin
	Draw(x, y, l, u, t);
	x := x + l*cos(u);
	y := y - l*sin(u);
end;

begin
	if t > 0 then 
	begin
		l := l/3;
		Draw2(x, y, l, u, t-1);
		Draw2(x, y, l, u+pi/3, t-1);
		Draw2(x, y, l, u-pi/3, t-1);
		Draw2(x, y, l, u, t-1);
	end
	else 
		Line(Round(x), Round(y), Round(x+cos(u)*l), Round(y-sin(u)*l))
end;

begin
	gd := Detect;
	InitGraph(gd, gm, 'c:\bp\bgi');
	Draw(410, 10, 400, -pi, 4);
	Draw(10, 410, 400, 0, 4);
	Draw(10, 10, 400, -pi/2, 4);
	Draw(410, 410, 400, pi/2, 4);
	ReadKey;            
	CloseGraph
end.
program Koch2;

uses CRT, Graph;

var
	gd, gm: Integer;

procedure Draw(x, y, l, u : Real; t : Integer);

procedure Draw2(Var x, y: Real; l, u : Real; t : Integer);

begin
	Draw(x, y, l, u, t);
	x := x + l*cos(u);
	y := y - l*sin(u);
end;

begin
	if t > 0 then 
	begin
		l := l/3;
		Draw2(x, y, l, u, t-1);
		Draw2(x, y, l, u+pi/3, t-1);
		Draw2(x, y, l, u-pi/3, t-1);
		Draw2(x, y, l, u, t-1);
	end
	else 
		Line(Round(x), Round(y), Round(x+cos(u)*l), Round(y-sin(u)*l))
end;

begin
	gd := Detect;
	InitGraph(gd, gm, 'c:\bp\bgi');
	Draw(210, 8, 400, -2*pi/3, 4);
	Draw(10, 354, 400, 0, 4);
	Draw(410, 354, 400, 2*pi/3, 4);
	ReadKey;              
	CloseGraph
end.
program Koch3;

uses CRT, Graph;

var
  gd, gm: Integer;

procedure Draw(x, y, l, u : Real; t : Integer);

procedure Draw2(Var x, y: Real; l, u : Real; t : Integer);

begin
	Draw(x, y, l, u, t);
	x := x + l*cos(u);
	y := y - l*sin(u);
end;

begin
	if t > 0 then 
	begin
		l := l/3;
		Draw2(x, y, l, u, t-1);
		Draw2(x, y, l, u+pi/3, t-1);
		Draw2(x, y, l, u-pi/3, t-1);
		Draw2(x, y, l, u, t-1);
	end
	else 
		Line(Round(x), Round(y), Round(x+cos(u)*l), Round(y-sin(u)*l))
end;

begin
	gd := Detect;
	InitGraph(gd, gm, 'c:\bp\bgi');
	Draw(10, 354, 400, pi/3, 4);
	Draw(410, 354, 400, pi, 4);
	Draw(210, 8, 400, -pi/3, 4);
	ReadKey;          
	CloseGraph
end.

Снежинку Коха Можно получить используя следующие СИФ (формат FRACTINT):

Island_Koch {
	 0.333  0.000  0.000  0.333 -0.006 7.325 0.084
	-0.167  0.288 -0.288 -0.167  2.013 3.823 0.083
	-0.167 -0.288  0.288 -0.167 -2.031 3.816 0.083
	 0.167  0.288 -0.288  0.167  2.031 6.136 0.084
	-0.333  0.000  0.000 -0.333  0.006 2.651 0.083
	 0.167 -0.288  0.288  0.167 -2.025 6.153 0.083
	 0.333  0.000  0.000  0.333 -0.006 1.325 0.084
	 0.167  0.288 -0.288  0.167 -3.177 3.148 0.083
	-0.167  0.288 -0.288 -0.167 -3.183 6.823 0.083
	-0.333  0.000  0.000 -0.333 -0.006 8.651 0.084
	 0.167 -0.288  0.288  0.167  3.159 3.165 0.083
	-0.167 -0.288  0.288 -0.167  3.177 6.804 0.083
}
или
Island_Koch_2 {
	0.333  0.000 0.000 0.333 -1.998  6.785 0.110
	0.333  0.000 0.000 0.333 -1.998 -0.139 0.110
	0.333  0.000 0.000 0.333  1.998 -0.139 0.110
	0.333  0.000 0.000 0.333  1.998  6.785 0.110
	0.333  0.000 0.000 0.333 -3.978  3.317 0.110
	0.333  0.000 0.000 0.333  4.002  3.317 0.110
	0.502 -0.290 0.290 0.502  1.452  2.442 0.340
}

Построение кривой Коха с помощью метода системы счисления по основанию 4

Более подробно смотрите Фракталы и системы счисления.

program Curve;

uses CRT, Graph;

const
	p = 4;
  
var
	gd, gm: Integer;
	i, j: Integer;
	x, y, l: Real;
	a: Real;
	n, m, k: Integer;

begin
	gd := Detect;
	InitGraph(gd, gm, 'c:\bp\bgi');
	x := 0;
	y := 400;
	l := 640/(exp(p*ln(3)));
	MoveTo(Round(x), Round(y));
	for i:=0 to Round(exp(p*ln(4)))-1 do 
	begin
		a := 0;
		n := i;
		k := 0;
		repeat
			m := n mod 4;
			n := n div 4;
			case m of
				0: a := a + 0;
				1: a := a - pi/3;
				2: a := a + pi/3;
				3: a := a + 0;
			end;
			inc(k);
		until k >= p;
		x := x + l*cos(a);
		y := y + l*sin(a);
		LineTo(Round(x), Round(y));
	end;
	ReadKey;
	CloseGraph;
end.

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

Ссылки: