python-2.5.2/win32/Lib/lib-tk/turtle.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 # LogoMation-like turtle graphics
       
     2 
       
     3 """
       
     4 Turtle graphics is a popular way for introducing programming to
       
     5 kids. It was part of the original Logo programming language developed
       
     6 by Wally Feurzeig and Seymour Papert in 1966.
       
     7 
       
     8 Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
       
     9 the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
       
    10 the direction it is facing, drawing a line as it moves. Give it the
       
    11 command turtle.left(25), and it rotates in-place 25 degrees clockwise.
       
    12 
       
    13 By combining together these and similar commands, intricate shapes and
       
    14 pictures can easily be drawn.
       
    15 """
       
    16 
       
    17 from math import * # Also for export
       
    18 from time import sleep
       
    19 import Tkinter
       
    20 
       
    21 speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
       
    22 
       
    23 class Error(Exception):
       
    24     pass
       
    25 
       
    26 class RawPen:
       
    27 
       
    28     def __init__(self, canvas):
       
    29         self._canvas = canvas
       
    30         self._items = []
       
    31         self._tracing = 1
       
    32         self._arrow = 0
       
    33         self._delay = 10     # default delay for drawing
       
    34         self._angle = 0.0
       
    35         self.degrees()
       
    36         self.reset()
       
    37 
       
    38     def degrees(self, fullcircle=360.0):
       
    39         """ Set angle measurement units to degrees.
       
    40 
       
    41         Example:
       
    42         >>> turtle.degrees()
       
    43         """
       
    44         # Don't try to change _angle if it is 0, because
       
    45         # _fullcircle might not be set, yet
       
    46         if self._angle:
       
    47             self._angle = (self._angle / self._fullcircle) * fullcircle
       
    48         self._fullcircle = fullcircle
       
    49         self._invradian = pi / (fullcircle * 0.5)
       
    50 
       
    51     def radians(self):
       
    52         """ Set the angle measurement units to radians.
       
    53 
       
    54         Example:
       
    55         >>> turtle.radians()
       
    56         """
       
    57         self.degrees(2.0*pi)
       
    58 
       
    59     def reset(self):
       
    60         """ Clear the screen, re-center the pen, and set variables to
       
    61         the default values.
       
    62 
       
    63         Example:
       
    64         >>> turtle.position()
       
    65         [0.0, -22.0]
       
    66         >>> turtle.heading()
       
    67         100.0
       
    68         >>> turtle.reset()
       
    69         >>> turtle.position()
       
    70         [0.0, 0.0]
       
    71         >>> turtle.heading()
       
    72         0.0
       
    73         """
       
    74         canvas = self._canvas
       
    75         self._canvas.update()
       
    76         width = canvas.winfo_width()
       
    77         height = canvas.winfo_height()
       
    78         if width <= 1:
       
    79             width = canvas['width']
       
    80         if height <= 1:
       
    81             height = canvas['height']
       
    82         self._origin = float(width)/2.0, float(height)/2.0
       
    83         self._position = self._origin
       
    84         self._angle = 0.0
       
    85         self._drawing = 1
       
    86         self._width = 1
       
    87         self._color = "black"
       
    88         self._filling = 0
       
    89         self._path = []
       
    90         self.clear()
       
    91         canvas._root().tkraise()
       
    92 
       
    93     def clear(self):
       
    94         """ Clear the screen. The turtle does not move.
       
    95 
       
    96         Example:
       
    97         >>> turtle.clear()
       
    98         """
       
    99         self.fill(0)
       
   100         canvas = self._canvas
       
   101         items = self._items
       
   102         self._items = []
       
   103         for item in items:
       
   104             canvas.delete(item)
       
   105         self._delete_turtle()
       
   106         self._draw_turtle()
       
   107 
       
   108     def tracer(self, flag):
       
   109         """ Set tracing on if flag is True, and off if it is False.
       
   110         Tracing means line are drawn more slowly, with an
       
   111         animation of an arrow along the line.
       
   112 
       
   113         Example:
       
   114         >>> turtle.tracer(False)   # turns off Tracer
       
   115         """
       
   116         self._tracing = flag
       
   117         if not self._tracing:
       
   118             self._delete_turtle()
       
   119         self._draw_turtle()
       
   120 
       
   121     def forward(self, distance):
       
   122         """ Go forward distance steps.
       
   123 
       
   124         Example:
       
   125         >>> turtle.position()
       
   126         [0.0, 0.0]
       
   127         >>> turtle.forward(25)
       
   128         >>> turtle.position()
       
   129         [25.0, 0.0]
       
   130         >>> turtle.forward(-75)
       
   131         >>> turtle.position()
       
   132         [-50.0, 0.0]
       
   133         """
       
   134         x0, y0 = start = self._position
       
   135         x1 = x0 + distance * cos(self._angle*self._invradian)
       
   136         y1 = y0 - distance * sin(self._angle*self._invradian)
       
   137         self._goto(x1, y1)
       
   138 
       
   139     def backward(self, distance):
       
   140         """ Go backwards distance steps.
       
   141 
       
   142         The turtle's heading does not change.
       
   143 
       
   144         Example:
       
   145         >>> turtle.position()
       
   146         [0.0, 0.0]
       
   147         >>> turtle.backward(30)
       
   148         >>> turtle.position()
       
   149         [-30.0, 0.0]
       
   150         """
       
   151         self.forward(-distance)
       
   152 
       
   153     def left(self, angle):
       
   154         """ Turn left angle units (units are by default degrees,
       
   155         but can be set via the degrees() and radians() functions.)
       
   156 
       
   157         When viewed from above, the turning happens in-place around
       
   158         its front tip.
       
   159 
       
   160         Example:
       
   161         >>> turtle.heading()
       
   162         22
       
   163         >>> turtle.left(45)
       
   164         >>> turtle.heading()
       
   165         67.0
       
   166         """
       
   167         self._angle = (self._angle + angle) % self._fullcircle
       
   168         self._draw_turtle()
       
   169 
       
   170     def right(self, angle):
       
   171         """ Turn right angle units (units are by default degrees,
       
   172         but can be set via the degrees() and radians() functions.)
       
   173 
       
   174         When viewed from above, the turning happens in-place around
       
   175         its front tip.
       
   176 
       
   177         Example:
       
   178         >>> turtle.heading()
       
   179         22
       
   180         >>> turtle.right(45)
       
   181         >>> turtle.heading()
       
   182         337.0
       
   183         """
       
   184         self.left(-angle)
       
   185 
       
   186     def up(self):
       
   187         """ Pull the pen up -- no drawing when moving.
       
   188 
       
   189         Example:
       
   190         >>> turtle.up()
       
   191         """
       
   192         self._drawing = 0
       
   193 
       
   194     def down(self):
       
   195         """ Put the pen down -- draw when moving.
       
   196 
       
   197         Example:
       
   198         >>> turtle.down()
       
   199         """
       
   200         self._drawing = 1
       
   201 
       
   202     def width(self, width):
       
   203         """ Set the line to thickness to width.
       
   204 
       
   205         Example:
       
   206         >>> turtle.width(10)
       
   207         """
       
   208         self._width = float(width)
       
   209 
       
   210     def color(self, *args):
       
   211         """ Set the pen color.
       
   212 
       
   213         Three input formats are allowed:
       
   214 
       
   215             color(s)
       
   216             s is a Tk specification string, such as "red" or "yellow"
       
   217 
       
   218             color((r, g, b))
       
   219             *a tuple* of r, g, and b, which represent, an RGB color,
       
   220             and each of r, g, and b are in the range [0..1]
       
   221 
       
   222             color(r, g, b)
       
   223             r, g, and b represent an RGB color, and each of r, g, and b
       
   224             are in the range [0..1]
       
   225 
       
   226         Example:
       
   227 
       
   228         >>> turtle.color('brown')
       
   229         >>> tup = (0.2, 0.8, 0.55)
       
   230         >>> turtle.color(tup)
       
   231         >>> turtle.color(0, .5, 0)
       
   232         """
       
   233         if not args:
       
   234             raise Error, "no color arguments"
       
   235         if len(args) == 1:
       
   236             color = args[0]
       
   237             if type(color) == type(""):
       
   238                 # Test the color first
       
   239                 try:
       
   240                     id = self._canvas.create_line(0, 0, 0, 0, fill=color)
       
   241                 except Tkinter.TclError:
       
   242                     raise Error, "bad color string: %r" % (color,)
       
   243                 self._set_color(color)
       
   244                 return
       
   245             try:
       
   246                 r, g, b = color
       
   247             except:
       
   248                 raise Error, "bad color sequence: %r" % (color,)
       
   249         else:
       
   250             try:
       
   251                 r, g, b = args
       
   252             except:
       
   253                 raise Error, "bad color arguments: %r" % (args,)
       
   254         assert 0 <= r <= 1
       
   255         assert 0 <= g <= 1
       
   256         assert 0 <= b <= 1
       
   257         x = 255.0
       
   258         y = 0.5
       
   259         self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
       
   260 
       
   261     def _set_color(self,color):
       
   262         self._color = color
       
   263         self._draw_turtle()
       
   264 
       
   265     def write(self, text, move=False):
       
   266         """ Write text at the current pen position.
       
   267 
       
   268         If move is true, the pen is moved to the bottom-right corner
       
   269         of the text. By default, move is False.
       
   270 
       
   271         Example:
       
   272         >>> turtle.write('The race is on!')
       
   273         >>> turtle.write('Home = (0, 0)', True)
       
   274         """
       
   275         x, y  = self._position
       
   276         x = x-1 # correction -- calibrated for Windows
       
   277         item = self._canvas.create_text(x, y,
       
   278                                         text=str(text), anchor="sw",
       
   279                                         fill=self._color)
       
   280         self._items.append(item)
       
   281         if move:
       
   282             x0, y0, x1, y1 = self._canvas.bbox(item)
       
   283             self._goto(x1, y1)
       
   284         self._draw_turtle()
       
   285 
       
   286     def fill(self, flag):
       
   287         """ Call fill(1) before drawing the shape you
       
   288          want to fill, and fill(0) when done.
       
   289 
       
   290         Example:
       
   291         >>> turtle.fill(1)
       
   292         >>> turtle.forward(100)
       
   293         >>> turtle.left(90)
       
   294         >>> turtle.forward(100)
       
   295         >>> turtle.left(90)
       
   296         >>> turtle.forward(100)
       
   297         >>> turtle.left(90)
       
   298         >>> turtle.forward(100)
       
   299         >>> turtle.fill(0)
       
   300         """
       
   301         if self._filling:
       
   302             path = tuple(self._path)
       
   303             smooth = self._filling < 0
       
   304             if len(path) > 2:
       
   305                 item = self._canvas._create('polygon', path,
       
   306                                             {'fill': self._color,
       
   307                                              'smooth': smooth})
       
   308                 self._items.append(item)
       
   309         self._path = []
       
   310         self._filling = flag
       
   311         if flag:
       
   312             self._path.append(self._position)
       
   313 
       
   314     def begin_fill(self):
       
   315         """ Called just before drawing a shape to be filled.
       
   316             Must eventually be followed by a corresponding end_fill() call.
       
   317             Otherwise it will be ignored.
       
   318 
       
   319         Example:
       
   320         >>> turtle.begin_fill()
       
   321         >>> turtle.forward(100)
       
   322         >>> turtle.left(90)
       
   323         >>> turtle.forward(100)
       
   324         >>> turtle.left(90)
       
   325         >>> turtle.forward(100)
       
   326         >>> turtle.left(90)
       
   327         >>> turtle.forward(100)
       
   328         >>> turtle.end_fill()
       
   329         """
       
   330         self._path = [self._position]
       
   331         self._filling = 1
       
   332 
       
   333     def end_fill(self):
       
   334         """ Called after drawing a shape to be filled.
       
   335 
       
   336         Example:
       
   337         >>> turtle.begin_fill()
       
   338         >>> turtle.forward(100)
       
   339         >>> turtle.left(90)
       
   340         >>> turtle.forward(100)
       
   341         >>> turtle.left(90)
       
   342         >>> turtle.forward(100)
       
   343         >>> turtle.left(90)
       
   344         >>> turtle.forward(100)
       
   345         >>> turtle.end_fill()
       
   346         """
       
   347         self.fill(0)
       
   348 
       
   349     def circle(self, radius, extent = None):
       
   350         """ Draw a circle with given radius.
       
   351         The center is radius units left of the turtle; extent
       
   352         determines which part of the circle is drawn. If not given,
       
   353         the entire circle is drawn.
       
   354 
       
   355         If extent is not a full circle, one endpoint of the arc is the
       
   356         current pen position. The arc is drawn in a counter clockwise
       
   357         direction if radius is positive, otherwise in a clockwise
       
   358         direction. In the process, the direction of the turtle is
       
   359         changed by the amount of the extent.
       
   360 
       
   361         >>> turtle.circle(50)
       
   362         >>> turtle.circle(120, 180)  # half a circle
       
   363         """
       
   364         if extent is None:
       
   365             extent = self._fullcircle
       
   366         frac = abs(extent)/self._fullcircle
       
   367         steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
       
   368         w = 1.0 * extent / steps
       
   369         w2 = 0.5 * w
       
   370         l = 2.0 * radius * sin(w2*self._invradian)
       
   371         if radius < 0:
       
   372             l, w, w2 = -l, -w, -w2
       
   373         self.left(w2)
       
   374         for i in range(steps):
       
   375             self.forward(l)
       
   376             self.left(w)
       
   377         self.right(w2)
       
   378 
       
   379     def heading(self):
       
   380         """ Return the turtle's current heading.
       
   381 
       
   382         Example:
       
   383         >>> turtle.heading()
       
   384         67.0
       
   385         """
       
   386         return self._angle
       
   387 
       
   388     def setheading(self, angle):
       
   389         """ Set the turtle facing the given angle.
       
   390 
       
   391         Here are some common directions in degrees:
       
   392 
       
   393            0 - east
       
   394           90 - north
       
   395          180 - west
       
   396          270 - south
       
   397 
       
   398         Example:
       
   399         >>> turtle.setheading(90)
       
   400         >>> turtle.heading()
       
   401         90
       
   402         >>> turtle.setheading(128)
       
   403         >>> turtle.heading()
       
   404         128
       
   405         """
       
   406         self._angle = angle
       
   407         self._draw_turtle()
       
   408 
       
   409     def window_width(self):
       
   410         """ Returns the width of the turtle window.
       
   411 
       
   412         Example:
       
   413         >>> turtle.window_width()
       
   414         640
       
   415         """
       
   416         width = self._canvas.winfo_width()
       
   417         if width <= 1:  # the window isn't managed by a geometry manager
       
   418             width = self._canvas['width']
       
   419         return width
       
   420 
       
   421     def window_height(self):
       
   422         """ Return the height of the turtle window.
       
   423 
       
   424         Example:
       
   425         >>> turtle.window_height()
       
   426         768
       
   427         """
       
   428         height = self._canvas.winfo_height()
       
   429         if height <= 1: # the window isn't managed by a geometry manager
       
   430             height = self._canvas['height']
       
   431         return height
       
   432 
       
   433     def position(self):
       
   434         """ Return the current (x, y) location of the turtle.
       
   435 
       
   436         Example:
       
   437         >>> turtle.position()
       
   438         [0.0, 240.0]
       
   439         """
       
   440         x0, y0 = self._origin
       
   441         x1, y1 = self._position
       
   442         return [x1-x0, -y1+y0]
       
   443 
       
   444     def setx(self, xpos):
       
   445         """ Set the turtle's x coordinate to be xpos.
       
   446 
       
   447         Example:
       
   448         >>> turtle.position()
       
   449         [10.0, 240.0]
       
   450         >>> turtle.setx(10)
       
   451         >>> turtle.position()
       
   452         [10.0, 240.0]
       
   453         """
       
   454         x0, y0 = self._origin
       
   455         x1, y1 = self._position
       
   456         self._goto(x0+xpos, y1)
       
   457 
       
   458     def sety(self, ypos):
       
   459         """ Set the turtle's y coordinate to be ypos.
       
   460 
       
   461         Example:
       
   462         >>> turtle.position()
       
   463         [0.0, 0.0]
       
   464         >>> turtle.sety(-22)
       
   465         >>> turtle.position()
       
   466         [0.0, -22.0]
       
   467         """
       
   468         x0, y0 = self._origin
       
   469         x1, y1 = self._position
       
   470         self._goto(x1, y0-ypos)
       
   471 
       
   472     def towards(self, *args):
       
   473         """Returs the angle, which corresponds to the line
       
   474         from turtle-position to point (x,y).
       
   475 
       
   476         Argument can be two coordinates or one pair of coordinates
       
   477         or a RawPen/Pen instance.
       
   478 
       
   479         Example:
       
   480         >>> turtle.position()
       
   481         [10.0, 10.0]
       
   482         >>> turtle.towards(0,0)
       
   483         225.0
       
   484         """
       
   485         if len(args) == 2:
       
   486             x, y = args
       
   487         else:
       
   488             arg = args[0]
       
   489             if isinstance(arg, RawPen):
       
   490                 x, y = arg.position()
       
   491             else:
       
   492                 x, y = arg
       
   493         x0, y0 = self.position()
       
   494         dx = x - x0
       
   495         dy = y - y0
       
   496         return (atan2(dy,dx) / self._invradian) % self._fullcircle
       
   497 
       
   498     def goto(self, *args):
       
   499         """ Go to the given point.
       
   500 
       
   501         If the pen is down, then a line will be drawn. The turtle's
       
   502         orientation does not change.
       
   503 
       
   504         Two input formats are accepted:
       
   505 
       
   506            goto(x, y)
       
   507            go to point (x, y)
       
   508 
       
   509            goto((x, y))
       
   510            go to point (x, y)
       
   511 
       
   512         Example:
       
   513         >>> turtle.position()
       
   514         [0.0, 0.0]
       
   515         >>> turtle.goto(50, -45)
       
   516         >>> turtle.position()
       
   517         [50.0, -45.0]
       
   518         """
       
   519         if len(args) == 1:
       
   520             try:
       
   521                 x, y = args[0]
       
   522             except:
       
   523                 raise Error, "bad point argument: %r" % (args[0],)
       
   524         else:
       
   525             try:
       
   526                 x, y = args
       
   527             except:
       
   528                 raise Error, "bad coordinates: %r" % (args[0],)
       
   529         x0, y0 = self._origin
       
   530         self._goto(x0+x, y0-y)
       
   531 
       
   532     def _goto(self, x1, y1):
       
   533         x0, y0 = self._position
       
   534         self._position = map(float, (x1, y1))
       
   535         if self._filling:
       
   536             self._path.append(self._position)
       
   537         if self._drawing:
       
   538             if self._tracing:
       
   539                 dx = float(x1 - x0)
       
   540                 dy = float(y1 - y0)
       
   541                 distance = hypot(dx, dy)
       
   542                 nhops = int(distance)
       
   543                 item = self._canvas.create_line(x0, y0, x0, y0,
       
   544                                                 width=self._width,
       
   545                                                 capstyle="round",
       
   546                                                 fill=self._color)
       
   547                 try:
       
   548                     for i in range(1, 1+nhops):
       
   549                         x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
       
   550                         self._canvas.coords(item, x0, y0, x, y)
       
   551                         self._draw_turtle((x,y))
       
   552                         self._canvas.update()
       
   553                         self._canvas.after(self._delay)
       
   554                     # in case nhops==0
       
   555                     self._canvas.coords(item, x0, y0, x1, y1)
       
   556                     self._canvas.itemconfigure(item, arrow="none")
       
   557                 except Tkinter.TclError:
       
   558                     # Probably the window was closed!
       
   559                     return
       
   560             else:
       
   561                 item = self._canvas.create_line(x0, y0, x1, y1,
       
   562                                                 width=self._width,
       
   563                                                 capstyle="round",
       
   564                                                 fill=self._color)
       
   565             self._items.append(item)
       
   566         self._draw_turtle()
       
   567 
       
   568     def speed(self, speed):
       
   569         """ Set the turtle's speed.
       
   570 
       
   571         speed must one of these five strings:
       
   572 
       
   573             'fastest' is a 0 ms delay
       
   574             'fast' is a 5 ms delay
       
   575             'normal' is a 10 ms delay
       
   576             'slow' is a 15 ms delay
       
   577             'slowest' is a 20 ms delay
       
   578 
       
   579          Example:
       
   580          >>> turtle.speed('slow')
       
   581         """
       
   582         try:
       
   583             speed = speed.strip().lower()
       
   584             self._delay = speeds.index(speed) * 5
       
   585         except:
       
   586             raise ValueError("%r is not a valid speed. speed must be "
       
   587                              "one of %s" % (speed, speeds))
       
   588 
       
   589 
       
   590     def delay(self, delay):
       
   591         """ Set the drawing delay in milliseconds.
       
   592 
       
   593         This is intended to allow finer control of the drawing speed
       
   594         than the speed() method
       
   595 
       
   596         Example:
       
   597         >>> turtle.delay(15)
       
   598         """
       
   599         if int(delay) < 0:
       
   600             raise ValueError("delay must be greater than or equal to 0")
       
   601         self._delay = int(delay)
       
   602 
       
   603     def _draw_turtle(self, position=[]):
       
   604         if not self._tracing:
       
   605             self._canvas.update()
       
   606             return
       
   607         if position == []:
       
   608             position = self._position
       
   609         x,y = position
       
   610         distance = 8
       
   611         dx = distance * cos(self._angle*self._invradian)
       
   612         dy = distance * sin(self._angle*self._invradian)
       
   613         self._delete_turtle()
       
   614         self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
       
   615                                           width=self._width,
       
   616                                           arrow="last",
       
   617                                           capstyle="round",
       
   618                                           fill=self._color)
       
   619         self._canvas.update()
       
   620 
       
   621     def _delete_turtle(self):
       
   622         if self._arrow != 0:
       
   623             self._canvas.delete(self._arrow)
       
   624             self._arrow = 0
       
   625 
       
   626 
       
   627 _root = None
       
   628 _canvas = None
       
   629 _pen = None
       
   630 _width = 0.50                  # 50% of window width
       
   631 _height = 0.75                 # 75% of window height
       
   632 _startx = None
       
   633 _starty = None
       
   634 _title = "Turtle Graphics"     # default title
       
   635 
       
   636 class Pen(RawPen):
       
   637 
       
   638     def __init__(self):
       
   639         global _root, _canvas
       
   640         if _root is None:
       
   641             _root = Tkinter.Tk()
       
   642             _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
       
   643             _root.title(_title)
       
   644 
       
   645         if _canvas is None:
       
   646             # XXX Should have scroll bars
       
   647             _canvas = Tkinter.Canvas(_root, background="white")
       
   648             _canvas.pack(expand=1, fill="both")
       
   649 
       
   650             setup(width=_width, height= _height, startx=_startx, starty=_starty)
       
   651 
       
   652         RawPen.__init__(self, _canvas)
       
   653 
       
   654     def _destroy(self):
       
   655         global _root, _canvas, _pen
       
   656         root = self._canvas._root()
       
   657         if root is _root:
       
   658             _pen = None
       
   659             _root = None
       
   660             _canvas = None
       
   661         root.destroy()
       
   662 
       
   663 def _getpen():
       
   664     global _pen
       
   665     if not _pen:
       
   666         _pen = Pen()
       
   667     return _pen
       
   668 
       
   669 class Turtle(Pen):
       
   670     pass
       
   671 
       
   672 """For documentation of the following functions see
       
   673    the RawPen methods with the same names
       
   674 """
       
   675 
       
   676 def degrees(): _getpen().degrees()
       
   677 def radians(): _getpen().radians()
       
   678 def reset(): _getpen().reset()
       
   679 def clear(): _getpen().clear()
       
   680 def tracer(flag): _getpen().tracer(flag)
       
   681 def forward(distance): _getpen().forward(distance)
       
   682 def backward(distance): _getpen().backward(distance)
       
   683 def left(angle): _getpen().left(angle)
       
   684 def right(angle): _getpen().right(angle)
       
   685 def up(): _getpen().up()
       
   686 def down(): _getpen().down()
       
   687 def width(width): _getpen().width(width)
       
   688 def color(*args): _getpen().color(*args)
       
   689 def write(arg, move=0): _getpen().write(arg, move)
       
   690 def fill(flag): _getpen().fill(flag)
       
   691 def begin_fill(): _getpen().begin_fill()
       
   692 def end_fill(): _getpen().end_fill()
       
   693 def circle(radius, extent=None): _getpen().circle(radius, extent)
       
   694 def goto(*args): _getpen().goto(*args)
       
   695 def heading(): return _getpen().heading()
       
   696 def setheading(angle): _getpen().setheading(angle)
       
   697 def position(): return _getpen().position()
       
   698 def window_width(): return _getpen().window_width()
       
   699 def window_height(): return _getpen().window_height()
       
   700 def setx(xpos): _getpen().setx(xpos)
       
   701 def sety(ypos): _getpen().sety(ypos)
       
   702 def towards(*args): return _getpen().towards(*args)
       
   703 
       
   704 def done(): _root.mainloop()
       
   705 def delay(delay): return _getpen().delay(delay)
       
   706 def speed(speed): return _getpen().speed(speed)
       
   707 
       
   708 for methodname in dir(RawPen):
       
   709     """ copies RawPen docstrings to module functions of same name """
       
   710     if not methodname.startswith("_"):
       
   711         eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
       
   712 
       
   713 
       
   714 def setup(**geometry):
       
   715     """ Sets the size and position of the main window.
       
   716 
       
   717     Keywords are width, height, startx and starty:
       
   718 
       
   719     width: either a size in pixels or a fraction of the screen.
       
   720       Default is 50% of screen.
       
   721     height: either the height in pixels or a fraction of the screen.
       
   722       Default is 75% of screen.
       
   723 
       
   724     Setting either width or height to None before drawing will force
       
   725       use of default geometry as in older versions of turtle.py
       
   726 
       
   727     startx: starting position in pixels from the left edge of the screen.
       
   728       Default is to center window. Setting startx to None is the default
       
   729       and centers window horizontally on screen.
       
   730 
       
   731     starty: starting position in pixels from the top edge of the screen.
       
   732       Default is to center window. Setting starty to None is the default
       
   733       and centers window vertically on screen.
       
   734 
       
   735     Examples:
       
   736     >>> setup (width=200, height=200, startx=0, starty=0)
       
   737 
       
   738     sets window to 200x200 pixels, in upper left of screen
       
   739 
       
   740     >>> setup(width=.75, height=0.5, startx=None, starty=None)
       
   741 
       
   742     sets window to 75% of screen by 50% of screen and centers
       
   743 
       
   744     >>> setup(width=None)
       
   745 
       
   746     forces use of default geometry as in older versions of turtle.py
       
   747     """
       
   748 
       
   749     global _width, _height, _startx, _starty
       
   750 
       
   751     width = geometry.get('width',_width)
       
   752     if width >= 0 or width == None:
       
   753         _width = width
       
   754     else:
       
   755         raise ValueError, "width can not be less than 0"
       
   756 
       
   757     height = geometry.get('height',_height)
       
   758     if height >= 0 or height == None:
       
   759         _height = height
       
   760     else:
       
   761         raise ValueError, "height can not be less than 0"
       
   762 
       
   763     startx = geometry.get('startx', _startx)
       
   764     if startx >= 0 or startx == None:
       
   765         _startx = _startx
       
   766     else:
       
   767         raise ValueError, "startx can not be less than 0"
       
   768 
       
   769     starty = geometry.get('starty', _starty)
       
   770     if starty >= 0 or starty == None:
       
   771         _starty = starty
       
   772     else:
       
   773         raise ValueError, "startx can not be less than 0"
       
   774 
       
   775 
       
   776     if _root and _width and _height:
       
   777         if 0 < _width <= 1:
       
   778             _width = _root.winfo_screenwidth() * +width
       
   779         if 0 < _height <= 1:
       
   780             _height = _root.winfo_screenheight() * _height
       
   781 
       
   782         # center window on screen
       
   783         if _startx is None:
       
   784             _startx = (_root.winfo_screenwidth() - _width) / 2
       
   785 
       
   786         if _starty is None:
       
   787             _starty = (_root.winfo_screenheight() - _height) / 2
       
   788 
       
   789         _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
       
   790 
       
   791 def title(title):
       
   792     """Set the window title.
       
   793 
       
   794     By default this is set to 'Turtle Graphics'
       
   795 
       
   796     Example:
       
   797     >>> title("My Window")
       
   798     """
       
   799 
       
   800     global _title
       
   801     _title = title
       
   802 
       
   803 def demo():
       
   804     reset()
       
   805     tracer(1)
       
   806     up()
       
   807     backward(100)
       
   808     down()
       
   809     # draw 3 squares; the last filled
       
   810     width(3)
       
   811     for i in range(3):
       
   812         if i == 2:
       
   813             fill(1)
       
   814         for j in range(4):
       
   815             forward(20)
       
   816             left(90)
       
   817         if i == 2:
       
   818             color("maroon")
       
   819             fill(0)
       
   820         up()
       
   821         forward(30)
       
   822         down()
       
   823     width(1)
       
   824     color("black")
       
   825     # move out of the way
       
   826     tracer(0)
       
   827     up()
       
   828     right(90)
       
   829     forward(100)
       
   830     right(90)
       
   831     forward(100)
       
   832     right(180)
       
   833     down()
       
   834     # some text
       
   835     write("startstart", 1)
       
   836     write("start", 1)
       
   837     color("red")
       
   838     # staircase
       
   839     for i in range(5):
       
   840         forward(20)
       
   841         left(90)
       
   842         forward(20)
       
   843         right(90)
       
   844     # filled staircase
       
   845     fill(1)
       
   846     for i in range(5):
       
   847         forward(20)
       
   848         left(90)
       
   849         forward(20)
       
   850         right(90)
       
   851     fill(0)
       
   852     tracer(1)
       
   853     # more text
       
   854     write("end")
       
   855 
       
   856 def demo2():
       
   857     # exercises some new and improved features
       
   858     speed('fast')
       
   859     width(3)
       
   860 
       
   861     # draw a segmented half-circle
       
   862     setheading(towards(0,0))
       
   863     x,y = position()
       
   864     r = (x**2+y**2)**.5/2.0
       
   865     right(90)
       
   866     pendown = True
       
   867     for i in range(18):
       
   868         if pendown:
       
   869             up()
       
   870             pendown = False
       
   871         else:
       
   872             down()
       
   873             pendown = True
       
   874         circle(r,10)
       
   875     sleep(2)
       
   876 
       
   877     reset()
       
   878     left(90)
       
   879 
       
   880     # draw a series of triangles
       
   881     l = 10
       
   882     color("green")
       
   883     width(3)
       
   884     left(180)
       
   885     sp = 5
       
   886     for i in range(-2,16):
       
   887         if i > 0:
       
   888             color(1.0-0.05*i,0,0.05*i)
       
   889             fill(1)
       
   890             color("green")
       
   891         for j in range(3):
       
   892             forward(l)
       
   893             left(120)
       
   894         l += 10
       
   895         left(15)
       
   896         if sp > 0:
       
   897             sp = sp-1
       
   898             speed(speeds[sp])
       
   899     color(0.25,0,0.75)
       
   900     fill(0)
       
   901 
       
   902     # draw and fill a concave shape
       
   903     left(120)
       
   904     up()
       
   905     forward(70)
       
   906     right(30)
       
   907     down()
       
   908     color("red")
       
   909     speed("fastest")
       
   910     fill(1)
       
   911     for i in range(4):
       
   912         circle(50,90)
       
   913         right(90)
       
   914         forward(30)
       
   915         right(90)
       
   916     color("yellow")
       
   917     fill(0)
       
   918     left(90)
       
   919     up()
       
   920     forward(30)
       
   921     down();
       
   922 
       
   923     color("red")
       
   924 
       
   925     # create a second turtle and make the original pursue and catch it
       
   926     turtle=Turtle()
       
   927     turtle.reset()
       
   928     turtle.left(90)
       
   929     turtle.speed('normal')
       
   930     turtle.up()
       
   931     turtle.goto(280,40)
       
   932     turtle.left(24)
       
   933     turtle.down()
       
   934     turtle.speed('fast')
       
   935     turtle.color("blue")
       
   936     turtle.width(2)
       
   937     speed('fastest')
       
   938 
       
   939     # turn default turtle towards new turtle object
       
   940     setheading(towards(turtle))
       
   941     while ( abs(position()[0]-turtle.position()[0])>4 or
       
   942             abs(position()[1]-turtle.position()[1])>4):
       
   943         turtle.forward(3.5)
       
   944         turtle.left(0.6)
       
   945         # turn default turtle towards new turtle object
       
   946         setheading(towards(turtle))
       
   947         forward(4)
       
   948     write("CAUGHT! ", move=True)
       
   949 
       
   950 
       
   951 
       
   952 if __name__ == '__main__':
       
   953     demo()
       
   954     sleep(3)
       
   955     demo2()
       
   956     done()