11# Mandelbrot Set example
2- # by Jordan Scales (http://jordanscales.com)
3- # Modified to use map1d (instead of map), and somewhat
4- # optimized (update_pixels instead of set, and hypot for abs)
5- # no need to loop
2+ # after an original by Jordan Scales (http://jordanscales.com)
3+ # Modified to use simple_complex library, instead of a custom Complex also uses
4+ # map1d (instead of map), and a somewhat optimized (update_pixels instead of
5+ # set), and using grid, rather than nested loops
6+
7+ load_library :simple_complex
68
79def setup
810 sketch_title 'Mandelbrot'
@@ -12,69 +14,31 @@ def setup
1214
1315# main drawing method
1416def draw
15- ( 0 ...900 ) . each do |x |
16- ( 0 ...600 ) . each do |y |
17- c = Complex . new ( map1d ( x , ( 0 ...900 ) , ( -3 ..1.5 ) ) , map1d ( y , ( 0 ...600 ) , ( -1.5 ..1.5 ) ) )
18- # mandel will return 0 to 20 (20 is strong)
19- # map this to 0, 255 (and flip it)
20- pixels [ x + y * 900 ] = color ( 255 - map1d ( mandel ( c , 20 ) , ( 0 ..20 ) , ( 0 ..255 ) ) . to_i )
21- end
17+ grid ( 900 , 600 ) do |x , y |
18+ c = SimpleComplex . new (
19+ map1d ( x , ( 0 ...900 ) , ( -3 ..1.5 ) ) , map1d ( y , ( 0 ...600 ) , ( -1.5 ..1.5 ) )
20+ )
21+ # mandel will return 0..20 (20 is strong) map this to 255..0 (NB: reverse)
22+ pixels [ x + y * 900 ] = color ( map1d ( mandel ( c , 20 ) , ( 0 ..20 ) , ( 255 ..0 ) ) . to_i )
2223 end
2324 update_pixels
2425end
2526
2627# calculates the "accuracy" of a given point in the mandelbrot set
27- # : how many iterations the number survives without becoming chaotic
28+ # how many iterations the number survives without becoming chaotic
2829def mandel ( z , max = 10 )
2930 score = 0
3031 c = z . clone
3132 while score < max
3233 # z = z^2 + c
33- z . square
34- z . add c
34+ z . square!
35+ z . add! c
3536 break if z . abs > 2
3637 score += 1
3738 end
3839 score
3940end
4041
41- # rolled my own Complex class
42- # including only the functionality I need (abs, square, add, to_s)
43- #
44- # Using this class, runs in ~12.5s on my MacBook Air
45- # compared to ~22s using ruby's Complex struct
46- class Complex
47- attr_accessor :real , :imag
48-
49- def initialize ( real , imag )
50- @real = real
51- @imag = imag
52- end
53-
54- # squares a complex number - overwriting it
55- def square
56- r = real * real - imag * imag
57- i = 2 * real * imag
58- @real = r
59- @imag = i
60- end
61-
62- # adds a given complex number
63- def add ( c )
64- @real += c . real
65- @imag += c . imag
66- end
67-
68- # computes the magnitude (HelperMethods dist is a safer version of Math.hypot)
69- def abs
70- dist ( 0 , 0 , real , imag )
71- end
72-
73- def to_s
74- format ( '(%f+%fi)' , real , imag )
75- end
76- end
77-
7842def settings
7943 size 900 , 600
8044end
0 commit comments