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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
#!/usr/bin/python
"""
__version__ = "$Revision: 1.2 $"
__date__ = "$Date: 2004/05/22 01:05:29 $"
"""
from PythonCard import clipboard, dialog, graphic, model
from PythonCard.turtle import AbstractTurtle, BitmapTurtle
import wx
import os
import time
import lsystem
class LSystem(lsystem.LSystem):
def on_initialize(self, event):
self.filename = None
#self.on_iterations_select(None)
#self.on_angle_select(None)
self.components.iterationDisplay.text = \
str(self.components.iterations.value)
self.components.angleDisplay.text = \
str(self.components.angle.value)
self.on_Render_command(None)
# depending on the complexity of the pattern string
# my system becomes pretty unresponsive above 6 or 7 iterations
def on_iterations_select(self, event):
self.components.iterationDisplay.text = \
str(self.components.iterations.value)
self.components.iterationDisplay.redraw()
self.on_Render_command(None)
def on_angle_select(self, event):
self.components.angleDisplay.text = \
str(self.components.angle.value)
self.components.angleDisplay.redraw()
self.on_Render_command(None)
def on_angleDisplay_textUpdate(self, event):
# how do we want to validate here
# just use a try/except block?
try:
self.components.angle.value = \
int(self.components.angleDisplay.text)
self.on_Render_command(None)
except:
pass
## # this seemed like a good idea, but you tend to press Render so it isn't needed
## def on_scriptField_closeField(self, event):
## self.on_Render_command(None)
def on_Render_command(self, event):
self.statusBar.text = "Drawing, please wait..."
starttime = time.time()
fractalString = self.expand(
self.components.scriptField.text,
self.components.iterations.value)
borderWidth = 5.0 * 4
angle = self.components.angle.value
bounds = lsystem.drawAbstractFractal(
fractalString,
1,
angle,
(0,0))
width, height = self.components.bufOff.size
scale = min(
(width - 2 * borderWidth) / (bounds[2]-bounds[0]),
(height - 2 * borderWidth) / (bounds[3]-bounds[1]))
startPos = (bounds[0] * -scale + borderWidth,
bounds[1] * -scale + borderWidth)
## self.components.bufOff.autoRefresh = True
self.components.bufOff.autoRefresh = False
self.drawFractal(
fractalString,
'blue',
scale,
angle,
startPos)
# the bufOff BitmapCanvas should always be 4x the size
# of the onscreen BitmapCanvas so we have a simple
# method to anti-alias the drawing
# also need to add some padding around side, so I
# multiplied borderWidth * 4 above
bmp = self.components.bufOff.getBitmap()
self.components.onscreen.drawBitmapScaled(bmp, (0, 0), self.components.onscreen.size)
# not sure if this is needed to prevent a memory leak
bmp = None
stoptime = time.time()
self.statusBar.text = "Draw time: %.2f seconds" % (stoptime - starttime)
def drawFractal(self, aFractalString, color, legLength, angle, startPos):
self.components.bufOff.clear()
t = BitmapTurtle(self.components.bufOff)
t.color(color)
t.width(3)
#t.setBackColor('black')
t.cls()
t.lt(90)
t.moveTo(startPos[0], startPos[1])
## bounds = list(startPos + startPos)
for char in aFractalString:
if char=='F':
t.fd(legLength)
curPos = t.getXY()
## bounds[0] = min(bounds[0], curPos[0])
## bounds[1] = min(bounds[1], curPos[1])
## bounds[2] = max(bounds[2], curPos[0])
## bounds[3] = max(bounds[3], curPos[1])
elif char=='+':
t.rt(angle)
elif char=='-':
t.lt(angle)
elif char=='B':
t.bk(legLength)
elif char=='[':
t.push()
elif char==']':
t.pop()
## return bounds
if __name__ == '__main__':
app = model.Application(LSystem)
app.MainLoop()
|