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-') ```

John Hammink 13 years, 2 months ago

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, 1 month ago

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.

 Created by FB36 on Sat, 27 Mar 2010 (MIT)