File: lsystemInteractive.py

package info (click to toggle)
pythoncard 0.8.1-8.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny
  • size: 5,352 kB
  • ctags: 4,594
  • sloc: python: 42,401; makefile: 55; sh: 22
file content (131 lines) | stat: -rw-r--r-- 4,490 bytes parent folder | download
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()