summaryrefslogtreecommitdiffstats
path: root/Lib/lib-tk/turtle.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/lib-tk/turtle.py')
-rw-r--r--Lib/lib-tk/turtle.py956
1 files changed, 0 insertions, 956 deletions
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
deleted file mode 100644
index e4cac29..0000000
--- a/Lib/lib-tk/turtle.py
+++ /dev/null
@@ -1,956 +0,0 @@
-# LogoMation-like turtle graphics
-
-"""
-Turtle graphics is a popular way for introducing programming to
-kids. It was part of the original Logo programming language developed
-by Wally Feurzeig and Seymour Papert in 1966.
-
-Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
-the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
-the direction it is facing, drawing a line as it moves. Give it the
-command turtle.left(25), and it rotates in-place 25 degrees clockwise.
-
-By combining together these and similar commands, intricate shapes and
-pictures can easily be drawn.
-"""
-
-from math import * # Also for export
-from time import sleep
-import Tkinter
-
-speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
-
-class Error(Exception):
- pass
-
-class RawPen:
-
- def __init__(self, canvas):
- self._canvas = canvas
- self._items = []
- self._tracing = 1
- self._arrow = 0
- self._delay = 10 # default delay for drawing
- self._angle = 0.0
- self.degrees()
- self.reset()
-
- def degrees(self, fullcircle=360.0):
- """ Set angle measurement units to degrees.
-
- Example:
- >>> turtle.degrees()
- """
- # Don't try to change _angle if it is 0, because
- # _fullcircle might not be set, yet
- if self._angle:
- self._angle = (self._angle / self._fullcircle) * fullcircle
- self._fullcircle = fullcircle
- self._invradian = pi / (fullcircle * 0.5)
-
- def radians(self):
- """ Set the angle measurement units to radians.
-
- Example:
- >>> turtle.radians()
- """
- self.degrees(2.0*pi)
-
- def reset(self):
- """ Clear the screen, re-center the pen, and set variables to
- the default values.
-
- Example:
- >>> turtle.position()
- [0.0, -22.0]
- >>> turtle.heading()
- 100.0
- >>> turtle.reset()
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.heading()
- 0.0
- """
- canvas = self._canvas
- self._canvas.update()
- width = canvas.winfo_width()
- height = canvas.winfo_height()
- if width <= 1:
- width = canvas['width']
- if height <= 1:
- height = canvas['height']
- self._origin = float(width)/2.0, float(height)/2.0
- self._position = self._origin
- self._angle = 0.0
- self._drawing = 1
- self._width = 1
- self._color = "black"
- self._filling = 0
- self._path = []
- self.clear()
- canvas._root().tkraise()
-
- def clear(self):
- """ Clear the screen. The turtle does not move.
-
- Example:
- >>> turtle.clear()
- """
- self.fill(0)
- canvas = self._canvas
- items = self._items
- self._items = []
- for item in items:
- canvas.delete(item)
- self._delete_turtle()
- self._draw_turtle()
-
- def tracer(self, flag):
- """ Set tracing on if flag is True, and off if it is False.
- Tracing means line are drawn more slowly, with an
- animation of an arrow along the line.
-
- Example:
- >>> turtle.tracer(False) # turns off Tracer
- """
- self._tracing = flag
- if not self._tracing:
- self._delete_turtle()
- self._draw_turtle()
-
- def forward(self, distance):
- """ Go forward distance steps.
-
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.forward(25)
- >>> turtle.position()
- [25.0, 0.0]
- >>> turtle.forward(-75)
- >>> turtle.position()
- [-50.0, 0.0]
- """
- x0, y0 = start = self._position
- x1 = x0 + distance * cos(self._angle*self._invradian)
- y1 = y0 - distance * sin(self._angle*self._invradian)
- self._goto(x1, y1)
-
- def backward(self, distance):
- """ Go backwards distance steps.
-
- The turtle's heading does not change.
-
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.backward(30)
- >>> turtle.position()
- [-30.0, 0.0]
- """
- self.forward(-distance)
-
- def left(self, angle):
- """ Turn left angle units (units are by default degrees,
- but can be set via the degrees() and radians() functions.)
-
- When viewed from above, the turning happens in-place around
- its front tip.
-
- Example:
- >>> turtle.heading()
- 22
- >>> turtle.left(45)
- >>> turtle.heading()
- 67.0
- """
- self._angle = (self._angle + angle) % self._fullcircle
- self._draw_turtle()
-
- def right(self, angle):
- """ Turn right angle units (units are by default degrees,
- but can be set via the degrees() and radians() functions.)
-
- When viewed from above, the turning happens in-place around
- its front tip.
-
- Example:
- >>> turtle.heading()
- 22
- >>> turtle.right(45)
- >>> turtle.heading()
- 337.0
- """
- self.left(-angle)
-
- def up(self):
- """ Pull the pen up -- no drawing when moving.
-
- Example:
- >>> turtle.up()
- """
- self._drawing = 0
-
- def down(self):
- """ Put the pen down -- draw when moving.
-
- Example:
- >>> turtle.down()
- """
- self._drawing = 1
-
- def width(self, width):
- """ Set the line to thickness to width.
-
- Example:
- >>> turtle.width(10)
- """
- self._width = float(width)
-
- def color(self, *args):
- """ Set the pen color.
-
- Three input formats are allowed:
-
- color(s)
- s is a Tk specification string, such as "red" or "yellow"
-
- color((r, g, b))
- *a tuple* of r, g, and b, which represent, an RGB color,
- and each of r, g, and b are in the range [0..1]
-
- color(r, g, b)
- r, g, and b represent an RGB color, and each of r, g, and b
- are in the range [0..1]
-
- Example:
-
- >>> turtle.color('brown')
- >>> tup = (0.2, 0.8, 0.55)
- >>> turtle.color(tup)
- >>> turtle.color(0, .5, 0)
- """
- if not args:
- raise Error, "no color arguments"
- if len(args) == 1:
- color = args[0]
- if type(color) == type(""):
- # Test the color first
- try:
- id = self._canvas.create_line(0, 0, 0, 0, fill=color)
- except Tkinter.TclError:
- raise Error, "bad color string: %r" % (color,)
- self._set_color(color)
- return
- try:
- r, g, b = color
- except:
- raise Error, "bad color sequence: %r" % (color,)
- else:
- try:
- r, g, b = args
- except:
- raise Error, "bad color arguments: %r" % (args,)
- assert 0 <= r <= 1
- assert 0 <= g <= 1
- assert 0 <= b <= 1
- x = 255.0
- y = 0.5
- self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
-
- def _set_color(self,color):
- self._color = color
- self._draw_turtle()
-
- def write(self, text, move=False):
- """ Write text at the current pen position.
-
- If move is true, the pen is moved to the bottom-right corner
- of the text. By default, move is False.
-
- Example:
- >>> turtle.write('The race is on!')
- >>> turtle.write('Home = (0, 0)', True)
- """
- x, y = self._position
- x = x-1 # correction -- calibrated for Windows
- item = self._canvas.create_text(x, y,
- text=str(text), anchor="sw",
- fill=self._color)
- self._items.append(item)
- if move:
- x0, y0, x1, y1 = self._canvas.bbox(item)
- self._goto(x1, y1)
- self._draw_turtle()
-
- def fill(self, flag):
- """ Call fill(1) before drawing the shape you
- want to fill, and fill(0) when done.
-
- Example:
- >>> turtle.fill(1)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.fill(0)
- """
- if self._filling:
- path = tuple(self._path)
- smooth = self._filling < 0
- if len(path) > 2:
- item = self._canvas._create('polygon', path,
- {'fill': self._color,
- 'smooth': smooth})
- self._items.append(item)
- self._path = []
- self._filling = flag
- if flag:
- self._path.append(self._position)
-
- def begin_fill(self):
- """ Called just before drawing a shape to be filled.
- Must eventually be followed by a corresponding end_fill() call.
- Otherwise it will be ignored.
-
- Example:
- >>> turtle.begin_fill()
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.end_fill()
- """
- self._path = [self._position]
- self._filling = 1
-
- def end_fill(self):
- """ Called after drawing a shape to be filled.
-
- Example:
- >>> turtle.begin_fill()
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.end_fill()
- """
- self.fill(0)
-
- def circle(self, radius, extent = None):
- """ Draw a circle with given radius.
- The center is radius units left of the turtle; extent
- determines which part of the circle is drawn. If not given,
- the entire circle is drawn.
-
- If extent is not a full circle, one endpoint of the arc is the
- current pen position. The arc is drawn in a counter clockwise
- direction if radius is positive, otherwise in a clockwise
- direction. In the process, the direction of the turtle is
- changed by the amount of the extent.
-
- >>> turtle.circle(50)
- >>> turtle.circle(120, 180) # half a circle
- """
- if extent is None:
- extent = self._fullcircle
- frac = abs(extent)/self._fullcircle
- steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
- w = 1.0 * extent / steps
- w2 = 0.5 * w
- l = 2.0 * radius * sin(w2*self._invradian)
- if radius < 0:
- l, w, w2 = -l, -w, -w2
- self.left(w2)
- for i in range(steps):
- self.forward(l)
- self.left(w)
- self.right(w2)
-
- def heading(self):
- """ Return the turtle's current heading.
-
- Example:
- >>> turtle.heading()
- 67.0
- """
- return self._angle
-
- def setheading(self, angle):
- """ Set the turtle facing the given angle.
-
- Here are some common directions in degrees:
-
- 0 - east
- 90 - north
- 180 - west
- 270 - south
-
- Example:
- >>> turtle.setheading(90)
- >>> turtle.heading()
- 90
- >>> turtle.setheading(128)
- >>> turtle.heading()
- 128
- """
- self._angle = angle
- self._draw_turtle()
-
- def window_width(self):
- """ Returns the width of the turtle window.
-
- Example:
- >>> turtle.window_width()
- 640
- """
- width = self._canvas.winfo_width()
- if width <= 1: # the window isn't managed by a geometry manager
- width = self._canvas['width']
- return width
-
- def window_height(self):
- """ Return the height of the turtle window.
-
- Example:
- >>> turtle.window_height()
- 768
- """
- height = self._canvas.winfo_height()
- if height <= 1: # the window isn't managed by a geometry manager
- height = self._canvas['height']
- return height
-
- def position(self):
- """ Return the current (x, y) location of the turtle.
-
- Example:
- >>> turtle.position()
- [0.0, 240.0]
- """
- x0, y0 = self._origin
- x1, y1 = self._position
- return [x1-x0, -y1+y0]
-
- def setx(self, xpos):
- """ Set the turtle's x coordinate to be xpos.
-
- Example:
- >>> turtle.position()
- [10.0, 240.0]
- >>> turtle.setx(10)
- >>> turtle.position()
- [10.0, 240.0]
- """
- x0, y0 = self._origin
- x1, y1 = self._position
- self._goto(x0+xpos, y1)
-
- def sety(self, ypos):
- """ Set the turtle's y coordinate to be ypos.
-
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.sety(-22)
- >>> turtle.position()
- [0.0, -22.0]
- """
- x0, y0 = self._origin
- x1, y1 = self._position
- self._goto(x1, y0-ypos)
-
- def towards(self, *args):
- """Returs the angle, which corresponds to the line
- from turtle-position to point (x,y).
-
- Argument can be two coordinates or one pair of coordinates
- or a RawPen/Pen instance.
-
- Example:
- >>> turtle.position()
- [10.0, 10.0]
- >>> turtle.towards(0,0)
- 225.0
- """
- if len(args) == 2:
- x, y = args
- else:
- arg = args[0]
- if isinstance(arg, RawPen):
- x, y = arg.position()
- else:
- x, y = arg
- x0, y0 = self.position()
- dx = x - x0
- dy = y - y0
- return (atan2(dy,dx) / self._invradian) % self._fullcircle
-
- def goto(self, *args):
- """ Go to the given point.
-
- If the pen is down, then a line will be drawn. The turtle's
- orientation does not change.
-
- Two input formats are accepted:
-
- goto(x, y)
- go to point (x, y)
-
- goto((x, y))
- go to point (x, y)
-
- Example:
- >>> turtle.position()
- [0.0, 0.0]
- >>> turtle.goto(50, -45)
- >>> turtle.position()
- [50.0, -45.0]
- """
- if len(args) == 1:
- try:
- x, y = args[0]
- except:
- raise Error, "bad point argument: %r" % (args[0],)
- else:
- try:
- x, y = args
- except:
- raise Error, "bad coordinates: %r" % (args[0],)
- x0, y0 = self._origin
- self._goto(x0+x, y0-y)
-
- def _goto(self, x1, y1):
- x0, y0 = self._position
- self._position = map(float, (x1, y1))
- if self._filling:
- self._path.append(self._position)
- if self._drawing:
- if self._tracing:
- dx = float(x1 - x0)
- dy = float(y1 - y0)
- distance = hypot(dx, dy)
- nhops = int(distance)
- item = self._canvas.create_line(x0, y0, x0, y0,
- width=self._width,
- capstyle="round",
- fill=self._color)
- try:
- for i in range(1, 1+nhops):
- x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
- self._canvas.coords(item, x0, y0, x, y)
- self._draw_turtle((x,y))
- self._canvas.update()
- self._canvas.after(self._delay)
- # in case nhops==0
- self._canvas.coords(item, x0, y0, x1, y1)
- self._canvas.itemconfigure(item, arrow="none")
- except Tkinter.TclError:
- # Probably the window was closed!
- return
- else:
- item = self._canvas.create_line(x0, y0, x1, y1,
- width=self._width,
- capstyle="round",
- fill=self._color)
- self._items.append(item)
- self._draw_turtle()
-
- def speed(self, speed):
- """ Set the turtle's speed.
-
- speed must one of these five strings:
-
- 'fastest' is a 0 ms delay
- 'fast' is a 5 ms delay
- 'normal' is a 10 ms delay
- 'slow' is a 15 ms delay
- 'slowest' is a 20 ms delay
-
- Example:
- >>> turtle.speed('slow')
- """
- try:
- speed = speed.strip().lower()
- self._delay = speeds.index(speed) * 5
- except:
- raise ValueError("%r is not a valid speed. speed must be "
- "one of %s" % (speed, speeds))
-
-
- def delay(self, delay):
- """ Set the drawing delay in milliseconds.
-
- This is intended to allow finer control of the drawing speed
- than the speed() method
-
- Example:
- >>> turtle.delay(15)
- """
- if int(delay) < 0:
- raise ValueError("delay must be greater than or equal to 0")
- self._delay = int(delay)
-
- def _draw_turtle(self, position=[]):
- if not self._tracing:
- self._canvas.update()
- return
- if position == []:
- position = self._position
- x,y = position
- distance = 8
- dx = distance * cos(self._angle*self._invradian)
- dy = distance * sin(self._angle*self._invradian)
- self._delete_turtle()
- self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
- width=self._width,
- arrow="last",
- capstyle="round",
- fill=self._color)
- self._canvas.update()
-
- def _delete_turtle(self):
- if self._arrow != 0:
- self._canvas.delete(self._arrow)
- self._arrow = 0
-
-
-_root = None
-_canvas = None
-_pen = None
-_width = 0.50 # 50% of window width
-_height = 0.75 # 75% of window height
-_startx = None
-_starty = None
-_title = "Turtle Graphics" # default title
-
-class Pen(RawPen):
-
- def __init__(self):
- global _root, _canvas
- if _root is None:
- _root = Tkinter.Tk()
- _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
- _root.title(_title)
-
- if _canvas is None:
- # XXX Should have scroll bars
- _canvas = Tkinter.Canvas(_root, background="white")
- _canvas.pack(expand=1, fill="both")
-
- setup(width=_width, height= _height, startx=_startx, starty=_starty)
-
- RawPen.__init__(self, _canvas)
-
- def _destroy(self):
- global _root, _canvas, _pen
- root = self._canvas._root()
- if root is _root:
- _pen = None
- _root = None
- _canvas = None
- root.destroy()
-
-def _getpen():
- global _pen
- if not _pen:
- _pen = Pen()
- return _pen
-
-class Turtle(Pen):
- pass
-
-"""For documentation of the following functions see
- the RawPen methods with the same names
-"""
-
-def degrees(): _getpen().degrees()
-def radians(): _getpen().radians()
-def reset(): _getpen().reset()
-def clear(): _getpen().clear()
-def tracer(flag): _getpen().tracer(flag)
-def forward(distance): _getpen().forward(distance)
-def backward(distance): _getpen().backward(distance)
-def left(angle): _getpen().left(angle)
-def right(angle): _getpen().right(angle)
-def up(): _getpen().up()
-def down(): _getpen().down()
-def width(width): _getpen().width(width)
-def color(*args): _getpen().color(*args)
-def write(arg, move=0): _getpen().write(arg, move)
-def fill(flag): _getpen().fill(flag)
-def begin_fill(): _getpen().begin_fill()
-def end_fill(): _getpen().end_fill()
-def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): _getpen().goto(*args)
-def heading(): return _getpen().heading()
-def setheading(angle): _getpen().setheading(angle)
-def position(): return _getpen().position()
-def window_width(): return _getpen().window_width()
-def window_height(): return _getpen().window_height()
-def setx(xpos): _getpen().setx(xpos)
-def sety(ypos): _getpen().sety(ypos)
-def towards(*args): return _getpen().towards(*args)
-
-def done(): _root.mainloop()
-def delay(delay): return _getpen().delay(delay)
-def speed(speed): return _getpen().speed(speed)
-
-for methodname in dir(RawPen):
- """ copies RawPen docstrings to module functions of same name """
- if not methodname.startswith("_"):
- eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
-
-
-def setup(**geometry):
- """ Sets the size and position of the main window.
-
- Keywords are width, height, startx and starty:
-
- width: either a size in pixels or a fraction of the screen.
- Default is 50% of screen.
- height: either the height in pixels or a fraction of the screen.
- Default is 75% of screen.
-
- Setting either width or height to None before drawing will force
- use of default geometry as in older versions of turtle.py
-
- startx: starting position in pixels from the left edge of the screen.
- Default is to center window. Setting startx to None is the default
- and centers window horizontally on screen.
-
- starty: starting position in pixels from the top edge of the screen.
- Default is to center window. Setting starty to None is the default
- and centers window vertically on screen.
-
- Examples:
- >>> setup (width=200, height=200, startx=0, starty=0)
-
- sets window to 200x200 pixels, in upper left of screen
-
- >>> setup(width=.75, height=0.5, startx=None, starty=None)
-
- sets window to 75% of screen by 50% of screen and centers
-
- >>> setup(width=None)
-
- forces use of default geometry as in older versions of turtle.py
- """
-
- global _width, _height, _startx, _starty
-
- width = geometry.get('width',_width)
- if width >= 0 or width is None:
- _width = width
- else:
- raise ValueError, "width can not be less than 0"
-
- height = geometry.get('height',_height)
- if height >= 0 or height is None:
- _height = height
- else:
- raise ValueError, "height can not be less than 0"
-
- startx = geometry.get('startx', _startx)
- if startx >= 0 or startx is None:
- _startx = _startx
- else:
- raise ValueError, "startx can not be less than 0"
-
- starty = geometry.get('starty', _starty)
- if starty >= 0 or starty is None:
- _starty = starty
- else:
- raise ValueError, "startx can not be less than 0"
-
-
- if _root and _width and _height:
- if 0 < _width <= 1:
- _width = _root.winfo_screenwidth() * +width
- if 0 < _height <= 1:
- _height = _root.winfo_screenheight() * _height
-
- # center window on screen
- if _startx is None:
- _startx = (_root.winfo_screenwidth() - _width) / 2
-
- if _starty is None:
- _starty = (_root.winfo_screenheight() - _height) / 2
-
- _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
-
-def title(title):
- """Set the window title.
-
- By default this is set to 'Turtle Graphics'
-
- Example:
- >>> title("My Window")
- """
-
- global _title
- _title = title
-
-def demo():
- reset()
- tracer(1)
- up()
- backward(100)
- down()
- # draw 3 squares; the last filled
- width(3)
- for i in range(3):
- if i == 2:
- fill(1)
- for j in range(4):
- forward(20)
- left(90)
- if i == 2:
- color("maroon")
- fill(0)
- up()
- forward(30)
- down()
- width(1)
- color("black")
- # move out of the way
- tracer(0)
- up()
- right(90)
- forward(100)
- right(90)
- forward(100)
- right(180)
- down()
- # some text
- write("startstart", 1)
- write("start", 1)
- color("red")
- # staircase
- for i in range(5):
- forward(20)
- left(90)
- forward(20)
- right(90)
- # filled staircase
- fill(1)
- for i in range(5):
- forward(20)
- left(90)
- forward(20)
- right(90)
- fill(0)
- tracer(1)
- # more text
- write("end")
-
-def demo2():
- # exercises some new and improved features
- speed('fast')
- width(3)
-
- # draw a segmented half-circle
- setheading(towards(0,0))
- x,y = position()
- r = (x**2+y**2)**.5/2.0
- right(90)
- pendown = True
- for i in range(18):
- if pendown:
- up()
- pendown = False
- else:
- down()
- pendown = True
- circle(r,10)
- sleep(2)
-
- reset()
- left(90)
-
- # draw a series of triangles
- l = 10
- color("green")
- width(3)
- left(180)
- sp = 5
- for i in range(-2,16):
- if i > 0:
- color(1.0-0.05*i,0,0.05*i)
- fill(1)
- color("green")
- for j in range(3):
- forward(l)
- left(120)
- l += 10
- left(15)
- if sp > 0:
- sp = sp-1
- speed(speeds[sp])
- color(0.25,0,0.75)
- fill(0)
-
- # draw and fill a concave shape
- left(120)
- up()
- forward(70)
- right(30)
- down()
- color("red")
- speed("fastest")
- fill(1)
- for i in range(4):
- circle(50,90)
- right(90)
- forward(30)
- right(90)
- color("yellow")
- fill(0)
- left(90)
- up()
- forward(30)
- down();
-
- color("red")
-
- # create a second turtle and make the original pursue and catch it
- turtle=Turtle()
- turtle.reset()
- turtle.left(90)
- turtle.speed('normal')
- turtle.up()
- turtle.goto(280,40)
- turtle.left(24)
- turtle.down()
- turtle.speed('fast')
- turtle.color("blue")
- turtle.width(2)
- speed('fastest')
-
- # turn default turtle towards new turtle object
- setheading(towards(turtle))
- while ( abs(position()[0]-turtle.position()[0])>4 or
- abs(position()[1]-turtle.position()[1])>4):
- turtle.forward(3.5)
- turtle.left(0.6)
- # turn default turtle towards new turtle object
- setheading(towards(turtle))
- forward(4)
- write("CAUGHT! ", move=True)
-
-
-
-if __name__ == '__main__':
- demo()
- sleep(3)
- demo2()
- done()