1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
############################################################################
#
# File: mandel2.icn
#
# Subject: Program to draw the Mandelbrot set
#
# Author: Roger Hare
#
# Date: June 17, 1994
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# This program draws portions of the Mandelbrot set according to the values
# input # on the command line. The method is that described in the articles by
# Dewdney # in the Computer Recreations column of Scientific American in August
# '85, # October '87 and February '89.
#
# I have problems with colours (not enough of 'em!), so I have used alternated
# black and white. Those with decent X-terminals will be able to do far
# better than me.
#
# The program certainly doesn't display images as striking as those seen
# in publications. Perhaps the scaling of the value of k needs to be
# different? All suggestions gratefully received.
#
# It is possible to speed things up by displaying the points row by row
# rather than randomly, but as the program is resident in the 100 cycle
# iteration most of the time, this is only ~5% speed-up. Not really
# worth it.
#
# One of Dewdney's articles mentions other methods to speed things up - I
# will search out the algorithms one of these days...
#
# Usage is - xmand startr startc size n &
#
# where:
#
# startr, startc are the co-ordinates of the lower left hand corner of the
# area of the complex plane to be displayed
# size is the size of the (square) area of the complex plane to be displayed
# n is the number of pixels into which size is to be divided for display
# purposes
#
# For example - xmand -1.5 -1.25 2.5 400 &
#
# will display the Mandelbrot set in the 2.5x2.5 region of the complex plane
# whose s-w corner is -1.5-i1.25. The display will be 400x400 pixels.
#
# The program has been tested on a Sun 4 using the Icon compiler, and
# on a Sequent Symmetry running Version 5 Unix using both the
# compiler and translator.
#
############################################################################
#
# Links: random, wopen
#
############################################################################
#
# Requires: Version 9 graphics
#
############################################################################
link random
link wopen
procedure main(args)
local a, b, c, colours, coords, events, gap, i, k, n, r, size
local startc, startr, t, x, xmand, y
# check the number of arguments - if it's not 4, select 4 arbitrary values
if *args == 4
then {startr:=args[1]
startc:=args[2]
size:=args[3]
n:=args[4]
n:=integer(n)}
else {startr:=-1.5
startc:=-1.25
size:=2.5
n:=200}
# set max size to 400
if (n>400) then n:=400
# calculate 'size' of each pixel
gap:=size/n
# open window
xmand:=WOpen("label=xmand", "height="||n+40,
"width="||n+40) | stop("Can't open xmand")
# set colours to be 5 cycles of alternating black & white - this for the
# benefit of those with monochrome screens, or (like me!), a crummy palette.
colours:=["black","white"]
colours:=colours|||colours|||colours|||colours|||colours
# write image info in window
GotoXY(xmand,20,35+n)
writes(xmand,startr," ",startc," ",size," ",n)
# this bit coupled with counting y *downwards* later, effectively means that
# the image in the X-window is 'right way up' for those who live in a
# cartesian world.
startc+:=size
# set up co-ordinates, one for every point in the display and randomize
coords:=list(n*n,0)
every i:=1 to n*n
do coords[i]:=i-1
randomize()
every !coords:=:?coords
# main loop
every i := 1 to n*n
do {t:=get(coords)
# compute random x,y value from co-ordinate
x:=(t/n)
y:=(t%n)
# compute value of this x,y point in complex plane - count downwards in
# y direction to get image 'right way up'
r:=startr+x*gap
c:=startc-y*gap
a:=0
b:=0
# and calculate if point is in set or not
every k:=1 to 100
do {t:=a*a-b*b+r
b:=2*a*b+c
a:=t
if (a*a+b*b) > 4.0 then break}
# scale final value of k to one of range of colours
# subtract 1 to put in range 0->99; divide by 10 to put in range 0->9
# add 1 to put in range 1->10 - I have 10 'colours' selected
# this scaling gives fairly unexciting displays, is there a better scaling
# (eg: logarithmic, square root, w.h.y)?
k-:=1
k/:=10
k+:=1
# and display
Fg(xmand,colours[k])
DrawPoint(xmand,(x+20),(y+20))
# this bit bales out of loop if left button is pressed
if (events:=Pending(xmand)) & (*events > 0)
then if Event(xmand)==&lpress
then break}
WFlush(xmand)
# just close the window and exit when it is finished
Event(xmand)
end
|