#!/usr/bin/python

# Fraktales Wachstum mittels Brown'scher Bewegung
#
# GZ 2011, TU Clausthal, http://zach.in.tu-clausthal.de/cg_in_schule/

import Image
import random
import sys


N = 200                             # size of image/grid
if len(sys.argv) > 1:
    N = int( sys.argv[1] )          # size from command line
print "grid size = %d\n" % N

launch = int( N * 0.9 );           # y-pos of launch site for particles
if launch >= N-2:                  # because of random walk condition below
    print "Choose larger image/grid size!"
    sys.exit(1)

# init grid for particle motion
grid = N * [None]                   # N rows
for i in range(1, N):
    grid[i] = N * [False]           # each row = N empty cells
grid[0] = N * [True]                # fill bottom row with particles

#grid = []                          # not-very-high-level way to init a grid;
#for i in range( 0, N ):            # this is the way you would do it in "classic"
#   b = []                          # languages like C++ / Java / etc.
#   for j in range( 0, N ):
#       b.append( False )  # False = "not occupied"
#   grid.append(b)
#for i in range(0, N):
#   grid[0][i] = True    # fill bottom row with particles

# create image to render grid into
im = Image.new("RGB", (N, N), (256, 256, 256) )

# grow fractal "plant"
done = False
particle_num = 0
while not done:
    x = random.randint( 0, N )      # init new particle
    y = launch 

    # output progress, just so that user knows that we are still working
    particle_num += 1
    if (particle_num % 1000 ) == 0:
        particle_num = 0
        print "." ,                 # comma prevents newline
        sys.stdout.flush()

    # perform random walk
    while (x < N - 2) and (x > 1) and (y < N - 2) and (y > 1):
        r = random.random()
        if r < 0.25:                # one random step in either of 
            x -= 1                  # 4 directions: left, right, up, or down
        elif r < 0.50:
            x += 1
        elif r < 0.65:              # slightly favor downward movement
            y += 1
        else:
            y -= 1

#       r = random.random()         # alternative:
#       if r < 0.33:                # random step in one of 8 directions
#           x -= 1
#       elif r < 0.66:
#           x += 1
#       r = random.random()
#       if r < 0.10:
#           y += 1
#       elif r < 0.75:              # slightly favor downward movement
#           y -= 1

        # check if particle touches the "plant"
        if grid[y][x-1] or grid[y][x+1] or grid[y-1][x] or grid[y+1][x]:

            grid[y][x] = True               # occupy grid cell
            im.putpixel( (x,y), (1,1,1) )   # draw new particle with white color

            if y > launch:                  # height of plant exceeds grid
                done = True                 # -> stop growth

            break                  # start with new particle

# display image (opens it in Preview on Mac)
im.transpose(Image.FLIP_TOP_BOTTOM).show()

#vim:expandtab:
