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

L-System fractals. I did not use the Turtle graphics module of Python because this way is much faster.

Python, 106 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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
# L-System Fractals
# FB - 201003276
import math
from PIL import Image, ImageDraw
# image size
imgx = 512
imgy = 512 # will be auto-re-adjusted

# generate the fractal drawing string
def L_system(level, initial_state, trgt, rplcmnt, trgt2, rplcmnt2):
    state = initial_state
   
    for counter in range(level):
        state2 = ''
        for character in state:
            if character == trgt:
                state2 += rplcmnt
            elif character == trgt2:
                state2 += rplcmnt2
            else:
                state2 += character
        state = state2
    return state

def draw_fractal(length, numAngle, level, initial_state, trgt, rplcmnt, trgt2, rplcmnt2):
    global imgx, imgy
    fractal = L_system(level, initial_state, trgt, rplcmnt, trgt2, rplcmnt2)
    na = 2.0 * math.pi / numAngle
    sn = []
    cs = []
    for i in range(numAngle):
        sn.append(math.sin(na * i))
        cs.append(math.cos(na * i))

    # find xmin, xmax, ymin, ymax
    x = 0.0
    y = 0.0
    xa = x
    xb = x
    ya = y
    yb = y
    k = 0
    for ch in fractal:
        if ch == 'F':
            # turtle forward(length)
            x += length * cs[k]
            y += length * sn[k]
            if x < xa:
                xa = x
            if x > xb:
                xb = x
            if y < ya:
                ya = y
            if y > yb:
                yb = y
        elif ch == '+':
            # turtle right(angle)
            k = (k + 1) % numAngle
        elif ch == '-':
            # turtle left(angle)
            k = ((k - 1) + numAngle) % numAngle

    # draw the fractal
    imgy = round(imgy * (yb - ya) / (xb - xa)) # auto-re-adjust the aspect ratio 
    image = Image.new("L", (imgx, imgy))
    draw = ImageDraw.Draw(image)
    x = 0.0
    y = 0.0
    jx = int((x - xa) / (xb - xa) * (imgx - 1)) 
    jy = int((y - ya) / (yb - ya) * (imgy - 1))
    k = 0
    for ch in fractal:
        if ch == 'F':
            # turtle forward(length)
            x0 = x + length * cs[k]
            y0 = y + length * sn[k]
            jx0 = int((x - xa) / (xb - xa) * (imgx - 1)) 
            jy0 = int((y - ya) / (yb - ya) * (imgy - 1))
            draw.line ([(jx, jy),(jx0, jy0)], 255)
            x = x0
            y = y0
            jx = jx0
            jy = jy0
        elif ch == '+':
            # turtle right(angle)
            k = (k + 1) % numAngle
        elif ch == '-':
            # turtle left(angle)
            k = ((k - 1) + numAngle) % numAngle

    image.save("L_System.png", "PNG")

# main       
if __name__ == '__main__':
   
    # Levy Dragon
    # draw_fractal(1, 4, 16, 'FX', 'X', 'X+YF+', 'Y', '-FX-Y')

    # Koch Snowflake
    # draw_fractal(1, 6, 6, 'F++F++F', 'F', 'F-F++F-F', '', '')

    # Levy C
    draw_fractal(1, 8, 17, 'F', 'F', '+F--F+', '', '')

    # Hilbert Space-filling Curve fractal
    # draw_fractal(1, 4, 5, 'L', 'L', '+RF-LFL-FR+', 'R', '-LF+RFR+FL-')

2 comments

John Hammink 13 years, 9 months ago  # | flag

Got this warning...

Warning (from warnings module): File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/PIL/Image.py", line 1763 return Image()._new(core.fill(mode, size, color)) DeprecationWarning: integer argument expected, got float

Jeff Brown 10 years, 8 months ago  # | flag

re: the "integer expected" error, I found a brute force way is to replace line 65 above with:

imgSize = (int(imgx),int(imgy))
image = Image.new("L", imgSize, 0)

I don't know yet if this has any repercussions later on.