IPB
ЛогинПароль:

 
 Ответить  Открыть новую тему 
> Фракталы 3d
сообщение
Сообщение #1


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Множество Мандельброта и множество Жюлиа.

Одним из интереснейших явлений в природе, можно по праву выделить фракталы. Более 30 лет назад, Бенуа Мандельброт ввел термин -фрактал, но до сих пор точного определения не существует. Одним из известных алгебраических фракталов, является фрактал Мандельброта (множество Мандельброта), который был так назван, в честь французского математика, упомянутого выше.
Я решил рассмотреть фрактал Мандельброта и Жюлиа в трехмерном пространстве.
Сначала кратно рассмотрим процедуру построения фрактального множества.
Возьмем формулу z'=F(z,c)
Это функцию от двух комплексных переменных z и c.
Вообще говоря одна из переменных "закрепляется" при построении, и в зависимости от того. какую переменную мы закрепим, мы получим либо множество Жюлиа либо множество Мандельброта.
Фактически z'=F(z,c) - чистейшая рекурсия. Но почему-то (видимо для скорости вычисления) принято использовать итерацию. В результате n итераций функции, мы получим некое значение Z которое будет предельным (вообще говоря выбирать этот предел можно произвольно... )
А само число n, будет показывать сколько итераций необходимо для достижения этого предела.
Выполнив для каждой точки пространства такой процесс, мы получим не что иное как фрактал.

Если z выбирается в зависимости от точки M(x,y) на плоскости, то получаем фрактал Мандельброта (при с- фиксированной), иначе, если z - константа, а c - переменная x+iy, то получим множество Жюлиа.

Саму функцию f(z,c) можно вообще говоря брать любую (будем получать различные фракталы) но как пример используют f= z^2 +c;

Простейшая программа рисования множества Мандельброта и Жюлиа (для построения Жюлиа, измените :{$define mandel} на {$define _mandel} например )

{$define mandel}
{$ifdef win32}
{$apptype gui}
{$mode objfpc}
uses wincrt,graph;
{$else}
uses graph, crt;
{$endif}

type
TComplex = record
X : Real;
Y : Real;
end;
const
iter = 50;
max = 16;
var
z, t, c : TComplex;
x, y, n : Integer;
Cancel : Boolean;
{$ifdef win32}
gd, gm : SmallInt;
{$else}
gd,gm: integer;
{$endif}
mx, my : Integer;
begin
Cancel := False;
Randomize;
gd := Detect;
InitGraph(gd,gm,'');
mx := GetMaxX div 2;
my := GetMaxY div 2;
for y := -my to my do
for x := -mx to mx do begin
n := 0;
{$ifdef mandel}
C.X := X * 0.005;
C.Y := Y * 0.005;
z.X := 0;
z.Y := 0;
{$else}
z.x := X * 0.005;
z.y := Y * 0.005;
c.x := 0.11;
c.y := -0.66;
{$endif}
while (sqr(z.X) + sqr(z.Y) < max) and (n < iter) do begin
t := z;
Z.X := sqr(t.X) - sqr(t.Y) + C.X;
Z.Y := 2 * t.X * t.Y+ C.Y;
Inc(n);
If keypressed then cancel := true;
end;
If n < iter then begin
PutPixel(mx + x,my + y,16 - (n mod 16));
end;
if cancel then exit;
end;
readkey;
closegraph;
end.


Но на этом останавливаться неинтересно!
Что если вместо цвета, определять высоту точки над плоскостью, и посмотреть эту фигурку в 3D пространстве?
Что же, так и поступим... вот текст программы, реализующий вывод множества в виде 3D поверхности.
(не обращайте внимание на странный метод - построение матрицы и дальнейшее конвертирование в массив, этот лишний шаг был сделан на этапе тестирования, вопрос с памятью, так же пусть не пугает вас, я специально завысил параметры, текст программы не оптимизирован, да и цель не текст программы а множество Мандельброта)
Код
unit main_types;
interface
const
        _maxx = 160;
        _maxy = 100;
        maxpixelcount = _maxx*_maxy*256;
type

        tfloat = single;
        tlong = longint;
        tint = integer;
        tbyte = byte;

        maparr = array[1.._maxx, 1.._maxy] of tbyte;


        tcomplex = record
                         cmplx_x, cmplx_y :tfloat;
        end;

        tpixelarr = array[0..maxpixelcount] of tfloat;
        //cube
        { (-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1, 1,1,-1,1,1,1);}
        tlineindex =  array[0..maxpixelcount] of tint;
        //cube
        { (0,1,0,4,0,2,1,3,1,5,2,3,2,6,3,7,4,5,4,6,5,7,6,7);}

