Tuesday 9 July 2013

Fun with Fractals

I saw an article on drawing fractals (Julia sets) using the Scratch programming language so I thought I would have a go at doing this in python using the pygame libraries. Program at the bottom of the page.

While playing around with the code and testing different values I came up with some pretty cool images. The first few attempts had it painting black pixels when they should have been coloured.

first test image (incorrect code)
first image zoomed x axis

experimenting with colours
different colours


Favourite colour selection
random 

looks like a chinese dragon
Filled Julia set for c=-1+0.1*i




#!/usr/bin/python

import os, pygame, sys;

from pygame.locals import *

def main():

    pygame.init()

    #set environment variable for SDL to position screen
    os.environ['SDL_VIDEO_WINDOW_POS'] = 'center'

    pygame.display.set_caption(os.path.split(os.path.abspath(__file__))[01])

    #windowed mode, 500x500, automatic colour depth
    screen = pygame.display.set_mode([500,500],0,0)

    #equation c=-0.7467+0.3515i
    #some default values
    #c_real = -0.1
    #c_im = 0.651
    c_real = -0.7467

    c_im = 0.3515
    max_It = 20
    col_offset= 5
    x_zoom = 3
    y_zoom = 1
    normalise=255.0/max_It

    #filename to store generated image
    filename='fractal-'+str(os.getpid())+'.png'

    screen.fill((255,255,255))
    pygame.display.flip()

    x = 0
    while x < 200:
        y= 0
        while y < 180:
           z_re = 1.5*(x - 200)/ (0.5 *x_zoom*200)
           z_im = (y - 180 / 2)/(0.5 * y_zoom *180)
           zi2 = z_im*z_im
           zr2 = z_re*z_re
           iterations = 0
           for iterations in range (0, max_It):

           zi = z_im*z_re
                z_re=(zr2-zi2)+c_real
                z_im=(2*zi)+c_im
                zi2 = z_im*z_im
                zr2=z_re*z_re
                iterations+=1
                if (zi2+zr2 >4):
                    break
           print('iterations=%d'%iterations)
           #convert iterations to a colour value [0-255]
           colour=iterations*normalise
           #if zi*zi + zr2*zr2 stays below 4 uptill max iterations, it has
           #'escaped' and pixel is painted black, otherwise paint with 'colour'
           if iterations >= max_It:
                print('colour=black')
                pygame.draw.line(screen, (0,0,0),(x,y),(x,y))
           else:
                print('colour=%d'%colour)
                pygame.draw.line(screen, (255-colour,colour,colour),(x,y),(x,y))
           pygame.display.flip()
           y+=1
        x+=1

    print('fractal drawn')
    while True:
        #exit for loop, e.g. close window
        for event in pygame.event.get():
           if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        pygame.image.save(screen, filename)
        pygame.time.wait(10000)

if __name__ == '__main__':
    main()