Mega Code Archive

 
Categories / Delphi / Algorithm Math
 

Building a Fractal Generator

Title: Building a Fractal Generator Question: How do you build those bright, weird, beautiful shapes called fractals they're everywhere in science, art and forecasting with graphic-routines for Delphi and Kylix ? Answer: Fractals are geometric figures, just like rectangles, circles and squares, but fractals have special properties that those figures do not have. There's lots of information on the Web about fractals, but most of it is either just pretty pictures or very high-level mathematics. So this article shows the important routine to draw the famous mandelbrot on a canvas. Benoit Mandelbrot was largely responsible for the present interest in fractal geometry. He showed how fractals can occur in many different places in both mathematics and elsewhere in nature. Much research in mathematics is currently being done all over the world. Although we need to study and learn more before we can understand most modern mathematics, there's a lot about fractals that we can understand. Before we take a look at the mandelbrot-code a note about the unit: A lot of programms does exists. I would only give you a glance at some code-snippets to motivate you, building your own generator with your own prameters in it. The OP-oriented library is free for download and shows some topics in Chaos like - Logistic Map - Henon - Lorenz Attractor - Bifurcation - Mandelbrot So here's the mandelbrot(not a real universum picture just plain code ;) procedure TModelMandelbrot.process(X, Y, au,bu: double; X2, Y2: integer); var c1, c2, z1, z2, tmp: double; i, j, count: integer; begin c2:= bu; for i:= 10 to X2 do begin c1:= au; for j:= 0 to Y2 do begin z1:= 0; z2:= 0; count:= 0; {count is deep of iteration of the mandelbrot set if |z| =2 then z is not a member of a mandelset} while (((z1*z1 + z2*z2 tmp:=z1; z1:= z1*z1 - z2*z2 + c1; z2:= 2*tmp*z2+c2; inc(count); end; //the color-palette depends on TColor(n*count mod t) cFrm.Canvas.pen.Color:= (16*count mod 255); cFrm.Canvas.DrawPoint(j,i); c1:=c1 + X; end; c2:= c2 + Y; end; end; The different colors depends on the count which tells us the set of mandelbrot, those are different sets in and out so are different colors. You call the unit simply by: with TChaosBase(TModelMandelbrot.create) do begin setup(frmChaos); //aForm has to be set Free; end; All models inherit from a baseclass: TChaosBase = class private cFrm: TForm; public scaleX1: double; scaleX2: double; scaleY1: double; scaleY2: double; procedure setup(vform: TForm); virtual; abstract; procedure scaleResults(const X, Y: double; var intX, intY: integer; width, height: integer); end; Thus, fractals graphically portray the notion of "worlds within worlds" which has obsessed Western culture from its tenth-century beginnings. I hope you enjoy the magic world of fractals and maybe you earn some money on the stock-exchanges too, cause they belong to the same chaos-theorie... Zooming isn't as simple as it seems, cause zooming of fractals is dependent on iterations not on graphic scales like form.widht/range or so on. the steps are as follow: 1. enlarge the picture with an increase of iterations cFrm:= vForm; X1:=20; X2:=trunc(cFrm.ClientWidth * zoomfact); ..... 2. compute the enlargment for i:= 10 to X2 do begin c1:= au; for j:= 0 to Y2 do begin ....... 3. copy the section as you wish either by mouse or by position cFrm.Canvas.CopyRect(cfrm.Canvas.ClipRect, cFrm.Canvas, SourceRect); the point is the enlargment, cause it takes time to deepen the fractal and my solution isn't efficient enough, cause it draws the fractal and then grabs the clipping area, better is to define a structure or collection, fill the data in an two dimensional array and then set the area to draw. AppRect:= Rect(cfrm.Left, cfrm.Top, cfrm.Left+ cfrm.Width, cfrm.Top+ cfrm.Height); GetCursorPos(Point); //Check If The Mouse Pointer Is Outside Of The Mainform. //If not PtInRect(AppRect,Point) Then pointTL.X:= trunc((cfrm.Width - basew + 066) * zoomfact); pointTL.Y:= trunc((cfrm.height - baseh + 140) * zoomfact); pointBR.X:= trunc((cfrm.width + 266) * zoomfact); pointBR.Y:= trunc((cfrm.height + 233) * zoomfact); SourceRect:= Rect(pointTL.x, pointTL.Y, pointBR.X, pointBR.Y); cFrm.Canvas.CopyRect(cfrm.Canvas.ClipRect, cFrm.Canvas, SourceRect); //InflateRect(sourceRect,Round(cfrm.Width/40),Round(cfrm.Height/40));