implementation
end.


Код
{$mode objfpc}
unit fract;
interface
uses
    windows, graph, wincrt, main_types;


function complex (re, im: tfloat ): tcomplex;
procedure InitGraphMode (mode:smallint);
procedure create_mandel(zoomx,zoomy,dx,dy:tfloat; var a:maparr );


implementation


function complex (re, im: tfloat ): tcomplex;
begin
     with result do begin
          cmplx_x:=re;
          cmplx_y:=im;
     end;
end;


operator +  ( const cmx_1, cmx_2 : tcomplex ) r:tcomplex;
begin
     r.cmplx_x:=cmx_1.cmplx_x+cmx_2.cmplx_x;
     r.cmplx_y:=cmx_1.cmplx_y+cmx_2.cmplx_y;
end;


operator -  ( const cmx_1, cmx_2 : tcomplex ) r:tcomplex;
begin
     r.cmplx_x:=cmx_1.cmplx_x-cmx_2.cmplx_x;
     r.cmplx_y:=cmx_1.cmplx_y-cmx_2.cmplx_y
end;

operator * ( const cmx_1, cmx_2 : tcomplex ) r:tcomplex;
begin
     r.cmplx_x:= (cmx_1.cmplx_x*cmx_2.cmplx_x) - (cmx_1.cmplx_y*cmx_2.cmplx_y);
     r.cmplx_y:= (cmx_1.cmplx_x*cmx_2.cmplx_y) + (cmx_1.cmplx_y*cmx_2.cmplx_x)
end;

procedure InitGraphMode (mode:smallint);
var
   gd: smallint;
begin
     gd:= D8bit;
     initgraph (gd, mode, '');
     SetWindowText(FindWindow(Nil,Pchar('Graph window application')),pchar('Fractals'));
     EnableMenuItem(GetSystemMenu(FindWindow(Nil, Pchar('Fractals')),False) ,SC_CLOSE,MF_BYCOMMAND or MF_GRAYED);

end;


Const
   color =16;
   iter = 50;
   max  = 2*color;


procedure create_mandel(zoomx,zoomy,dx,dy:tfloat; var a:maparr );
var
        z,c: tcomplex;
        mx,my,x,y:longint;
        n:integer;

begin
        for x:=1 to _maxx do for y:=1 to _maxy do a[x,y]:=0;
        Mx         :=          _maxx div 2;
        My         :=          _maxy div 2;
        For y := -my to my do
                For x := -mx to mx do Begin
                        n := 0;
                        {$ifdef _mandel}
                              c:=complex (x *zoomx+dx, y*zoomy +dy);
                              z:=complex (0, 0 );
                        {$else}
                              z:=complex (x* zoomx+dx, y*zoomy+dy);
                              c:=complex(0.11, -0.66);
                              {$ifdef dendrid}
                                    c:=complex(0,1);
                              {$endif}
                        {$endif}
                        While (sqr(z.cmplx_x) + sqr(z.cmplx_Y) < max) and (n < iter) do Begin
                                //z:=c*z - c*z*z;
                                z:=z*z - c;
                                //z:=z*z-complex(x *zoomx+dx, y*zoomy +dy);
                                Inc(n);
                        End;
                        If n < iter then   a[mx + x,my + y]:= 64 - (n mod color) else a[mx +x, my +y]:=15;


                end;

end;


end.

{var
   gd,gm:smallint;
   dx,dy,zoomx, zoomy:     tfloat;
   i,j:longint;
   mandel_map : maparr;
begin
     zoomx      :=          0.007;
     zoomy      :=          0.007;
     dx         :=          0.5;
     dy         :=         0.0;
     Randomize;
     InitGraphMode (m800x600);
     create_mandel(zoomx,zoomy,dx,dy,mandel_map);
     for i:=1 to _maxx do for j:=1 to _maxy do putpixel(i,j,mandel_map[i,j]);
     readkey;
     CloseGraph;
end.}



Код
{$M 99000000, 0, 0}
{$mode objfpc}
{$apptype gui}
{$define mode1}
{$define no_debugmode}


uses
    graph,wincrt, windows, fract, main_types;

const {global}
      kontur:boolean = false;



procedure drawpixel_l(x,y:   tint; points:tpixelarr; zoom: tfloat; pointcount:tint; color:tint);
var
sx,sy,sx1,sy1,p:tlong;
begin
     for p:=0 to pointcount-1 do begin
         sx:=round(zoom*points[p*3])+x;
         sy:=round(zoom*points[p*3+1])+y;
         sx1:=round(zoom*points[(p+1)*3])+x;
         sy1:=round(zoom*points[(p+1)*3])+x;
         setcolor(color);
         line(sx,sy,sx1,sy1);
     end;
