File : mandel.sp


[Mandelbrot Set image]

#!/usr/local/bin/spar

pragma annotate( summary, "mandel" )
       @( description, "Create a color image of the Mandelbrot set" )
       @( author, "Ken O. Burtch" );
pragma license( unrestricted );

pragma restriction( no_external_commands );

procedure mandel is

  mandel_limit : constant long_float := 4.0;       -- reach this? it's the set
  max_iterations : constant integer := 128;        -- quit if looped this amt

  center_r : constant long_float := -0.75;         -- center of set (x=real)
  center_i : constant long_float := 0.0;           -- center of set (i=imag.)

  c_r : long_float;                                -- current point (x=real)
  c_i : long_float;                                -- current point (i=imag.)

  loop_count : integer;                            -- number of iterations

  z_r  : long_float;                               -- mandelbot set formula
  z_i  : long_float;                               -- variables
  z_r2 : long_float;
  z_i2 : long_float;

  c    : pen.canvas_id;                            -- bush drawing canvas
  plot : pen.rect;                                 -- rectangle to draw with
  s    : string;

  bits : integer;                                  -- for determining color
  red  : pen.rgbcomponent;
  green: pen.rgbcomponent;
  blue : pen.rgbcomponent;
begin

  -- create the drawing canvas

  pen.new_window_canvas( 200, 200, 32, c );
  pen.set_title( c, "Mandelbrot" );

  -- loop for the size of the canvas (-50% to +50%)

  for i in -50..50 loop
      c_i := center_i - long_float(i)*0.025;
      pen.wait_to_reveal( c );
      for r in -50..50 loop
          c_r := center_r - long_float(r)*0.025;

      -- Evaluatuate how close point (c_z, c_i ) in complex number space
      -- is to the Mandelbrot set.  Return a number between 0 and
      -- max_iterations.  A value of max_iterations implies that the point
      -- is probably a member of the Mandelbrot set.

         z_r := c_r;
         z_i := c_i;
         loop_count := 1;
         loop
            z_i2 := z_i*z_i;
            z_r2 := z_r*z_r;
            z_i := 2.0 * z_r * z_i + c_i;
            z_r := z_r2 - z_i2 + c_r;
            loop_count := @+1;
            exit when not ( (z_r2 + z_i2 < mandel_limit) and (loop_count /= max_iterations) );
         end loop;

         -- pick a color based on loop_count (mandelbrot set is black)

         if loop_count = max_iterations then
            red := 0.0;
            green := 0.0;
            blue := 0.0;
         else
            bits := (loop_count and 3 );
            red := 100.0-pen.rgbcomponent((100*bits/3));
            bits := (loop_count / 3 ) and 3;
            green := 100.0-pen.rgbcomponent((100*bits/3));
            bits := (loop_count / 27 ) and 2;
            blue := 100.0-pen.rgbcomponent((100*bits)/2);
         end if;
         pen.set_pen_ink( c, red, green, blue );

         -- Draw the point, reversing the X axis

         pen.set_rect( plot, 100-(r+50),i+50, 100-(r+49), i+51 );
         pen.paint_rect( c, plot );
      end loop;
      pen.reveal( c );
  end loop;

  ? "Press return";
  s := get_line;

end mandel;

-- VIM editor formatting instructions
-- vim: ft=spar