L-System fractals. I did not use the Turtle graphics module of Python because this way is much faster.
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-')
|
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
re: the "integer expected" error, I found a brute force way is to replace line 65 above with:
I don't know yet if this has any repercussions later on.