Mandelbrot set: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
Line 175: Line 175:


=={{header|haXe}}==
=={{header|haXe}}==
This version compiles for flash version 9 or grater.
The compilation command is
<lang>haxe -swf9 mandelbrot.swf -main Mandelbrot</lang>

<lang haxe>
class Mandelbrot extends flash.display.Sprite
{
inline static var MAX_ITER = 255;

public static function main() {
var w = flash.Lib.current.stage.stageWidth;
var h = flash.Lib.current.stage.stageHeight;
var mandelbrot = new Mandelbrot(w, h);
flash.Lib.current.stage.addChild(mandelbrot);
mandelbrot.drawMandelbrot();
}

var image:flash.display.BitmapData;
public function new(width, height) {
super();
var bitmap:flash.display.Bitmap;
image = new flash.display.BitmapData(width, height, false);
bitmap = new flash.display.Bitmap(image);
this.addChild(bitmap);
}

public function drawMandelbrot() {
image.lock();
var step_x = 3.0 / (image.width-1);
var step_y = 2.0 / (image.height-1);
for (i in 0...image.height) {
var ci = i * step_y - 1.0;
for (j in 0...image.width) {
var k = 0;
var zr = 0.0;
var zi = 0.0;
var cr = j * step_x - 2.0;
while (k <= MAX_ITER && (zr*zr + zi*zi) <= 4) {
var temp = zr*zr - zi*zi + cr;
zi = 2*zr*zi + ci;
zr = temp;
k ++;
}
paint(j, i, k);
}
}
image.unlock();
}

inline function paint(x, y, iter) {
var color = iter > MAX_ITER? 0 : iter * 0x100;
image.setPixel(x, y, color);
}
}
</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==

Revision as of 04:10, 7 August 2009

This page uses content from Wikipedia. The original article was at Mandelbrot_set. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)
Task
Mandelbrot set
You are encouraged to solve this task according to the task description, using any language you may know.

Generate and draw the Mandelbrot set.

C

This code uses functions from category Raster graphics operations.

<lang c>#include <stdio.h>

  1. include "imglib.h"
  1. define MAX_ITERATIONS 500

void draw_mandel(image img){

 unsigned int x, y;
 unsigned int width, height;
 color_component colour;
 double x0, y0, xtemp, cr, ci;
 unsigned int i;

 width = img->width;
 height = img->height;
 for (x = 0; x < width; x++) {
   for (y = 0; y < height; y++) {
     x0 = y0 = 0;
     cr = ((double)x / (double)width - 0.5);
     ci = ((double)y / (double)height - 0.5);
     i = 0;

     while (((x0*x0 + y0*y0) <= 4.0) && (i < MAX_ITERATIONS)){
       xtemp = x0*x0 - y0*y0 + cr;
       y0 = 2*x0*y0 + ci;
       x0 = xtemp;
       i++;
     }

     /* points in the set are coloured as white, others are coloured black. */
     colour = (i == MAX_ITERATIONS ? 255 : 0);

     put_pixel_clip(img, x, y, colour, colour, colour);
   }
 }

}

  1. define W 640
  2. define H 480

int main() {

 image img;
 FILE *o;
 img = alloc_img(W, H);
 draw_mandel(img);
 o = fopen("mandel.ppm", "w");
 output_ppm(o, img);
 fclose(o);
 free_img(img);

}</lang>

C++

This generic function assumes that the image can be accessed like a two-dimensional array of colors. It may be passed a true array (in which case the Mandelbrot set will simply be drawn into that array, which then might be saved as image file), or a class which maps the subscript operator to the pixel drawing routine of some graphics library. In the latter case, there must be functions get_first_dimension and get_second_dimension defined for that type, to be found by argument dependent lookup. The code provides those functions for built-in arrays. <lang cpp>

  1. include <cstdlib>
  2. include <complex>

// get dimensions for arrays template<typename ElementType, std::size_t dim1, std::size_t dim2>

std::size_t get_first_dimension(ElementType (&a)[dim1][dim2])

{

 return dim1;

}

template<typename ElementType, std::size_t dim1, std::size_t dim2>

std::size_t get_second_dimension(ElementType (&a)[dim1][dim2])

{

 return dim2;

}


template<typename ColorType, typename ImageType>

void draw_Mandelbrot(ImageType& image,                                       // where to draw the image
                     ColorType set_color, ColorType non_set_color,           // which colors to use for set/non-set points
                     double cxmin, double cxmax, double cymin, double cymax,  // the rectangle to draw in the complex plane
                     unsigned int max_iterations)                            // the maximum number of iterations