end;


procedure drawpixel(var mandel:maparr; x,y:   tint; points:tpixelarr; zoom: tfloat; pointcount:tint; color:tint);
var
sx,sy,sx1,sy1,p:tlong;
gv:tint;
begin
     for p:=0 to pointcount-1 do begin
         sx:=round(zoom*points[p*3])+x;
         sy:=round(zoom*points[p*3+1])+y;
         {setcolor(color);}
         if p < pointcount -5 then
//          gv:=mandel[trunc(points[p*3]), trunc(points[p*3+1]) ];
//          if gv>250 then gv:=31;
gv:=15;

         if color=15 then putpixel(sx,sy,gv) else  putpixel(sx,sy,color)


     end;
end;

procedure calc(var cube:tpixelarr; pointcount:tint;xan,yan,zan:tfloat);
var
   p:tlong;
   xt,yt,zt:tfloat;
begin
     for p:=0 to pointcount-1 do begin
         yt := cube[p*3+1] * cos(xan) - cube[p*3+2] * sin(xan);
         zt := cube[p*3+1] * sin(xan) + cube[p*3+2] * cos(Xan);
         cube[p*3+1] := Yt;
         cube[p*3+2] := Zt;
         xt := cube[p*3] * cos(Yan) - cube[p*3+2] * sin(Yan);
         zt := cube[p*3] * sin(Yan) + cube[p*3+2] * cos(Yan);
         cube[p*3] := xt;
         cube[p*3+2] := Zt;
         xt := cube[p*3] * cos(zan) - cube[p*3+1] * sin(zan);
         yt := cube[p*3] * sin(Zan) + cube[p*3+1] * cos(Zan);
         cube[p*3] := xt;
         cube[p*3+1] := yt
     end;
end;

procedure draw_and_calc ( x,y:   tint; var points:tpixelarr; zoom: tfloat; pointcount:tint; color:tint; xan,yan,zan:tfloat );
var
sx,sy,sx1,sy1:tlong;
gv:tint;
   xt,yt,zt:tfloat;
   p:integer;
   st:byte;
begin
st:=4;
//no color
//st=3;
for p:=0 to pointcount-1 do begin
         if (round(points[p*st+3])<>15) or (kontur=true)  then begin {§ ¬Є­гвл© Є®­вга... }
            sx:=round(zoom*points[p*st])+x;
            sy:=round(zoom*points[p*st+1])+y;
            gv:=0;
            putpixel(sx,sy,gv);
            // new coords...
            yt := points[p*st+1] * cos(xan) - points[p*st+2] * sin(xan);
            zt := points[p*st+1] * sin(xan) + points[p*st+2] * cos(Xan);
            points[p*st+1] := Yt;
            points[p*st+2] := Zt;
            xt := points[p*st] * cos(Yan) - points[p*st+2] * sin(Yan);
            zt := points[p*st] * sin(Yan) + points[p*st+2] * cos(Yan);
            points[p*st] := xt;
            points[p*st+2] := Zt;
            xt := points[p*st] * cos(zan) - points[p*st+1] * sin(zan);
            yt := points[p*st] * sin(Zan) + points[p*st+1] * cos(Zan);
            points[p*st] := xt;
            points[p*st+1] := yt;
            sx:=round(zoom*points[p*st])+x;
            sy:=round(zoom*points[p*st+1])+y;
            gv:=round(points[p*st+3]);
            putpixel(sx,sy,gv+64);
         end;

     end;
end;



function read_from_file (fn: string; var  objpoint:tpixelarr; var pixcount: tint ): boolean;
var
   sourcefile:text;
   i:tint;
   _count:tint;
begin
     assign( sourcefile, fn);
     {$I-} reset( sourcefile );{$I+}
     result := (ioresult=0);
     if ioresult =0 then begin
        readln( sourcefile , pixcount );
        _count:=pixcount*3;
        for i:=0 to _count-1 do begin
                read( sourcefile, objpoint[i] );
        end;
     end
end;

procedure  convert_map(var  _map:maparr; var _pmap:tpixelarr);
var
        i,j,k:tlong;
begin
        k:=0;
        for i:=1 to _maxx do for j:=1 to _maxy do begin
                _pmap[k]:=i;
                inc(k);
                _pmap[k]:=j;
                inc(k);
                _pmap[k]:=_map[i,j];
                inc(k);
        end;
        {pixcount:=_maxx*_maxy;}
end;


