Fractals by The Wendigo16th Nov 2004 20:28
|
---|
Summary Create fractals for your projects. Description Fractals are beautiful, mathmatical graphs that have captured our eyes for decades. You may have seen many fractals on screensavers and for wallpaper. You may have even played a game on one and didn't even know it! That's right, fractals are present more than you might think. Fractals can be used for random terrain generation, folliage and random decor, and even galaxies to name a few. I hope this code will benefit you and your projects as they are mine. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com Rem Project: Mandelbrot Rem Created: 11/16/2004 3:00:56 PM Rem The Mandelbrot set is a very interresting fractal. There are many different fractals Rem available, but this is one is one of the most commonly seen. You may have seen it Rem in wallpapers, screensavers, and may have even seen parts of it (without even knowing) Rem as terrain. Rem This example will show you how the mandelbrot set can be created for your own DarkBasic Rem projects which can be used for a variety of different purposes including terrain generation, Rem galaxy making, or folliage plotting. #Constant FRACT_WIDTH = 512.0 #Constant FRACT_HEIGHT = 512.0 #Constant FRACT_ITERATIONS = 256 set text opaque Rem This is our main loop. Each fractal call will show a fractal image Rem at that given, X position, Y position, and Scale(inverse zoom) factor, respecitvely do Fractal(0,0,4) wait 5000 Fractal(-.371505859375, -.644072265625, .001) wait 5000 Fractal(.18359375, .5859375, .001) wait 5000 Fractal(.1843069296875,.586176051757813,.001) wait 5000 loop Function Fractal(PosX as float, PosY as float, Scale as float) perc as float Rem Scaled position dx as float dy as float px as float py as float Rem Scaler (modified a tad) nScale as float nScale = Scale / 2 Rem Scale the position (if you don't understand this, just ignore it for now) dx = ((PosX + nScale) - (PosX - nScale)) / FRACT_WIDTH dy = ((PosY + nScale) - (PosY - nScale)) / FRACT_HEIGHT Rem go through and plot some fractal pixels! for y = 0 to FRACT_HEIGHT - 1 Rem System stuff (Ignore) perc = (y / FRACT_HEIGHT) * 100 text 0, FRACT_HEIGHT, str$(int(perc)) + "%" sync if escapekey() then exitfunction Rem Now back to fractals for x = 0 to FRACT_WIDTH - 1 Rem Scale the pixel appropriately (this is Source plotting) px = x py = y px = (PosX-nScale) + px * dx py = (PosY-nScale) + py * dy Rem Plot the pixel! Rem NOTE: Obviously, using the DOT command could be opitmized. I'll leave that Rem to you Dot x, y, GetColor(MandelbrotPixel(px, py, FRACT_ITERATIONS)) next x next y EndFunction Function MandelbrotPixel(x as float, y as float, Iterations as integer) Rem Plotting a pixel is a little more complex than just plotting any Rem old pixel anywhere. A fractal is a graph of a Complex number, meaning Rem a number with a real part and an imaginary part (ie: A + Bi) Rem We will let A represent the real part of our number A as float Rem And B represent the imaginary part B as float Rem LastA is the last A position before we changed it LastA as float Rem Length is the distance from origin Length as float Rem Now step through a number of iterations and see if the numbers fly off into infinity i=0 A=0 B=0 for i = 0 to Iterations-1 Rem Now, The mandelbrot set is the function of NZ = Z*Z + C where NZ, Z and C are Rem complex numbers and C is a constant (meaning it wont change for this particular Rem iteration. Rem Z's parts will be A (real) and B (imaginary). and C is X (real) and Y (imaginary) Rem Therefore our equation will be: Rem (A + B)(A + B) + C Rem which turns into: A*A + 2*A*B + B*B + X + Y Rem now, the square root of -1 is i, therefore and imaginary number (i) squared Rem would be -1 by definition. That said, B*B is no longer imaginary. Therefore Rem B*B is now real and equal to -B*B. This is important, because we now need to Rem seperate the real and imaginary parts and graph real on X and imaginary on Y Rem our formula seperated into real and imaginary parts (also, remember the last A!) LastA = A A = A*A - B*B + X B = 2*LastA*B + Y Rem now, in order for us to figure out what value our pixel will be, we need to Rem figure out its distance from the origin. For a real number this is easy. It Rem would be ABS(number), but for complex numbers, it's a little different: Length = A*A + B*B Rem NOTE: normally we would grab the sqrt() of length now, but this is not necissary Rem here and would slow down the overall process. Rem Now, if Length is less than 4, it is within the Mandelbrot set. Otherwise, if Rem it passes 4, it will stretch out into infinity and will not lye within the set. if Length > 4 then exitfunction i next i Rem Bingo! We should now have a value... what is that value? Why, the number of iterations Rem ofcourse ;). Simply return the value of i. (NOTE: My method is inverse of a normal Mandelbrot) Rem Also, you can change RESULT to eqaul iterations - 1 and you will get the maximum color value Rem to color in your mandelbrot set. Heck, lets do that! `RESULT = i RESULT = iterations - 1 EndFunction RESULT Function GetColor(Value as integer) Rem This wraps the value to within 0-255 (provided Value isn't negative!) Rem This will make a firey Mandelbrot (fire! woohoo!) if Value <= 85 and Value >= 0 then Color = rgb(Value * 3, 0, 0) if Value <= 85+85 and Value > 85 then Color = rgb(255, Value * 3, 0) if Value <= 85+85+85 and Value > 85+85 then Color = rgb(255, 255, Value * 3) EndFunction Color |