{

 std::size_t const ixsize = get_first_dimension(ImageType);
 std::size_t const iysize = get_first_dimension(ImageType);
 for (std::size_t ix = 0; ix < ixsize; ++ix)
   for (std::size_t iy = 0; iy < iysize; ++iy)
   {
     std::complex c(cxmin + ix/(ixsize-1.0)*(cxmax-cxmin), cymin + iy/(iysize-1.0)*(cymax-cymin));
     std::complex z = 0;
     unsigned int iterations = 0;
     while (iterations < max_iterations && std::norm(z) < 4.0) // note: std::norm(z) gives the *squared* absolute value of z
     {
       z = z*z + c;
       ++iterations;
     }
     if (iterations == max_iterations)
       image[ix][iy] = set_color;
     else
       image[ix][iy] = non_set_color;
   }

} </lang>

D

Library: qd

using

Library: SDL
Library: Phobos

<lang D> module mandelbrot;

import qd;

double lensqr(cdouble c) { return c.re * c.re + c.im * c.im; }

const Limit = 150;

void main() {

 screen(640, 480);
 for (int y = 0; y < screen.h; ++y) {
   flip; events;
   for (int x = 0; x < screen.w; ++x) {
     auto
       c_x = x * 1.0 / screen.w - 0.5,
       c_y = y * 1.0 / screen.h - 0.5,
       c = c_y * 2.0i + c_x * 3.0 - 1.0,
       z = 0.0i + 0.0,
       i = 0;
     for (; i < Limit; ++i) {
       z = z * z + c;
       if (lensqr(z) > 4) break;
     }
     auto value = cast(ubyte) (i * 255.0 / Limit);
     pset(x, y, rgb(value, value, value));
   }
 }
 while (true) { flip; events; }

} </lang>

Forth

This uses grayscale image utilities. <lang Forth>500 value max-iter

mandel ( gmp F: imin imax rmin rmax -- )
 0e 0e { F: imin F: imax F: rmin F: rmax F: Zr F: Zi }
 dup bheight 0 do
   i s>f dup bheight s>f f/ imax imin f- f* imin f+ TO Zi
   dup bwidth 0 do
     i s>f dup bwidth s>f f/ rmax rmin f- f* rmin f+ TO Zr
     Zr Zi max-iter
     begin  1- dup
     while  fover fdup f* fover fdup f*
            fover fover f+ 4e f<
     while  f- Zr f+
            frot frot f* 2e f* Zi f+
     repeat fdrop fdrop
            drop 0        \ for a pretty grayscale image, replace with: 255 max-iter */
     else   drop 255
     then   fdrop fdrop
     over i j rot g!
   loop
 loop    drop ;

80 24 graymap dup -1e 1e -2e 1e mandel dup gshow free bye</lang>

haXe

This version compiles for flash version 9 or grater. The compilation command is <lang>haxe -swf9 mandelbrot.swf -main Mandelbrot</lang>

<lang haxe> class Mandelbrot extends flash.display.Sprite {

   inline static var MAX_ITER = 255;
   public static function main() {
       var w = flash.Lib.current.stage.stageWidth;
       var h = flash.Lib.current.stage.stageHeight;
       var mandelbrot = new Mandelbrot(w, h);
       flash.Lib.current.stage.addChild(mandelbrot);
       mandelbrot.drawMandelbrot();
   }
   var image:flash.display.BitmapData;
   public function new(width, height) {
       super();
       var bitmap:flash.display.Bitmap;
       image = new flash.display.BitmapData(width, height, false);
       bitmap = new flash.display.Bitmap(image);
       this.addChild(bitmap);
   }
   public function drawMandelbrot() {
       image.lock();
       var step_x = 3.0 / (image.width-1);
       var step_y = 2.0 / (image.height-1);
       for (i in 0...image.height) {
           var ci = i * step_y - 1.0;
           for (j in 0...image.width) {
               var k = 0;
               var zr = 0.0;
               var zi = 0.0;
               var cr = j * step_x - 2.0;
               while (k <= MAX_ITER && (zr*zr + zi*zi) <= 4) {
                   var temp = zr*zr - zi*zi + cr;
                   zi = 2*zr*zi + ci;
                   zr = temp;
                   k ++;
               }
               paint(j, i, k);
           }
       }
       image.unlock();
   }
   inline function paint(x, y, iter) {
       var color = iter > MAX_ITER? 0 : iter * 0x100;
       image.setPixel(x, y, color);
   }

} </lang>

OCaml

<lang OCaml> #load "graphics.cma"

open Graphics;;

let mandelbrot xMin xMax yMin yMax xPixels yPixels maxIter =

 let rec mandelbrotIterator z c n = 
   if (Complex.norm z) > 2.0 then false else
     match n with 
     |0 -> true
     |n -> let z' = Complex.add (Complex.mul z z) c in
        mandelbrotIterator z' c (n-1) in
 Graphics.open_graph 
   (" "^(string_of_int xPixels)^"x"^(string_of_int yPixels)^"+0-0");
 let dx = (xMax -. xMin) /. (float_of_int xPixels) in
 let dy = (yMax -. yMin) /. (float_of_int yPixels) in
 for xi = 0 to xPixels - 1 do
   for yi = 0 to yPixels - 1 do
     let c = {Complex.re = xMin +. (dx *. float_of_int xi); 
       Complex.im = yMin +. (dy *. float_of_int yi)} in
     if (mandelbrotIterator Complex.zero c maxIter) then
       (Graphics.set_color Graphics.white;
       Graphics.plot xi yi )
     else
       Graphics.set_color Graphics.black;
       Graphics.plot xi yi 
   done
 done;;
 