var
   t:char;
   xan,yan,zan, zoom:tfloat;
   objpoint:tpixelarr;
{   objline :tlineindex;}
   pixcount,linecount: tint;
   filename:string;
   {i:integer;}
   dx,dy,zoomx, zoomy:     tfloat;
   mandel_map : maparr;
  vp, i,j,k: integer;
  r:tfloat;
begin

     zoomx      :=          0.02;
     zoomy      :=          0.02;
     dx         :=          0.2;
     dy         :=         0.0;
     {$ifdef debugmode}      writeln ('create mandel map...'); {$endif}
     create_mandel(zoomx,zoomy,dx,dy,mandel_map);
     {$ifdef debugmode}writeln('ok! press any key!'); readln; {$endif}

   {
     filename:='d:/g.txt';

     if not read_from_file (filename, objpoint, pixcount ) then begin
        writeln ('Error I\O');
        halt
     end  else begin } {
        for i:=0 to pixcount do write ( objpoint[i]:3);
     end;}


     {writeln('convert ...');
     convert_map( mandel_map, objpoint);
     writeln('ok! press any key!');
}
        k:=-1;
        for i:=1 to _maxx do for j:=1 to _maxy do begin
                inc(k);
                objpoint[k]:=0;
        end;
    //    writeln('zero!');readln;

        k:=-1;
        for i:=- _maxx div 2 to _maxx div 2 do for j:=- _maxy div 2 to _maxy div 2 do begin
                inc(k);
                objpoint[k]:=i;
                inc(k);
                objpoint[k]:=j;
                inc(k);
                objpoint[k]:=mandel_map[(_maxx div 2) + i, (_maxy div 2) +j];

                //color
                inc(k);
                objpoint[k] :=mandel_map[(_maxx div 2) + i, (_maxy div 2) +j];
        end;
      //       writeln('ok! press any key!');




     {} pixcount:=_maxx*_maxy;

     initgraphmode (m800x600);
//     initgraphmode (g1024x768x16);

     zoom:=exp(1);
     vp:=10;
     r:=0;
     repeat
      zan := 0.01;
      yan := 0.01;
      xan := 0.02;

     {$ifdef mode1}
           draw_and_calc (getmaxx div 2, getmaxy div 2, objpoint, zoom ,pixcount,15, xan,yan,zan);
           delay(10);
     {$else}
           setactivepage(1);
           cleardevice;
           calc(objpoint, pixcount,xan,yan,zan);
           drawpixel(mandel_map,getmaxx div 2, getmaxy div 2, objpoint, zoom ,pixcount, 15);
           setvisualpage(1);
           delay(vp);

           setactivepage(2);
           cleardevice;
           calc(objpoint, pixcount,xan,yan,zan);
           drawpixel(mandel_map,getmaxx div 2, getmaxy div 2, objpoint, zoom ,pixcount, 15);
           setvisualpage(2);
           delay(vp);

     {$endif}
//           delay(20);
          { drawpixel(getmaxx div 2, getmaxy div 2, objpoint, zoom ,pixcount, 0);}
//          cleardevice;
  //         calc(objpoint, pixcount,xan,yan,zan);
           if keypressed then begin
              t:=readkey;
              case t of
                   '=':zoom:=zoom+0.1; {+}
                   '-': zoom:=zoom-0.1;{-}
              end;
              cleardevice;
           end
     until t=#13;
     closegraph;
{     writeln('press any key...');}
{     readln;}
end.


Вот скомпилированная программа:
Прикрепленный файл  gr3d.zip ( 51.63 килобайт ) Кол-во скачиваний: 478

В ней выводиться множество Жюлиа, при желании измением define переменной, можно выводить множество Манделброта.
Выход их программы - ENTER, клавиши - и = - увеличение и уменьшение сетки вывода.

А теперь мысленно представим , что выведенная сетка - повехность! Какая же красота открывается нашему взгляду! wub.gif

Ничто пожалуй так не притягивает взор как математические объекты - графики, аттракторы, фракталы, со своей математической красотой и совершенством форм и линий!

(просматривайте скриншеты, они не пустые smile.gif )
Прикрепленное изображениеПрикрепленное изображениеПрикрепленное изображение


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Знаток
****

Группа: Пользователи
Сообщений: 408
Пол: Мужской

Репутация: -  3  +


Еще одного в нашем полку прибыло
я так люблю эти плазмы и фракталы и множества и много много другого
я имею ввиду в компутерном виде
демок много много видел - вот тама - класс


--------------------
- Где я?
- Во тьме.
- В какой тьме?
- Во тьме твоего мозга.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 21.11.2019 3:21
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name