ec2-3-15-211-107.us-east-2.compute.amazonaws.com | ToothyWiki | MandelbrotSet | RecentChanges | Login | Webcomic
%! Postscript code to draw the Mandelbrot Set.
% Shove this in a file called mandelbrot.ps or something,
% and use a postscript viewer like Ghostview.
% It takes a while.
% Adjustable stuff -----------------------------------------------------
/x_start -2 def % Initial x value (real part)
/y_start -2 def % Initial y value (imaginary)
/x_end 2 def % Final x value (real part)
/y_end 2 def % Final y value (imaginary)
/max 250 def % Maximum number of iterations
/quality 1.0 def % Rendering quality, 1.0 = 100% .. 0.5=50% .. 0.1 = 10%
% General procedures -----------------------------------------------------
/inch {72 mul} def
/minimum {% Return the lesser of two top stack values
/b exch def
/a exch def
a b le {a} {b} ifelse
} def
/maximum {% Return the greater of two top stack values
/b exch def
/a exch def
a b gt {a} {b} ifelse
} def
% Scaling things for the page
/page_width 8.5 inch def
/page_height 11 inch def
page_width 2 div page_height 2 div translate % Set origin at center of page
/x_domain x_end x_start sub def % Domain of x numbers
/x_range page_width .9 mul def % Horizontal space on page, w/ margins
/x_scale x_range x_domain div def % Maximum x scaling factor
/y_domain y_end y_start sub def % Domain of y numbers
/y_range page_height .9 mul def % Vertical space on page, w/ margins
/y_scale y_range y_domain div def % Maximum y scaling factor
/page_scale x_scale y_scale minimum def % Final scaling factor
page_scale dup scale % Set proper scale
x_domain 2 div x_start add neg % x distance from image center to origin
y_domain 2 div y_start add neg % y distance from image center to origin
translate % move origin so image is centered on page
/xstep x_domain x_range div quality div def
/ystep y_domain y_range div quality div def
/xsize xstep 1.5 mul def % x size of pixel
/ysize ystep 1.5 mul def % y size of pixel
/square {
dup mul
} bind def
/double {
dup add
} bind def
/box {% Draw filled rectangle, size slightly larger than w x h, with (x,y) at bottom left
% w h x y
2 index 2 div add % w h x (y+h/2)
moveto % w h
setlinewidth % w
0 rlineto stroke
} bind def
% Plot points in Mandelbrot set
x_end xstep x_start {
y_end ystep y_start {
% lx . . ly
max % lx . . ly count
4 index % lx . . ly count x
2 index % lx . . ly count x y
{
% args: x y
2 copy 2 copy % x y x y x y
sub % x y x y x-y
3 1 roll add % x y x-y x+y
mul % x y x*x-y*y
7 index add % x y x*x-y*y+x
3 1 roll mul double % x*x-y*y+x 2xy
3 index add % x' y'
2 copy 2 copy % x y x y x y
sub % x y x y x-y
3 1 roll add % x y x-y x+y
mul % x y x*x-y*y
7 index add % x y x*x-y*y+x
3 1 roll mul double % x*x-y*y+x 2xy
3 index add % x' y'
2 copy 2 copy % x y x y x y
sub % x y x y x-y
3 1 roll add % x y x-y x+y
mul % x y x*x-y*y
7 index add % x y x*x-y*y+x
3 1 roll mul double % x*x-y*y+x 2xy
3 index add % x' y'
% check exit condition
2 copy square % x y x y*y
exch square % x y y*y x*x
2 copy add 4 ge { % copy y*y+x*x and check if we can bail out
pop pop pop pop % kill locals
max div setgray % set colour
xsize ysize 5 index 3 index box
exit
} if
sub neg % x y x*x-y*y
7 index add % x y x*x-y*y+x
3 1 roll mul double % x*x-y*y+x 2xy
3 index add % x' y'
3 -1 roll % get counter
4 sub % update counter
dup 4 lt {
pop pop pop % kill locals
0 setgray % black
xsize ysize 5 index 3 index box
exit
} if
3 1 roll % put counter back
} loop
% end step val
1 index add % end step val'
dup 3 index % end step val' val' end
gt {exit} if % loop?
% end step val'
} loop pop pop pop
% end step val
1 index add % end step val+step
dup 3 index % end step val+step val+step end
gt {exit} if % loop?
% end step val'
} loop pop pop pop
showpage
% --------------8<-------------- cut here