Welcome, guest | Sign In | My Account | Store | Cart

This program recursively generates a Mandelbrot set using Python and PyGame. The size of the window must be a power of two or you will get rendering errors in the final image. It was written as an exercise in recursion, primarily to further my own understanding of that.

Python, 93 lines
 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 # Recursively draw the Mandelbrot set # Dependencies: Python 2.7.5, PyGame 1.9.1 import pygame from pygame.locals import QUIT from sys import exit # size must be a power of 2 or you will get rounding errors in the image # E.g. 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ... size = 512 pygame.init() surface = pygame.display.set_mode((size, size), 0, 32) # Mandelbrot drawing area xa = -2.0 xb = 1.0 ya = -1.5 yb = 1.5 # maximum iterations maxIt = 256 def pump(): # pump the event queue so the window is responsive, exit if signaled for event in pygame.event.get(): if event.type == QUIT: pygame.quit() exit() def point(x, y): # get the escape value of a specific coordinate in the Mandelbrot set zy = y * (yb - ya) / size + ya zx = x * (xb - xa) / size + xa z = zx + zy * 1j c = z for i in xrange(maxIt): if abs(z) > 2.0: break z = z * z + c return i def col(c): # return a color variable computed from a escape value return (c % 4 * 64, c % 8 * 32, c % 16 * 16) def mandel(x, y, i_size): p1 = point(x, y) half = i_size / 2 # if half > 1 then there are still possible sub-divisions if half > 1: # if all the pixels around the square are the same then it can just # be filled instead of sub-divided - test the square test = False for i in xrange(i_size): t1 = point(x, y + i) t2 = point(x + i, y) t3 = point(x + i_size, y + i) t4 = point(x + i, y + i_size) if (p1 != t1 or p1 != t2 or p1 !=t3 or p1 != t4): test = True break if test: # The colors all around the square are not equal so sub-divide mandel(x, y, half) mandel(x + half, y, half) mandel(x + half, y + half, half) mandel(x, y + half, half) else: # This is a base case, all square border points are same color # fill area and return back up the stack surface.fill(col(p1), (x, y, i_size, i_size)) else: # This is a base case, a 2x2 block. Plot the four pixels # and return back up the stack p2 = point(x + i_size - 1, y) p3 = point(x + i_size - 1, y + i_size - 1) p4 = point(x, y + i_size - 1) surface.lock() surface.set_at((x, y), col(p1)) surface.set_at((x + i_size - 1, y), col(p2)) surface.set_at((x + i_size - 1, y + i_size - 1), col(p3)) surface.set_at((x, y + i_size - 1), col(p4)) surface.unlock() pygame.display.update() pump() # calculate the image mandel(0, 0, size) # Wait for user to click close widget on window while True: pump() Created by Bill Pickett on Sat, 10 Aug 2013 (CC0)