// mj-fractal.rtb // Adapted from many sources // But thanks to Lode Vandevenne and his work at http://lodev.org/ // // Gordon Henderson, 2016 // Colour lookup tables dim rc (2048), gc (2048), bc (2048) cls print print " The Mandelbrot and Julia Sets" print " =============================" print print " Use the arrow keys to move round, the + key to" print " zoom in and the - key to zoom out." print print " The * key will increase the resolution and / will" print " decrease it." print print " L takes you to low-resolution and H to high resolution" print " graphics. It's faster in low-res, then you can switch to" print " high resolution for a nice image." print print " To start again, press the Z key and the F key will" print " toggle fast/slow drawing mode." print print " Press M for Mandelbrot, J for Julia ... "; cycle k$ = get$ repeat until k$ = "m" or k$ = "j" doJulia = k$ = "j" proc setup cycle start = TIME if doJulia then proc drawJulia (moveX, moveY, zoom, iterations) else proc drawMandelbrot (moveX, moveY, zoom, iterations) endif frameTime = TIME - start hvTab (0,0) numFormat (5, 3) print "T: "; frameTime / 1000 numFormat (0, 0) print "Z: "; zoom print "N: "; iterations // if fast then // print "Fast" // else // print "Slow" // endif print "x: "; moveX print "y: "; moveY print "-> "; k = get if k = asc ("f") then fast = not fast if k = keyRight then moveX = moveX - (0.5 / zoom) if k = keyLeft then moveX = moveX + (0.5 / zoom) if k = keyUp then moveY = moveY - (0.5 / zoom) if k = keyDown then moveY = moveY + (0.5 / zoom) if k = asc ("+") then zoom = zoom * 2 if k = asc ("-") then zoom = zoom / 2 if k = asc ("*") then iterations = iterations * 2 if k = asc ("/") then iterations = iterations / 2 if k = asc ("z") then proc setup if k = asc ("l") then GR if k = asc ("h") then HGR if zoom < 1 then zoom = 1 if iterations > 2048 then iterations = 2048 if iterations < 8 then iterations = 8 hvTab (0,0) print "... Working "; space$ (20) repeat end // drawMandelbrot: //================================================================================ def proc drawMandelbrot (moveX, moveY, zoom, iterations) local pReal, pImag // Real & Imaginary parts of the pixel local newRe, newIm, oldRe, oldIm // Real and imaginary parts of new and old local h, w, h1, w1, h2, w2 local zoom5w, zoom5h local x, y proc setupColours (iterations) h = gHeight w = gWidth h2 = h / 2 w2 = w / 2 h1 = h - 1 w1 = w - 1 zoom5w = 0.5 * zoom * w zoom5h = 0.5 * zoom * h //draw the fractal for y = 0 to h1 cycle for x = 0 to w1 cycle // calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values pReal = 1.5 * (x - w2) / zoom5w + moveX pImag = (y - h2) / zoom5h + moveY newRe = 0 newIm = 0 oldRe = 0 oldIm = 0 oldRe2 = 0 oldIm2 = 0 // iterate for i = 0 to iterations - 1 cycle newRe = oldRe2 - oldIm2 + pReal newIm = 2 * oldRe * oldIm + pImag // we're done when the point is outside the circle with radius 2 oldRe2 = newRe * newRe oldIm2 = newIm * newIm if (oldRe2 + oldIm2) > 4 then break oldRe = newRe oldIm = newIm repeat if i = iterations - 1 then colour = 0 else rgbColour (rc (i), gc (i), bc (i)) endif plot (x, y) repeat if not fast then update repeat endproc // drawJulia //================================================================================ def proc drawJulia (moveX, moveY, zoom, iterations) local pReal, pImag // Real & Imaginary parts of the pixel local newRe, newIm, oldRe, oldIm // Real and imaginary parts of new and old local h, w, h1, w1, h2, w2 local zoom5w, zoom5h local x, y proc setupColours (iterations) h = gHeight w = gWidth h2 = h / 2 w2 = w / 2 h1 = h - 1 w1 = w - 1 zoom5w = 0.5 * zoom * w zoom5h = 0.5 * zoom * h //draw the fractal for y = 0 to h1 cycle for x = 0 to w1 cycle // calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values oldRe = 1.5 * (x - w2) / (zoom5w) + moveX oldIm = (y - h2) / (zoom5h) + moveY oldRe2 = oldRe * oldRe oldIm2 = oldIm * oldIm // iterate for i = 0 to iterations - 1 cycle newRe = oldRe2 - oldIm2 + cRe newIm = 2 * oldRe * oldIm + cIm oldRe2 = newRe * newRe oldIm2 = newIm * newIm // we're done when the point is outside the circle with radius 2 if (oldRe2 + oldIm2) > 4 then break oldRe = newRe oldIm = newIm repeat if i = iterations - 1 then colour = 0 else rgbColour (rc (i), gc (i), bc (i)) endif plot (x, y) repeat if not fast then update repeat endproc // setup: // Initialise variables to reasonable defaults //================================================================================ def proc setup fast = FALSE zoom = 1 iterations = 16 if doJulia then // Julia definitions cRe = -0.7 cIm = 0.27015 moveX = 0 moveY = 0 else // Mandelbrot moveX = -0.5 moveY = 0 endif endproc // setupColours: // Compute a nice sort of rainbow colour pallette //================================================================================ def proc setupColours (iterations) local i local r, g, b, h, f, q for stp = 0 to iterations - 1 cycle r = 0 g = 0 b = 0 h = stp / iterations i = int (h * 6) f = h * 6 - i q = 1 - f switch (i mod 6) case 0 r = 1 g = f b = 0 endcase case 1 r = q g = 1 b = 0 endcase case 2 r = 0 g = 1 b = f endcase case 3 r = 0 g = q b = 1 endcase case 4 r = f g = 0 b = 1 endcase case 5 r = 1 g = 0 b = q endcase endswitch rc (stp) = r * 255 gc (stp) = g * 255 bc (stp) = b * 255 repeat // test // for x = 0 to gWidth - 1 cycle // rgbColour (rc (x), gc (x), bc (x)) // line (x,8, x,200) // //rect (x * 8, 12, 8, 200, 1) // repeat // update // hvtab (0,0) endproc