Фрактальные множества Delphi

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

Здесь хочу остановиться на фрактальных множествах Мандельброта и Жюлиа. Изображения этих множеств не имеют каких либо четко очерченных границ. Особенностью фракталов является то, что даже маленькая часть изображения в конечном итоге представлет общее целое, особенно хорошо этот эффект можно пронаблюдать на примере множества Жюлиа. Кстати на основе этого свойства фракталов основано фрактальное сжатие данных, но эту тему разберем как-нибудь позже (когда накопиться достаточно нужного материала).

Итак приступим к самому главному, ради чего мы здесь и собрались. Как же строятся эти удивителные множества ?

Все сводится к вычислению одной единственной формулы.


Zi+1=Zi2+C   

Здесь Z и C - комплексные числа. Как видно, формулы по сути представляет собой обычную рекурсию (или что-то вроде многократно примененного преобразования). Зная правила работы с комплексными числами данную формулу можно упростить и привести к следующему виду.


xi+1=xi2-yi2+a  
yi+1=2*xi*yi+b  

Построение множества Мандельброта сводится к следующему. Для каждой точки (a,b) проводится серия вычислений по вышеприведенным формулам, причем x0 и y0 принимаются равными нулю, т.е. точка в формуле выступает в качестве константы. На каждом шаге вычиляется величина r=sqrt(x2+y2 ). Значением r ,как ни трудно заметить, является расстояние точки с координатами (x,y) от начала координат ( r=sqrt[ (x-0)2+(y-0)2] ). Исходная точка (a,b) считается принадлежащей множеству Мандельброта, если она никогда не удаляется от начала координат на какое-то критическое число. Для отображения можно подсчитать скорость удаления от центра, если например точка ушла за критическое расстояние, и в зависимости от нее окрасить исходную точку в соответствующие цвет. Полное изображение множества Мандельброта можно получить на плоскости от -2 до 1 по оси x и от -1.5 до 1.5 по оси y. Также известно, что для получения примелимой точности достаточно 100 итеарций (по теории их должно быть бесконечно много). Ниже представлен листинг функции реализующей выполнение итераций и определение принадлежности точки множеству Мандельброта, точнее на выходе мы получаем цвет для соответствующе точки. В качестве критического числа взято число 2. Чтобы не вычислять корень, мы сравниваем квадрат расстояния (r2) с квадратом критического числа, т.е. сравниваем (x2+y2) и 4.


function MandelBrot(a,b: real): TColor;  
var  
    x,y,xy: real;  
    x2,y2: real;  
    r:real;  
    k: integer;  
begin  
    r:=0;  
    x:=0; y:=0;  
    k:=100;  
    while (k>0)and(r<4) do  
    begin  
        x2:=x*x;  
        y2:=y*y;  
        xy:=x*y;  
        x:=x2-y2+a;  
        y:=2*xy+b;  
        r:=x2+y2;  
        dec(k)  
    end;  
    k:=round((k/100)*255);  
    result:=RGB(k,k,k);  
end;   

Множество Жюлиа получается если зафиксировать в формуле значение комплексной константы (a+ib), которая будет одинакова для всех точек, а начальные значения x0 и y0 принимать равными значениям координатам вычисляемой точки. Листинг для множества Жюлиа приведен ниже.


function Julia(x0,y0: real): TColor;  
var  
    a,b,x,y,x2,y2,xy: real;  
    r:real;  
    speed,k: integer;  
begin  
    r:=1;  
    a:=-0.55; b:=-0.55;  
    x:=x0; y:=y0;  
    k:=100;  
    while (k>0)and(r<4) do  
    begin  
        x2:=x*x;  
        y2:=y*y;  
        xy:=x*y;  
        x:=x2-y2+a;  
        y:=2*xy+b;  
        r:=x2+y2;  
        dec(k)  
    end;  
    k:=round((k/100)*255);  
    result:=RGB(k,k,k);  
end;   

Ниже приведен листинг функции отображающий данные множества.


procedure TForm1.BitBtn2Click(Sender: TObject);  
var  
    x_min,y_min,x_max,y_max,hx,hy,x,y: real;  
    i,j,n: integer;  
    color: TColor;  
begin  
    x_min:=-1.5; x_max:=2;  
    y_min:=-1.5; y_max:=1.5;  
    n:=300;  
    y:=y_min;  
    hx:=(x_max-x_min)/n;  
    hy:=(y_max-y_min)/n;  
    for j:=0 to n do  
    begin  
        x:=x_min;  
        for i:=0 to n do  
        begin  
            if rbM.Checked then color:=MandelBrot(x,y);  
            if rbJ.Checked then color:=Julia(x,y);  
            imPict.Picture.Bitmap.Canvas.Pixels[i,j]:=color;  
            x:=x+hx;  
        end;  
        y:=y+hy;  
    end;  
end;   

При рассмотрении темы большую помощь оказала статья А.Колесникова "Визуализация фрактальных структур" в "Компьтерных вестях".
Теги:
Фрактальные множества
Добавлено: 07 Августа 2018 21:32:09 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...