globals [xmin xmax ymin ymax ;; frame bounds
worldscale ;; relative to patch grid
minesc maxesc] ;; for color normalization
patchesown [x y] ;; in the 'virtual' coordinate space
to startup reset end
;;;;;;;;;;; Command line user interface: ;;;;;;;;;;;;;
to where ;; location and scale
type (word ((xmax + xmin) / 2) " "
((ymax + ymin) / 2) " " worldscale "\n")
end
to goto [x' y' scale]
let h worldwidth / (2 * scale) ;; half virtual display width
let ar worldwidth / worldheight ;; aspect ratio
set xmin x'  h set xmax x' + h
set ymin y'  h * ar set ymax y' + h * ar
set worldscale scale
render
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
to reset
clearall set zoomscale 2
crt 1 [set color [255 0 0 128] set shape "frame"
set size worldwidth / zoomscale hideturtle]
goto 0.5 0 (worldwidth / 4) ;; frame the whole Mandelbrot set
end
to setzoomfocus
ask turtle 0
[showturtle set size worldwidth / zoomscale
if mouseinside? and mousedown?
[setxy mousexcor mouseycor]]
display ask turtle 0 [hideturtle]
end
to zoomin zoom zoomscale end
to zoomout zoom 1 / zoomscale end
to zoom [proportion]
goto ([x] of turtle 0) ([y] of turtle 0) (worldscale * proportion)
end
to render
resetticks resettimer
ask patches ;; update virtual coordinates
[set x pxcor / worldscale + (xmin + xmax) / 2
set y pycor / worldscale + (ymin + ymax) / 2]
nodisplay ask patches [set pcolor white] display
set minesc n set maxesc 1 ask patches [iterate]
ask patches with [pcolor != black] [recolor]
display tickadvance timer ;; show how long the rendering took
end
to iterate ;; find the escape value for a single pixelpatch
let x' x let y' y ;; tick notation means "next"
let x'^2 x * x let y'^2 y * y ;; calculate these only once!
let x'' 0 let esc 0
if worldscale < 25000 ;; optimization probably useless at deep zoom
[let q (x  0.25) ^ 2 + y'^2 ;; shortcut check for pixels
if ((x + 1) ^ 2 + y'^2 < 0.0625) or ;; in the periodtwo bulb or
(q * (q + x  0.25) < y'^2 * 0.25) ;; the main cardioid shape
[set pcolor black stop]]
while [esc < n and x'^2 + y'^2 < 4] ;; the main loop:
[set x'' x + x'^2  y'^2 ;; z' < z'^2 + z
set y' y + 2 * x' * y' ;; for complex number z = x + yi
set x' x'' set esc esc + 1
set x'^2 x' * x' set y'^2 y' * y']
if (esc = n) [set pcolor black stop] ;; no escape: presumed in the set
set esc esc  (log ln sqrt (x'^2 + y'^2) 2) ;; use smooth interpolation otherwise
if esc < minesc [set minesc floor esc] ;; find the visible value range,
if esc > maxesc [set maxesc ceiling esc] ;; for recoloring later
set pcolor 98 + esc / n ;; meanwhile, color it pale blue
end
to recolor ;; use entire available gradient range in each picture
set pcolor skyellow ((n * (pcolor  98)  minesc) / (maxesc  minesc))
end
toreport skyellow [s] ;; number in [0,1] > gradient from sky to yellow
report ifelsevalue (s < 0.333) [95 + 14.7 * s] [49.9  14.8 * (s  0.333)]
end
@#$#@#$#@
GRAPHICSWINDOW
164
10
655
402
240
180
1.0
1
10
1
1
1
0
0
0
1
240
240
180
180
0
0
1
seconds to render
30.0
MONITOR
12
37
155
82
mouse location (x + yi)
ifelsevalue mouseinside?\n[[(word precision x 5 \" + \" precision y 5 \"i\")]\n of patch mousexcor mouseycor]\n[\"\"]
17
1
11
BUTTON
12
230
154
263
NIL
setzoomfocus
T
1
T
OBSERVER
NIL
Z
NIL
NIL
1
BUTTON
12
368
154
401
NIL
reset
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
SLIDER
12
290
154
323
zoomscale
zoomscale
1
25
2
0.01
1
X
HORIZONTAL
BUTTON
89
327
154
364
NIL
zoomin
NIL
1
T
OBSERVER
NIL
=
NIL
NIL
1
BUTTON
12
327
84
364
NIL
zoomout
NIL
1
T
OBSERVER
NIL

NIL
NIL
1
SLIDER
12
140
155
173
N
N
0
1000
50
1
1
iterations
HORIZONTAL
TEXTBOX
15
177
155
218
higher N means slower rendering of a more accurate approximation
11
5.0
1
MONITOR
12
85
155
130
scale
word precision (worldscale * 4 / worldwidth) 1 \" : 1\"
0
1
11
TEXTBOX
16
265
153
283
drag frame with mouse
11
5.0
1
TEXTBOX
13
10
155
32
Mandelbrot Set
18
0.0
1
@#$#@#$#@
## The Mandelbrot set
... or rather, an interactive zooming approximation to it.
(The Mandelbrot set is a set of complex numbers which is famous for its infinitely writhing selfsimilar shape when viewed as points on a plane. It was invented by Benoît Mandelbrot in 1979 at IBM Research, as part of his development of "fractal geometry".)
## What's going on here?
Complex numbers have the form _z_ = _x_ + _yi_, where _x_ and _y_ are real numbers and the imaginary number _i_ is the square root of 1. (The terminology is a little silly: socalled "real" numbers are just as madeup as "imaginary" ones, and vice versa!) Every real number is a legitimate complex number too  one whose _y_ part is zero. Addition and multiplication of complex numbers are defined in a way that extends and preserves these familiar operations on real numbers, as well as the definition _i_ ^{2} = 1. We also define the absolute value or _magnitude_ of a complex number as its distance from the _origin_ 0:
> For two complex numbers _z_ = _x_ + _yi_ and _z'_ = _x'_ + _y'i_,
> the **sum** _z_ + _z'_ = (_x_ + _x'_) + (_y_ + _y'_)_i_,
> the **product** _zz'_ = (_xx'_  _yy'_) + (_x'y_ + _xy'_), and
> the **magnitude** _z_ = √(_x_^{2} + _y_^{2}), a real number.
Now, for each complex number _z_, we can define an _infinite sequence_:
> The **initial** term _z__{0} = _z_, and **successive** terms _z__{n + 1} = _z__{n}^{2} + _z_
The numbers in the Mandelbrot set are those _z_ for which this sequence remains _bounded_: that is to say, _z__{n} is small for _all_ positive integers _n_. Because numbers with magnitude greater than 2 always generate sequences which grow without bound, the entire set is contained within the radiustwo circle centered at the origin. However, there are also plenty of numbers with magnitudes less than 2 whose sequences "escape to infinity".
We can't calculate every term in these sequences, but we can go as far as _z__{_N_}, for a sufficiently large integer _N_. A pixel located at _z_, for which the first _N_ terms of its associated sequence _z__{0}, _z__{1}, _z__{2}, ... all have magnitudes less than 2, gets colored black in the picture. Any other pixels get colored along a gradient from sky blue through white to yellow, depending on how many consecutive terms in their sequences have magnitudes less than 2.
## How to use this model
The monitors labelled **mouse location** and **scale** show the complex number directly beneath the mouse pointer, and the zoom level of the whole picture relative to the initial view of the entire set.
The **slider** parameter _N_ determines how many terms of the sequence to calculate and check, for each pixel in the picture. Naturally, higher_N_ pictures take longer to make. When visualizing the Mandelbrot set, there's no point in making _N_ too big, because we'll end up calculating details below pixel scale which are effectively invisible. Generally speaking, you'll want to set _N_ just high enough so that you see a moderate amount of yellow fringe or glow around the black regions which define the set. Exactly how high that is will depend on what you're looking at, and at what scale. It's also quite interesting to watch the set "develop", by calculating successive values of _N_ for a single viewpoint.
The **setzoomfocus** button, when active, lets you move a red zoom frame around the picture by clicking or dragging. The **zoomscale** slider changes the size of the frame. Clicking **zoomout** makes a new view which fits the entire current picture into the zoom frame. Similarly, clicking **zoomin** makes a new fullsized view of just the region within the frame. In case you get lost, the **reset** button returns to the initial view at 1:1 scale.
If you want bigger pictures, and are willing to wait for the correspondingly longer render times, just change the "world size" by clicking the **Settings...** button in the toolbar. The zoom frame is shaped for a picture with an aspect ratio of 4:3 (that is, four pixels wide for every three pixels tall) but other aspect ratios should also work. The patch size should remain one pixel wide.
Just three numbers  the real and imaginary coordinates and zoom depth  are sufficient to reconstitute any picture made by this model. To print these three numbers in the Command Center, just type `where`. To go directly to any such specified location, use the `goto` command followed by the three numbers.
## How it works
This NetLogo implementation has a few features which deserve some explanation. First, the view frame in the coordinate system of the complex plane is dynamically translated to the fixed patch grid: every pixelsized patch has `x` and `y` variables which determine the patch's color, and which are reset during zooming. The `iterate` procedure, which runs many thousands of times to generate a single picture, is written to do as few arithmetic operations as possible, storing intermediate values in temporary variables. The two largest regions of the Mandelbrot set which have regular shapes  the central _cardioid_ and the circular "bulb" immediately to its left  are checked for as special cases, which can save some rendering time for views which include these regions. However, the deeper the zoom level, the less likely it is that you'll be looking at the interior of these regions, rather than the intricate fringe around them. Since the precheck itself costs some time, it's disabled for zoom levels above a fixed threshold.
Once an integer "escape value" `esc` < _N_ is calculated by `iterate`, we use a smoothing doublelogarithm interpolation formula to convert it to an appropriate fractional value. This gives us a continuous range of colors to work with, and reduces colorbanding artifacts. The highest and lowest such values for the whole picture are tracked, so that the entire range of color is used for each finished picture. By fading the highest escape values from yellow to black, we prevent some aliasing artifacts in the finished picture  and visually denote the relative uncertainly of the edge of the black region, which is always an _over_estimate of the "real" Mandelbrot set. Finally, we use the `timer` reporter to keep track of how long the entire rendering process takes, and display it in place of `ticks`.
## Due credit
Developed in February 2013 by Max Orhai for the Santa Fe Institute's Complexity Explorer website, under the direction of Melanie Mitchell.
For more about fractal geometry and the Mandelbrot set, see Benoît Mandelbrot's 1982 book _The Fractal Geomety of Nature_, published by W.H. Freeman and Co.
The doublelogarithm color smoothing technique is due to Linas Vepstas in 1997:
http://linas.org/artgallery/escape/escape.html
NetLogo is Copyright 2005 by Uri Wilensky and the Center for Connected Learning and ComputerBased Modeling, Northwestern University, Evanston, IL.
@#$#@#$#@
default
true
0
Polygon 7500403 true true 150 5 40 250 150 205 260 250
circle
false
0
Circle 7500403 true true 0 0 300
circle 2
false
0
Circle 7500403 true true 0 0 300
Circle 16777216 true false 30 30 240
frame
false
0
Rectangle 7500403 false true 0 38 299 263
square
false
0
Rectangle 7500403 true true 30 30 270 270
square 2
false
0
Rectangle 7500403 true true 30 30 270 270
Rectangle 16777216 true false 60 60 240 240
@#$#@#$#@
NetLogo 5.0.3
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
default
0.0
0.2 0 1.0 0.0
0.0 1 1.0 0.0
0.2 0 1.0 0.0
link direction
true
0
Line 7500403 true 150 150 90 180
Line 7500403 true 150 150 210 180
@#$#@#$#@
0
@#$#@#$#@