Update of /cvsroot/pythoncard/PythonCard/samples/turtle/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23170/scripts Added Files: .cvsignore automata.py byteDesign.py chaosScript1.py chaosScript1Fastest.py chaosScript2.py coordinates.py distance.py firstTests.py fourBugs.py generalPlot.py helloTurtle.py hilbert.py kochCurves.py madness.py pentests.py raceturtles.py spingon.py sun.py template.py threeTurtles.py toitles.py trees.py wrappers.py Removed Files: 3Turtles.txt 4bugs.txt ChaosScript1.txt ChaosScript1Direct.txt ChaosScript1Fastest.txt ChaosScript2and3.txt HelloTurtle.txt TurtleScript.txt TurtleScript2.txt TurtleScriptFirst.txt automata.txt bytedesign.txt coordinates.txt distance.txt generalPlot.txt hilbert.txt hopalong.txt kochCurves.txt madness.txt originalbytedesign.txt pentests.txt raceturtles.txt spingon.txt sun.txt template.txt toitles.txt trees.txt Log Message: changed turtle script to Python modules changed how modules are run by using __import__ refactored the turtle wrappers removed redundant examples --- NEW FILE: template.py --- from wrappers import Turtle def draw(canvas): t = Turtle(canvas) t.cls() --- NEW FILE: chaosScript2.py --- # another example that doesn't actually use the turtle for drawing import math import sys from wrappers import Turtle class ChaosTurtle(Turtle): def chaos(self, a=1.5732, xOrig=0.0, yOrig=0.0, endRange=38, xOffset=250, yOffset=250, scale=200.0): mult = 1.2 / endRange tempAutoRefresh = self.canvas.autoRefresh self.canvas.autoRefresh = False for j in range(1, endRange + 1): x = xOrig + mult * j y = yOrig + mult * j for i in range(1000): temp = x * math.cos(a) - (y - (x * x)) * math.sin(a) y = x * math.sin(a) + (y - (x * x)) * math.cos(a) x = temp try: self.canvas.drawPoint((xOffset + scale * x, yOffset + scale * y)) except OverflowError: pass self.canvas.refresh() self.canvas.autoRefresh = tempAutoRefresh # this is an alternate implementation of the method above, # but it uses drawPointList instead. in order to avoid # an OverflowError exception in drawPointList an explicit # check that x1 and y1 are in the maxint conversion range # must be done. at least on my machine the need to create # the temporary variables x1, y1 and the conversion check # ends up making this method slower that the method above def chaosWithList(self, a=1.5732, xOrig=0.0, yOrig=0.0, endRange=38, xOffset=250, yOffset=250, scale=200.0): mult = 1.2 / endRange points = [] maxint = sys.maxint for j in range(1, endRange + 1): x = xOrig + mult * j y = yOrig + mult * j for i in range(1000): temp = x * math.cos(a) - (y - (x * x)) * math.sin(a) y = x * math.sin(a) + (y - (x * x)) * math.cos(a) x = temp x1 = xOffset + scale * x y1 = yOffset + scale * y if x1 > -maxint and x1 < maxint and y1 > -maxint and y1 < maxint: points.append((x1, y1)) self.canvas.drawPointList(points) def draw(canvas): t = ChaosTurtle(canvas) t.cls() #t.chaos(1.5732, 0.0, 0.0, 38, 250, 250, 200) t.chaos(1.1111, 0.0, 0.0, 38, 250, 250, 200) # zoom in on one section of the same set as above #t.chaos(1.1111, 0.74, 0.27, 500, 0, 0, 500) --- madness.txt DELETED --- --- bytedesign.txt DELETED --- --- pentests.txt DELETED --- --- NEW FILE: kochCurves.py --- # examples derived from # Visual Modeling with Logo: A Structural Approach to Seeing # by James Clayson # p. 146 # and # Turtle Geometry: The Computer as a Medium for Exploring Mathematics # by Harold Abelson and Andrea diSessa # p. 91 # see http://physics.hallym.ac.kr/education/chaos/ncsa/Fgeom.html # for some more explanation of fractals from wrappers import CurvesTurtle def draw(canvas): t = CurvesTurtle(canvas) t.cls() t.pu() t.lt(90) t.fd(50) t.rt(90) t.pd() # VM p. 146 t.fractalgon(3, 200, 4, -1) t.fractalgon(3, 250, 4, 1) # if you turn on the odometer you should see the total distance # the turle has gone, so you can compare a level 1 curve to # level 2, 3, etc. # but you will need to subtract the radius (rad) distance * 2 # to compensate for the forward() and back() calls in fractalgon # the same distance measurements can be done with other curves: # cCurves, dragon, hilbert, or any drawing commands # for example as the number of sides increases in a polygon # the distance traveled will approach the 2 * pi * r (the radius) # (circumference) of the circle bounded by the polygon # # odometer commands # t.getOdometer() # t.resumeOdometer() # t.resetOdometer() # t.suspendOdometer() --- automata.txt DELETED --- --- NEW FILE: byteDesign.py --- # example based on article in BYTE magazine # Problem Solving with Logo: Using Turtle Graphics to Redraw a Design # November 1982 # p. 118 - 134 from wrappers import Turtle class ByteTurtle(Turtle): def design(self, homePos, scale): self.pu() for i in range(5): self.fd(64.65 * scale) self.pd() self.wheel(self.getXY(), scale) self.pu() self.bk(64.65 * scale) self.rt(72) self.pu(); self.setXY(homePos); self.rt(36); self.fd(24.5 * scale); self.rt(198); self.pd() self.centerpiece(46 * scale, 143.4, scale) def wheel(self, initpos, scale): self.rt(54) for i in range(4): self.pentpiece(initpos, scale) self.pd(); self.lt(36) for i in range(5): self.tripiece(initpos, scale) self.lt(36) for i in range(5): self.pd() self.rt(72) self.fd(28 * scale) self.pu() self.bk(28 * scale) self.lt(54) def tripiece(self, initpos, scale): oldh = self.getHeading() self.pd(); self.bk(2.5 * scale) self.tripolyr(31.5 * scale, scale) self.pu(); self.setXY(initpos); self.setHeading(oldh) self.pd(); self.bk(2.5 * scale) self.tripolyl(31.5 * scale, scale) self.pu(); self.setXY(initpos); self.setHeading(oldh) self.lt(72) def pentpiece(self, initpos, scale): oldh = self.getHeading() self.pu(); self.fd(29 * scale); self.pd() for i in range(5): self.fd(18 * scale) self.rt(72) self.pentr(18 * scale, 75, scale) self.pu(); self.setXY(initpos); self.setHeading(oldh) self.fd(29 * scale); self.pd() for i in range(5): self.fd(18 * scale) self.rt(72) self.pentl(18 * scale, 75, scale) self.pu(); self.setXY(initpos); self.setHeading(oldh) self.lt(72) def pentl(self, side, ang, scale): if side < (2 * scale): return self.fd(side) self.lt(ang) self.pentl(side - (.38 * scale), ang, scale) def pentr(self, side, ang, scale): if side < (2 * scale): return self.fd(side) self.rt(ang) self.pentr(side - (.38 * scale), ang, scale) def tripolyr(self, side, scale): if side < (4 * scale): return self.fd(side) self.rt(111) self.fd(side / 1.78) self.rt(111) self.fd(side / 1.3) self.rt(146) self.tripolyr(side * .75, scale) def tripolyl(self, side, scale): if side < (4 * scale): return self.fd(side) self.lt(111) self.fd(side / 1.78) self.lt(111) self.fd(side / 1.3) self.lt(146) self.tripolyl(side * .75, scale) def centerpiece(self, s, a, scale): self.fd(s); self.lt(a) if s < (7.5 * scale): return self.centerpiece(s - (1.2 * scale), a, scale) def draw(canvas): t = ByteTurtle(canvas) t.cls() """ t.pu() t.lt(90) t.fd(30) t.rt(90) t.pd() """ t.design(t.getXY(), 2.3) --- template.txt DELETED --- --- generalPlot.txt DELETED --- --- NEW FILE: threeTurtles.py --- from wrappers import CurvesTurtle def draw(canvas): # top left corner is 0,0 and bottom right is some positive x and positive y # so the coordinate space is not like a Logo turtle where 0,0 is the center # of the screen t1 = CurvesTurtle(canvas) t1.color('red') # show turtle #t1.st() # get rid of any previous drawing t1.cls() t2 = CurvesTurtle(canvas) t2.color('green') #t2.st() t2.left(120) t3 = CurvesTurtle(canvas) t3.color('blue') #t3.st() t3.left(240) tList = [t1, t2, t3] for t in tList: t.pu() t.forward(50) t.pd() ## for i in range(6): ## [t.fd(80) for t in tList] ## [t.rt(60) for t in tList] #[t.cCurve(4, 10) for t in tList] [t.rDragon(4, 11) for t in tList] #[t.lDragon(4, 11) for t in tList] --- toitles.txt DELETED --- --- NEW FILE: automata.py --- # 1-dimensional binary cellular automata example # this is not done for maximum efficiency # the line is a simple list with a simulated wrap-around if desired # each bit and the bit to the left and right of it # on the line is treated as a binary number # 001 is 1 decimal and 111 is 7 decimal # so a rule can be tested simply by seeing the sum # of the bits # and the rule itself is just a list of numbers to match # [0, 7] for example means if the sum of the bits is 0 or 7 # then turn the bit on in the next iteration # http://psoup.math.wisc.edu/mcell/rullex_1dbi.html # http://psoup.math.wisc.edu/mcell/ca_rules.html # http://psoup.math.wisc.edu/mcell/ca_gallery.html # http://psoup.math.wisc.edu/mcell/rullex_1dto.html from wrappers import Turtle from random import randint # wrapper for any additional drawing routines # that need to know about each other class WolframTurtle(Turtle): def wolframRule(self, str): """convert hex str to list of numbers""" hex = {'F':[1,1,1,1],'E':[1,1,1,0],'D':[1,1,0,1],'C':[1,1,0,0], 'B':[1,0,1,1],'A':[1,0,1,0],'9':[1,0,0,1],'8':[1,0,0,0], '7':[0,1,1,1],'6':[0,1,1,0],'5':[0,1,0,1],'4':[0,1,0,0], '3':[0,0,1,1],'2':[0,0,1,0],'1':[0,0,0,1],'0':[0,0,0,0]} # first create a binary list str = str.upper() bList = [] for c in str: bList += hex[c] # multiply each item in the list by its position # only return the non-zero items bList.reverse() nList = [] for i in range(len(bList)): if bList[i]: nList.append(i) #print str, nList, bList return nList def drawLine(self, line, x, y): points = [] for i in range(len(line)): if line[i]: # KEA 2004-05-10 # it is faster to just draw on the BitmapCanvas directly # and even faster to use the drawPointList method # in fact this whole example doesn't have anything to # do with turtle graphics :) #self.plot(x + i, y) #self.canvas.drawPoint((x + i, y)) points.append((x + i, y)) self.canvas.drawPointList(points) def randomLine(self, n): r = [] for i in range(n): r.append(randint(0, 1)) return r def draw(canvas): t = WolframTurtle(canvas) t.cls() # change wrap, ruleWidth, and r to get different patterns wrap = 1 # if 0, each side is padded with zeros ruleWidth = 2 # 1 or 2 - number of bits to check to the left or right r = t.randomLine(100) #r = [0] * 50 + [1] + [0] * 50 # a line with only one bit on in the center #r = [1] + [0] * 100 #r = [1,0] * 9 + [1,1,1,1,0] + [1,1,0] * 20 + [0] * 20 + [1,0,0,1,0,1,1,1,1,0,0,0,1] print r pad = [0] * ruleWidth lpad = len(pad) if wrap: a = r[-lpad:] + r[:] + r[:lpad] # wrap line else: a = pad + r[:] + pad # wrap line """ rule1 = [0, 7] rule2 = [1, 2, 3, 4, 5, 6] # opposite of rule 1 rule3 = [0, 5, 6, 7] rule4 = [0, 3, 5, 6, 7] rule5 = [1, 2, 4] # opposite of rule 4 rule6 = [1, 2, 4, 5, 6] #rule7 = [0, 3, 7] # opposite of rule 6 rule7 = [6,5,3,2,1] # R1,W6E rule8 = [5,4,2,1] # R1,W36 rule9 = [31,29,27,26,24,23,20,19,18,14,13,12,9,5,4,1] # chaotic gliders rule10 = [29,27,26,25,24,23,19,17,12,11,6,4,3] # solitons D1 """ """ rules.append(rule1) rules.append(rule2) rules.append(rule3) rules.append(rule4) rules.append(rule5) rules.append(rule6) rules.append(rule7) rules.append(rule8) """ # create a method to turn rule notation like R1,W6E into # the search width (R1 is 1 cell to the left and 1 cell to # the right) and a list of numbers (W36 is [5,4,2,1] # create another method to handle this syntax # R2,C10,M1,S0,S1,B0,B3 # from http://psoup.math.wisc.edu/mcell/rullex_1dto.html # 1D CA at http://psoup.math.wisc.edu/mcell/rullex_1dbi.html rules = [] # now create a list of rules if ruleWidth == 1: rules.append(t.wolframRule("36")) # brownian motion rules.append(t.wolframRule("6E")) # fishing-net rules.append(t.wolframRule("16")) # heavy triangles rules.append(t.wolframRule("5A")) # linear a rules.append(t.wolframRule("96")) # linear b rules.append(t.wolframRule("12")) # pascal's triangle (use just a single bit in the center) else: rules.append(t.wolframRule("BC82271C")) # bermuda triangle rules.append(t.wolframRule("AD9C7232")) # chaotic gliders rules.append(t.wolframRule("89ED7106")) # compound gliders rules.append(t.wolframRule("1C2A4798")) # fliform gliders 1 rules.append(t.wolframRule("5C6A4D98")) # fliform gliders 2 rules.append(t.wolframRule("5F0C9AD8")) # fish bones rules.append(t.wolframRule("B51E9CE8")) # glider p106 W4668ED14 rules.append(t.wolframRule("4668ED14")) # raindrops x = 10 original = a[:] lena = len(a) - (2 * lpad) for rule in rules: # R2 rules are too long to write on the screen # but this works fine for R1 rules if ruleWidth == 1: t.moveTo(x, 0) t.write(str(rule)) #print a[lpad:-lpad] #print a t.drawLine(a[lpad:-lpad], x, 19) for i in range(500): b = [0] * lena # a[lpad:-lpad] for j in range(lena): # generalize this to check an arbitrary number of # cells to the left and right if ruleWidth == 1: sum = a[j + lpad - 1] * 4 + a[j + lpad] * 2 + a[j + lpad + 1] else: sum = a[j + lpad - 2] * 16 + a[j + lpad - 1] * 8 + a[j + lpad] * 4 + a[j + lpad + 1] * 2 + a[j + lpad + 2] if sum in rule: b[j] = 1 else: b[j] = 0 t.drawLine(b, x, 20 + i) if wrap: a = b[-lpad:] + b[:] + b[:lpad] else: a = pad + b[:] + pad x += lena + 10 a = original[:] --- TurtleScript.txt DELETED --- --- 3Turtles.txt DELETED --- --- raceturtles.txt DELETED --- --- ChaosScript1Direct.txt DELETED --- --- NEW FILE: coordinates.py --- # test coordinate system from wrappers import Turtle class CoordinatesTurtle(Turtle): def doTick(self, n): self.right(90) self.forward(5) self.write("%d" % n) self.back(10) self.forward(5) self.left(90) def draw(canvas): t = CoordinatesTurtle(canvas) t.cls t.plot() # "0, 0" in Logo space, but "windowWidth / 2, windowHeight / 2" in Guido space # in Guido space (turtle.py from Python standard library) t.color('green') for i in range(4): t.fd(250) t.doTick(250) t.fd(250) t.bk(500) t.lt(90) # note that the lines are not perfectly straight above which indicates a truncation or # rounding bug. since i have yet to mess with the coordinate system or keeping a high-precision # virtual turtle that is only converted to integer coordinates when drawing i haven't # traced out the problem """ t.plot(10, 10) t.plot(10, 500) t.plot(500, 500) t.plot(500, 10) """ t.color('gray') for i in (10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180): t.lt(i) t.fd(i * 2) #print t._angle # change this to write on screen, DrawText or something t.write("%d" % t._angle) t.bk(i * 2) t.rt(i) --- sun.txt DELETED --- --- NEW FILE: pentests.py --- from wrappers import Turtle def draw(canvas): # top left corner is 0,0 and bottom right is some positive x and positive y # so the coordinate space is not like a Logo turtle where 0,0 is the center # of the screen # these are returning the screen dimensions, not the width of the dc #print dc_local.GetSize() #print dc_local.GetSizeTuple() #print dc_local.GetClippingBox() t1 = Turtle(canvas) t1.setBackColor('black') # background is shared among all turtles t1.color('red') t1.showTurtle() t1.turtleDelay(1) t1.cls() # get rid of any previous drawing t2 = Turtle(canvas) t2.color('green') t2.showTurtle() t2.width(2) t2.left(120) t3 = Turtle(canvas) t3.color('blue') #t3.showTurtle() t3.width(3) t3.left(240) t1.forward(50) t2.forward(50) t3.forward(50) # for loop below is equivelant, need a better way of doing # index range though nList = ['1', '2', '3'] for i in nList: eval('t' + i + '.pu()') eval('t' + i + '.forward(50)') eval('t' + i + '.pd()') tList = [t1, t2, t3] for i in range(6): [t.fd(80) for t in tList] #for j in range(1000000): pass # huge delay so we can see the turtle [t.rt(60) for t in tList] #for j in range(1000000): pass # huge delay so we can see the turtle --- distance.txt DELETED --- --- ChaosScript1Fastest.txt DELETED --- --- NEW FILE: madness.py --- """ based on the "madness" algorithm by Stanley S. Miller presented in the May 1988 Scientific American Computer Recreations column by A. K. Dewdney algorithm starts on page 121 """ import math from math import cos, sin from wrappers import Turtle class MadnessTurtle(Turtle): def madness(self, xOffset, yOffset, scale, n, stepSize): # in the article, the equations were # x = sin(.99 * t) - .7 * cos(3.01 * t) # y = cos(1.01 * t) + .1 * sin(15.03 * t) # the units of t are radians a = 1.0 # a = 0.3 b = 0.99 c = -0.7 d = 3.01 e = 1.0 # e = 0.9 f = 1.01 g = 0.1 h = 15.03 # moveTo the first point to avoid a line from # the center position t = -n * stepSize x = a * sin(b * t) + c * cos(d * t) y = e * cos(f * t) + g * sin(h * t) self.moveTo(x * scale + xOffset, y * scale + yOffset) for t in range(-n, n): t *= stepSize x = a * sin(b * t) + c * cos(d * t) y = e * cos(f * t) + g * sin(h * t) #self.plot(x * scale + xOffset, y * scale + yOffset) self.lineTo(x * scale + xOffset, y * scale + yOffset) def draw(canvas): t1 = MadnessTurtle(canvas) t1.cls() # a stepSize of .01 gives pretty smooth curves t1.madness(350, 250, 200, 40000, .01) --- NEW FILE: chaosScript1Fastest.py --- # KEA 2001-10-14 # this is the same algorithm as chaosScript1.py # but rather than using a turtle, the script below uses the # canvas (BitmapCanvas) and drawPointList directly # it still draws line by line so the pattern evolves # on the screen rather than just showing the whole thing at once # plus the extra blit overhead for each line isn't that bad # with a decent video card def draw(canvas): canvas.clear() xOffset = 50 yOffset = 0 scale = 1.0 r = 2.9 # when r was 4.0 I got an exception when doing the int # conversion below, so I need to consider the appropriate # behaviour when x or y is out of bounds for an int # and also out of bounds of the current cliprect or frame steps = 400 inc = (4.0 - 2.9) / steps for j in range(steps): points = [] r += inc x = 0.3 y = j + 30 for i in range(200): x = r * x * (1 - x) for i in range(300): x = r * x * (1 - x) x1 = int(500 * x) x2 = int(xOffset + scale * x1) y2 = int(yOffset + scale * y) points.append((x2, y2)) canvas.drawPointList(points) --- NEW FILE: .cvsignore --- .cvsignore *.pyc *.log .DS_Store --- 4bugs.txt DELETED --- --- NEW FILE: hilbert.py --- # example derived from # Turtle Geometry: The Computer as a Medium for Exploring Mathematics # by Harold Abelson and Andrea diSessa # p. 96-98 from wrappers import CurvesTurtle def draw(canvas): t = CurvesTurtle(canvas) t.cls() t.moveTo(50, 50) t.right(90) t.hilbert(5, 6, 1) --- NEW FILE: wrappers.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/05/11 01:12:51 $" """ # by referring to the Turtle class in this # module rather than PythonCard.turtle.BitmapTurtle # directly in scripts, the script can be run in # a different turtle environment such as LegoTurtle # by simply changing the import line below # of course, I haven't written those other # turtle wrappers, but it never hurts to plan ahead <wink> # i'm open to suggestions for another way of achieving # the same result, namely not needing to change myriads # of turtle scripts in order to run them in a different # graphics environment (BitmapTurtle, LegoTurtle, etc.) from PythonCard import turtle class Turtle(turtle.BitmapTurtle): pass # examples derived from # Visual Modeling with Logo: A Structural Approach to Seeing # by James Clayson # and # Turtle Geometry: The Computer as a Medium for Exploring Mathematics # by Harold Abelson and Andrea diSessa class CurvesTurtle(Turtle): # TG p. 92 def cCurve(self, size, level): if level == 0: self.forward(size) return self.cCurve(size, level - 1) self.right(90) self.cCurve(size, level - 1) self.left(90) # TG p. 93 def lDragon(self, size, level): if level == 0: self.forward(size) return self.lDragon(size, level - 1) self.left(90) self.rDragon(size, level - 1) # TG p. 93 def rDragon(self, size, level): if level == 0: self.forward(size) return self.lDragon(size, level - 1) self.right(90) self.rDragon(size, level - 1) # example derived from # Turtle Geometry: The Computer as a Medium for Exploring Mathematics # by Harold Abelson and Andrea diSessa # p. 96-98 def hilbert(self, size, level, parity): if level == 0: return # rotate and draw first subcurve with opposite parity to big curve self.left(parity * 90) self.hilbert(size, level - 1, -parity) # interface to and draw second subcurve with same parity as big curve self.forward(size) self.right(parity * 90) self.hilbert(size, level - 1, parity) # third subcurve self.forward(size) self.hilbert(size, level - 1, parity) # fourth subcurve self.right(parity * 90) self.forward(size) self.hilbert(size, level - 1, -parity) # a final turn is needed to make the turtle # end up facing outward from the large square self.left(parity * 90) # Visual Modeling with Logo: A Structural Approach to Seeing # by James Clayson # Koch curve, after Helge von Koch who introduced this geometric figure in 1904 # p. 146 def fractalgon(self, n, rad, lev, dir): import math # if dir = 1 turn outward # if dir = -1 turn inward edge = 2 * rad * math.sin(math.pi / n) # logo uses sin(180 / n); Python uses radians self.pu() self.fd(rad) self.pd() self.rt(180 - (90 * (n - 2) / n)) for i in range(n): self.fractal(edge, lev, dir) self.rt(360 / n) self.lt(180 - (90 * (n - 2) / n)) self.pu() self.bk(rad) self.pd() # p. 146 def fractal(self, dist, depth, dir): if depth < 1: self.fd(dist) return self.fractal(dist / 3, depth - 1, dir) self.lt(60 * dir) self.fractal(dist / 3, depth - 1, dir) self.rt(120 * dir) self.fractal(dist / 3, depth - 1, dir) self.lt(60 * dir) self.fractal(dist / 3, depth - 1, dir) --- NEW FILE: spingon.py --- # examples derived from # Visual Modeling with Logo: A Structural Approach to Seeing # by James Clayson from wrappers import Turtle import math from math import pi, sin class GonTurtle(Turtle): # same as polygon, but without the efficiency ;-) def ngon(self, n, edge): for i in range(n): self.fd(edge) self.rt(360.0 / n) # draw a n-sided polygon with radius rad # p. 30 def cngon(self, n, rad): self.pu() self.fd(rad) angle = 180 - (90 * (n - 2) / n) self.rt(angle) self.pd() edge = 2 * rad * sin(pi / n) # logo uses sin(180 / n); Python uses radians self.ngon(n, edge) self.left(angle) self.pu() self.bk(rad) self.pd() # p. 22 def spingon(self, n, edge, angle, growth, times): if times < 1: return self.ngon(n, edge) self.rt(angle) self.spingon(n, edge * growth, angle, growth, times - 1) # another way to do recursion, though the way above seems best """ def spingon(self, n, edge, angle, growth, times): if times > 0: self.ngon(n, edge) self.rt(angle) self.spingon(n, edge * growth, angle, growth, times - 1) """ def draw(canvas): t = GonTurtle(canvas) t.cls() # check that variations of plot works """ t.plot() # uses current x, y #t.plot(375, 300) t.plot(None,10) t.plot(10,None) """ # p. 21 #t.spingon(50, 3, 10, 1.02, 95) radius = 150 # check the radius by uncommenting this """ t.color('blue') for i in range(36): t.fd(radius) t.bk(radius) t.rt(10) """ """ # show that as the number of sides increases # the distance traveled approaches the circumference # of the circle # use the built-in cPolygon (centered-Polygon aTurtle class method) # output is sent to the console window print "circumference: %f" % (2 * pi * radius) for i in range(3, 30): t.resetOdometer() t.resumeOdometer() t.cPolygon(i, radius) dist = t.getOdometer() - (2 * radius) print "sides: %d, distance: %f" % (i, dist) t.suspendOdometer() """ t.color(0, 0, 0) # same as t.color('black') t.color(50, 100, 200) # any r, g, b values between 0 - 255 are valid """""" for i in range(10): t.cngon(8, radius) #t.cngon(6, radius) #t.cngon(5, radius) #t.cngon(4, radius) #t.cngon(3, radius) t.rt(5) radius = radius - 5 """""" --- HelloTurtle.txt DELETED --- --- ChaosScript2and3.txt DELETED --- --- spingon.txt DELETED --- --- NEW FILE: fourBugs.py --- # example based on article in BYTE magazine # 4 bugs starting in separate corners of a square # walk towards each other (this is also the picture on the cover) # November 1982 # p. 236 - 240 from wrappers import Turtle def draw(canvas): t = Turtle(canvas) t.cls() # create four bugs and send them to the four corners of a square bug1 = Turtle(canvas) bug1.color('magenta') bug1.st() bug1.pu() bug1.rt(45) bug1.fd(300) bug1.pd() bug2 = Turtle(canvas) bug2.color('green') bug2.st() bug2.pu() bug2.rt(135) bug2.fd(300) bug2.pd() bug3 = Turtle(canvas) bug3.color('blue') bug3.st() bug3.pu() bug3.rt(225) bug3.fd(300) bug3.pd() bug4 = Turtle(canvas) bug4.color('orange') bug4.st() bug4.pu() bug4.rt(315) bug4.fd(300) bug4.pd() # bug1 is added at the end of the list as a convenience bList = [bug1, bug2, bug3, bug4, bug1] # speed up drawing time tempAutoRefresh = canvas.autoRefresh canvas.autoRefresh = 0 # the bugs take 400 "steps" toward each other for i in range(430): # orient each bug towards its neighbor # by doing this separately from # the step forward, we don't need to maintain # state in a separate list for b in range(4): h = bList[b].towards(bList[b + 1]) bList[b].setHeading(h) # each bug takes one step forward for b in range(4): bList[b].fd(1) canvas.refresh() canvas.autoRefresh = tempAutoRefresh for b in range(4): bList[b].ht() --- NEW FILE: generalPlot.py --- # this is the beginnings of a generalized set of plotting # methods for drawing graphs where x and y can be described # by an equation such as x = t, y = cos(t) # where t is the iteration value over some low to high range # and a step value # since Python can be handed a couple of strings that # are then have eval() applied to them in the loop # generalPlot allows any equation to be passed in as long # as it can be defined in terms of t # the tschirnhausen curve is shown as its own method and # defined in terms of generalPlot for comparison import math from math import cos, pi, sin, sqrt, tan from wrappers import Turtle # wrapper for any additional drawing routines # that need to know about each other class PlotTurtle(Turtle): def doTick(self, n): self.right(90) self.forward(5) self.write("%d" % n) self.back(10) self.forward(5) self.left(90) def coordinateLines(self, x0, y0, xScale, yScale, xLow, xHigh): self.moveTo(0, y0) self.color('blue') self.lineTo(1000, y0) self.moveTo(x0, 0) self.lineTo(x0, 1000) self.moveTo(x0, y0) """ for i in range(10): self.moveTo(i * xLow * xScale + x0, y0) self.doTick(i * xLow) self.moveTo(i * xHigh * xScale + x0, y0) self.doTick(i * xHigh) self.lt(90) """ self.color('black') def generalPlot(self, xOffset, yOffset, xScale, yScale, xEquation, yEquation, low, high, stepSize): # the units of t are radians print "xEquation:", xEquation print "yEquation:", yEquation steps = int((high - low) / stepSize) + 2 # low to high inclusive # moveTo the first point to avoid an extra line t = low x = eval(xEquation) y = eval(yEquation) self.moveTo(x * xScale + xOffset, y * yScale + yOffset) for j in range(steps): t += stepSize x = eval(xEquation) y = eval(yEquation) # self.plot(x * xScale + xOffset, y * yScale + yOffset) self.lineTo(x * xScale + xOffset, y * yScale + yOffset) #self.write("%f, %f" % (x, y)) #break def tschirnhausen2(self, xOffset, yOffset, xScale, yScale, a, low, high, stepSize): # the units of t are radians steps = int((high - low) / stepSize) + 2 # low to high inclusive # moveTo the first point to avoid an extra line t = low - stepSize x = 3 * a * (pow(t, 2) - 3) y = a * t * (pow(t, 2) - 3) self.moveTo(x * xScale + xOffset, y * yScale + yOffset) for j in range(steps): t += stepSize temp = a * (pow(t, 2) - 3) x = 3 * temp y = t * temp # self.plot(x * xScale + xOffset, y * yScale + yOffset) self.lineTo(x * xScale + xOffset, y * yScale + yOffset) """ based on the Tschirnhausen algorithm presented in the May 1988 Scientific American Computer Recreations column by A. K. Dewdney algorithm starts on page 121 """ def tschirnhausen(self, xOffset, yOffset, xScale, yScale, low, high, stepSize): # the units of t are radians a = 1.0 # a = 0.3 steps = int(high - low) / stepSize aSteps = int((2 - 0.1) / 0.1) a = 0.1 for i in range(aSteps): # moveTo the first point to avoid an extra line t = low x = 3 * a * (pow(t, 2) - 3) y = t * a * (pow(t, 2) - 3) self.moveTo(x * xScale + xOffset, y * yScale + yOffset) for j in range(steps): t += stepSize x = 3 * a * (pow(t, 2) - 3) y = a * t * (pow(t, 2) - 3) # self.plot(x * xScale + xOffset, y * yScale + yOffset) self.lineTo(x * xScale + xOffset, y * yScale + yOffset) a += .1 def draw(canvas): t1 = PlotTurtle(canvas) t1.cls() t1.coordinateLines(300, 250, 100, 100, -10, 10) # plot sin, cos, and tan t1.color('red') t1.generalPlot(300, 250, 100, 100, "t", "sin(t)", -pi, pi, .01) t1.color('green') t1.generalPlot(300, 250, 100, 100, "t", "cos(t)", -pi, pi, .01) t1.color('purple') t1.generalPlot(300, 250, 100, 100, "t", "tan(t)", -pi, pi, .01) # generalPlot takes an equation for x and an equation for y # and iterates over a range with a step value # t is the value of each iteration # hippopede t1.color('black') for a in range(20, 50, 5): b = 20 t1.generalPlot(300, 250, 2, 2, "2*cos(t)*sqrt("+str(a)+"*"+str(b)+"-"+"pow("+str(b)+",2)*pow(sin(t), 2))", "2*sin(t)*sqrt("+str(a)+"*"+str(b)+"-"+"pow("+str(b)+",2)*pow(sin(t), 2))", -pi, pi, pi/180) t1.tschirnhausen(200, 250, 5, 3, -4.4, 4.4, .01) #t1.tschirnhausen2(200, 250, 5, 3, 1.0, -4.4, 4.4, .01) """ aLow = .1 aHigh = 2 aStepSize = .1 aSteps = ((aHigh - aLow) / aStepSize) + 2 # aLow to aHigh inclusive a = aLow - aStepSize for i in range(aSteps): a += .1 # a stepSize of .01 gives pretty smooth curves t1.generalPlot(200, 250, 5, 3, "3*" + str(a) + "*(pow(t,2)-3)", "t*" + str(a) + "*(pow(t, 2)-3)", -4.4, 4.4, .01) """ --- hopalong.txt DELETED --- --- TurtleScriptFirst.txt DELETED --- --- NEW FILE: firstTests.py --- from wrappers import CurvesTurtle class SimpleTurtle(CurvesTurtle): def square1(self, distance): self.polygon(4, distance) # just to be different, turn right instead of left def square2(self, distance): for i in range(4): self.forward(distance) self.right(90) def polygon(self, sides, distance): angle = 360.0 / sides for i in range(sides): self.forward(distance) self.left(angle) def draw(canvas): t = SimpleTurtle(canvas) t.color('blue') t.rDragon(3, 12) t.color('orange') t.cCurve(5, 10) t.color('black') t.square2(30) t.square1(100) t.polygon(6, 30) #print t._invradian #print t.angle # I would like to be able to call routines like square2 and polygon1 # without having refer to the object if something like below # is possible? #def polygon(sides, distance): tc.polygon1(sides, distance) #polygon(3, 60) # I got this from chapter 4 of Learning Python, it seems to work # functions are just objects # so we create local objects that point to the methods of the object # this only works for the object, not the class in general, so a # different solution might be more appropriate square = t.square1 polygon = t.polygon t.color('green') # test to see if we get a green square square(150) # this also shows some kind of truncation or rounding error # the top corners of the triangle are off by one pixel t.color('black') t.pu() t.home() t.lt(180) t.fd(200) t.rt(180) t.pd() t.color('blue') for i in range(5): polygon(5, 40) #t.polygon(5, 40) t.left(360.0 / 5) t2 = SimpleTurtle(canvas) t2.color('red') t2.polygon(16, 10) t.color('blue') #t.forward(200) polygon(8, 80) # if this works correctly # the arcs will be different colors # so _goto has to be changed to set the pen characteristics # before drawing for i in range(18): #t.color('blue') t.forward(50) t.right(30) #t2.color('red') t2.fd(50) t2.rt(30) --- NEW FILE: distance.py --- import math from wrappers import Turtle def draw(canvas): t1 = Turtle(canvas) t1.cls() """ # test towards (towardsXY) # these kinds of tests should be done using pyunit tt = Turtle(canvas) for i in range(0, 370, 10): tt.pu() tt.lt(i) tt.fd(100) print "angle: %f, t1 towards tt: %f, tt towards t1: %f" % (i, t1.towards(tt), tt.towards(t1)) tt.bk(100) tt.rt(i) """ # test the distance calculation t1.left(45) t1.forward(100 * math.sqrt(2)) t2 = Turtle(canvas) t2.forward(100) d = t2.distance(t1) t2.write("%f" % d) # should display 100 # test the odometer reading t1.resetOdometer() t1.resumeOdometer() t1.polygon(4, 100) t1.write("odometer: %f" % t1.getOdometer()) --- NEW FILE: helloTurtle.py --- # this is a simple turtle script from wrappers import Turtle def draw(canvas): t = Turtle(canvas) t.cls() t.forward(100) t.write("Hello Turtle") --- trees.txt DELETED --- --- NEW FILE: trees.py --- # examples derived from # Visual Modeling with Logo: A Structural Approach to Seeing # by James Clayson # and # Turtle Geometry: The Computer as a Medium for Exploring Mathematics # by Harold Abelson and Andrea diSessa import wrappers from random import uniform class TreesTurtle(wrappers.Turtle): # TG p. 85 def node(self, length, angle, level): if level == 0: return # point along left branch and draw it self.left(angle) self.lbranch(length, angle, level - 1) # draw right branch self.right(2 * angle) self.rbranch(length, angle, level - 1) # make node state-transparent self.left(angle) # TG p. 84 def lbranch(self, length, angle, level): # draw a long stem self.forward(2 * length) # do next level self.node(length, angle, level) # make lbranch state-transparent self.back (2 * length) # TG p. 84 def rbranch(self, length, angle, level): # draw a short stem self.forward(length) # do next level self.node(length, angle, level) # make lbranch state-transparent self.back (length) # VM p. 292 def tree(self, a, b, n, t, bt, f, l): if l < 1: return pos = self.getXY() self.fd(a) self.rt(t) for i in range(n): pos2 = self.getXY() self.fd(b) self.tree(a * f, b * f, n, t, bt, f, l - 1) #self.bk(b) self.setXY(pos2) self.lt(bt) self.rt((n * bt) - t) #self.moveTo(pos[0], pos[1]) self.setXY(pos) #self.bk(a) # VM p. 306 def randTree(self, a, n, t, bt, f, l): # to draw multiply branched recursive trees # with randomized components if l < 1: return # save the current position and angle pos = self.getXY() heading = self.getHeading() self.fd(uniform(0.5 * a, 1.5 * a)) self.rt(uniform(0.5 * t, 1.5 * t)) #self.fd(uniform(0.5 * t, 1.5 * t)) for i in range(n): d = uniform(0.5 * a / 2, 1.5 * a / 2) # save the position (not the heading) pos2 = self.getXY() self.fd(d) self.randTree(a * f, n, t, bt, f, l - 1) # restore the position self.setXY(pos2) self.lt(uniform(0.5 * bt, 1.5 * bt)) # restore the saved position and heading self.setXY(pos) self.setHeading(heading) def testTree(self, size): if size < 5: return self.fd(size) self.lt(30) self.testTree(size * .7) self.rt(60) self.testTree(size * .7) self.lt(30) self.bk(size) def testRTree(self, size): if size < 5: return self.fd(size) self.lt(30) self.testRTree(size * ((uniform(1, 5) + 5) / 10)) self.rt(60) self.testRTree(size * ((uniform(1, 5) + 5) / 10)) self.lt(30) self.bk(size) def draw(canvas): t = TreesTurtle(canvas) t.cls() t.left(90) #t.tree(80, 40, 4, 60, 30, .6, 5) #t.randTree(50, 3, 60, 30, .6, 4) #t.randTree(30, 3, 30, 30, .75, 5) #t.randTree(30, 3, 30, 15, .9, 5) t.pu() t.bk(150) t.pd() #t.testTree(75) t.testRTree(50) #t.lbranch(20, 20, 7) --- NEW FILE: chaosScript1.py --- from wrappers import Turtle def draw(canvas): t = Turtle(canvas) t.cls() autoRefreshTemp = t.canvas.autoRefresh t.canvas.autoRefresh = 0 xOffset = 50 yOffset = 0 scale = 1.0 r = 2.9 # when r was 4.0 I got an exception when doing the int # conversion below, so I need to consider the appropriate # behaviour when x or y is out of bounds for an int # and also out of bounds of the current cliprect or frame steps = 400 inc = (4.0 - 2.9) / steps for j in range(steps): r += inc x = 0.3 y = j + 30 for i in range(200): x = r * x * (1 - x) for i in range(300): x = r * x * (1 - x) x1 = int(500 * x) # originally self.plot(dc, x1, y1, xOffset, yOffset, scale) # the scale and offset stuff should probably # be part of the turtle or coordinate space x2 = int(xOffset + scale * x1) y2 = int(yOffset + scale * y) t.plot(x2, y2) t.canvas.refresh() t.canvas.autoRefresh = autoRefreshTemp --- ChaosScript1.txt DELETED --- --- NEW FILE: toitles.py --- from wrappers import Turtle def draw(canvas): t = Turtle(canvas) t.cls() namedColors = ['aquamarine', 'black', 'blue', 'blue violet', 'brown', 'cadet blue', 'coral', 'cornflower blue', 'cyan', 'dark grey', 'dark green', 'dark olive green', 'dark orchid', 'dark slate blue'] boids = [] for i in range(len(namedColors)): b = Turtle(canvas) b.moveTo(50, 50) #b.penUp() b.color(namedColors[i]) print namedColors[i] b.showTurtle() b.rt(5 * i) b.fd(10 * i) boids.append(b) autoRefreshTemp = boids[0].canvas.autoRefresh boids[0].canvas.autoRefresh = False for i in range(550): for b in boids: b.fd(1) boids[0].canvas.refresh() boids[0].canvas.autoRefresh = autoRefreshTemp --- coordinates.txt DELETED --- --- hilbert.txt DELETED --- --- NEW FILE: raceturtles.py --- # simple example to show putting multiple # turtles in a list and then applying the # same function to each one, in this case # "racing" them down the screen from wrappers import Turtle def draw(canvas): t = Turtle(canvas) t.cls() #print "On your mark, get set,", # don't make this larger than 255 # since we're using a different shade of red for each turtle # and there are only 256 shades :) maxTurtles = 200 tList = [] for i in range(maxTurtles): t = Turtle(canvas) t.moveTo((i + 1) * 3, 10) t.rt(90) t.color(i + (255 - maxTurtles), 0 , 0) # r, g, b color tList.append(t) autoRefreshTemp = tList[0].canvas.autoRefresh tList[0].canvas.autoRefresh = False #print "go!" for i in range(50): for t in tList: t.fd(10) tList[0].canvas.refresh() tList[0].canvas.autoRefresh = autoRefreshTemp --- kochCurves.txt DELETED --- --- TurtleScript2.txt DELETED --- --- originalbytedesign.txt DELETED --- --- NEW FILE: sun.py --- # examples derived from # Turtle Geometry: The Computer as a Medium for Exploring Mathematics # by Harold Abelson and Andrea diSessa from wrappers import Turtle class SunTurtle(Turtle): # p. 10 def arcr(self, r, deg): for i in range(deg): self.forward(r) self.right(1) # p. 11 def arcl(self, r, deg): for i in range(deg): self.forward(r) self.left(1) # p. 12 def ray(self, r): for i in range(2): self.arcr(r, 90) self.arcl(r, 90) """ self.arcl(r, 90) self.arcr(r, 90) self.arcl(r, 90) self.arcr(r, 90) """ # p. 12 def circles(self): for i in range(9): self.arcr(1, 360) self.right(40) # p. 12 def petal(self, size): self.arcr(size, 60) self.right(120) self.arcr(size, 60) self.right(120) # p. 12 def flower(self, size): for i in range(6): self.petal(size) self.right(60) # p. 12 def sun(self, size): for i in range(9): self.ray(size) self.rt(160) def draw(canvas): t = SunTurtle(canvas) t.cls() #t.circles() #t.flower(3) # simplify coding below by mapping the object methods pu = t.pu pd = t.pd rt = t.rt lt = t.lt fd = t.fd bk = t.bk sun = t.sun pu() lt(90) fd(225) rt(90) bk(100) pd() t.color('gold') sun(1.5) t.moveTo(10, 10) t.write("Good Morning!") |