mandelbrot (-1.5) 0.5 (-1.0) 1.0 500 500 200;; </lang>

Octave

This code runs rather slowly and produces coloured Mandelbrot set by accident (output image here).

<lang octave>#! /usr/bin/octave -qf global width = 200; global height = 200; maxiter = 100;

z0 = 0; global cmax = 1 + i; global cmin = -2 - i;

function cs = pscale(c)

 global cmax;
 global cmin;
 global width;
 global height;
 persistent px = (real(cmax-cmin))/width;
 persistent py = (imag(cmax-cmin))/height;
 cs = real(cmin) + px*real(c) + i*(imag(cmin) + py*imag(c));

endfunction

ms = zeros(width, height); for x = 0:width-1

 for y = 0:height-1
   z0 = 0;
   c = pscale(x+y*i);
   for ic = 1:maxiter
     z1 = z0^2 + c;
     if ( abs(z1) > 2 ) break; endif
     z0 = z1;
   endfor
   ms(x+1, y+1) = ic/maxiter;
 endfor

endfor

saveimage("mandel.ppm", round(ms .* 255).', "ppm");</lang>

PostScript

<lang postscript>%!PS-Adobe-2.0 %%BoundingBox: 0 0 300 200 %%EndComments /origstate save def /ld {load def} bind def /m /moveto ld /g /setgray ld /dot { currentpoint 1 0 360 arc fill } bind def %%EndProlog % param /maxiter 200 def % complex manipulation /complex { 2 array astore } def /real { 0 get } def /imag { 1 get } def /cmul { /a exch def /b exch def

   a real b real mul
   a imag b imag mul sub
   a real b imag mul
   a imag b real mul add
   2 array astore

} def /cadd { aload pop 3 -1 roll aload pop

   3 -1 roll add
   3 1 roll add exch 2 array astore

} def /cconj { aload pop neg 2 array astore } def /cabs2 { dup cconj cmul 0 get} def % mandel 200 100 translate -200 1 100 { /x exch def

 -100 1 100 { /y exch def
   /z0 0.0 0.0 complex def
   0 1 maxiter { /iter exch def

x 100 div y 100 div complex z0 z0 cmul cadd dup /z0 exch def cabs2 4 gt {exit} if

   } for
   iter maxiter div g
   x y m dot
 } for

} for % showpage origstate restore %%EOF</lang>

R

<lang R>createmandel <- function(zfrom, zto, inc=0.01, maxiter=100) {

 x <- c()
 y <- c()
 cost <- zfrom
 while( Re(cost) <= Re(zto) ) {
   cost <- Re(cost) + Im(zfrom)*1i
   while ( Im(cost) <= Im(zto) ) {
     j <- 0
     z <- 0
     while( (abs(z) < 2) && (j < maxiter)) {
       z <- z^2 + cost
       j <- j + 1
     }
     if ( j == maxiter ) {
       x <- c(x, Re(cost))
       y <- c(y, Im(cost))
     }
     cost <- cost + inc*1i
   }
   cost <- cost + inc
 }
 plot(x,y, pch=".")

}

createmandel(-2-1i, 1+1i)</lang>

Tcl

Library: Tk

This code makes extensive use of Tk's built-in photo image system, which provides a 32-bit RGBA plotting surface that can be then quickly drawn in any number of places in the application. It uses a computational color scheme that was easy to code... <lang tcl>package require Tk

proc mandelIters {cx cy} {

   set x [set y 0.0]
   for {set count 0} {hypot($x,$y) < 2 && $count < 255} {incr count} {
       set x1 [expr {$x*$x - $y*$y + $cx}]
       set y1 [expr {2*$x*$y + $cy}]
       set x $x1; set y $y1
   }
   return $count

} proc mandelColor {iter} {

   set r [expr {16*($iter % 15)}]
   set g [expr {32*($iter % 7)}]
   set b [expr {8*($iter % 31)}]
   format "#%02x%02x%02x" $r $g $b

} image create photo mandel -width 300 -height 300

  1. Build picture in strips, updating as we go so we have "progress" monitoring
  2. Also set the cursor to tell the user to wait while we work.

pack [label .mandel -image mandel -cursor watch] update for {set x 0} {$x < 300} {incr x} {

   for {set y 0} {$y < 300} {incr y} {
       set i [mandelIters [expr {($x-220)/100.}] [expr {($y-150)/90.}]]
       mandel put [mandelColor $i] -to $x $y
   }
   update

} .mandel configure -cursor {}</lang>

XSLT

The fact that you can create an image of the Mandelbrot Set with XSLT is sometimes under-appreciated. However, it has been discussed extensively on the internet so is best not reproduced here, not when the code can be executed directly in your browser at that site.