Hi Vern, hi everybody!
I've had a look to turtlenew - which in fact has not very much new stuff ...
I provide a set of sample programs, sort of test, which I use to use as
test cases with my (X)turtle module - work inprogress .. I've modified
them, so they work with turtlenew.
Just save them together with turtlenew2.py in a directory and run them
from within IDLE (or uncomment the mainloop - call). All of them except
demo.py will also run with turtlenew.py
I've - as a proposition - added one function to turtlenew:
towards(*args), which returns the angle between the line from the turtle
to the arg and the positive x-axis-direction. As a demo it's used
in demo.py. (The idea is of course taken from Logo, where it is also
present) This method uses atan2. So it's not elementary and young
students won't be able to program it on their own. So I consider it
rather essential. (In fact I incorporated it also into my book-specific
turtle.py three years ago - which was also a moderate extension of the
original one.)
I've also changed one line in the speed-method just for aesthetic
reasons. (Line 317 intutlenew2.py)
If hope you appreciate these changes, and I'd like to see them
integrated into turtle.py
Imho there is one serious problem with circle and fill - they don't fit
together. You can observe this with the yinyang - program and with
demo.py . They simply do not work as everybody would naturally expect.
I fear this could only be solved by abandoning the use of the arc items
of the canvas widget.
Regards,
Gregor
--
Gregor Lingl
Reisnerstrasse 3/19
A-1030 Wien
Telefon: +43 1 713 33 98
Mobil: +43 664 140 35 27
Website: python4kids.net
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"edupython" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/edupython
-~----------~----~----~----~------~----~------~--~---
# Xturtle ==> turtle example
# yinyang
# NOTE: In the first import statement
# replace Xturtle by turtle to see, how
# the original turtle acts here.
from turtlenew2 import *
from Tkinter import mainloop
def yin(radius, farbe1, farbe2):
width(3)
color("black")
fill(1)
circle(radius/2., 180)
circle(radius, 180)
left(180)
circle(-radius/2., 180)
color(farbe1)
fill(1)
left(90)
up()
forward(radius*0.375)
right(90)
down()
circle(radius*0.125)
left(90)
color(farbe2)
fill(1)
up()
backward(radius*0.375)
down()
left(90)
reset()
yin(100, "white", "black")
yin(100, "black", "white")
#mainloop()
from turtlenew2 import *
from Tkinter import mainloop
from time import sleep
def demo1():
# demo des alten turtle-Moduls
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)
# more text
write("wait a moment...")
tracer(1)
def demo2():
# einige weitere und einige neue features
speed(1)
## st()
width(3)
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)
l = 10
color("green")
width(3)
left(180)
sp = 1
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 < 4:
sp = sp+1
speed(sp)
color(0.25,0,0.75)
fill(0)
color("green")
left(120)
up()
forward(70)
right(30)
down()
color("red")
speed(0)
fill(1)
for i in range(4):
circle(50,90)
right(90)
forward(30)
right(90)
color("yellow")
fill(0)
color("red")
left(90)
up(); forward(30); down(); # setshape(1)
## tri = turtles()[0]
turtle=Pen()
## turtle.setshape(1)
#### turtle.mode("logo")
turtle.reset()
turtle.left(90)
turtle.speed(2)
turtle.up()
turtle.goto(280,40)
turtle.left(24)
turtle.down()
turtle.speed(2)
turtle.color("blue")
turtle.width(2)
speed(4)
## setheading(towards(*turtle.position())) ## for simple towards
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)
## setheading(towards(*turtle.position()))
setheading(towards(turtle))
forward(4)
write("CAUGHT! ", move=True)
demo1()
demo2()
#mainloop()
## NT - Die neue Turtle-Grafik
##
#######################################
## Nfilltest.py ---
## urspruenglich ein Testprogramm in NT.py
#######################################
##
## Autor: Gregor Lingl
## Datum: 16. 3. 2006
from turtlenew2 import Pen
from Tkinter import mainloop
t = Pen()
t.left(90)
t.speed(1)
l = 210
t.up()
t.backward(20)
t.down()
## 1. triangle
t.right(30)
t.width(3)
t.fill(True)
for i in 1,2,3:
t.color("red")
t.forward(l/3.)
t.color("green")
t.forward(l/3.)
t.color("blue")
t.forward(l/3.)
t.left(120)
t.color(.8,.8,1)
t.fill(False)
t.left(30)
## 2. triangle
t.left(60)
t.color("blue")
t.fill(True)
t.width(10)
for i in 1,2,3:
t.forward(l)
t.left(120)
t.color("red")
t.fill(False)
t.left(30)
## 3. triangle
t.left(60)
t.up()
t.fill(True)
for i in 1,2,3:
t.forward(l)
t.left(120)
t.color(0.7,0,0.7)
t.fill(False)
t.down()
t.left(30)
## Change screencolor
# t.screen.screencolor("yellow")
## 4. triangle
t.left(60)
t.speed(1)
t.color("green")
t.fill(True)
for i in 1,2,3:
#if i==2: t.hideturtle()
t.width(2+3*i)
t.forward(l/3.0)
t.up()
t.left(60)
t.forward(l/6.0)
t.right(120)
t.forward(l/3.0)
t.left(120)
t.forward(l/6.0)
t.right(60)
t.down()
t.forward(l/3.0)
# if i==2: t.showturtle()
t.left(120)
t.color("red")
t.fill(True)
t.left(30)
## original heading
t.left(90)
t.speed(2)
t.up()
t.forward(l/3**0.5)
#mainloop()
# Autor: Rudolf Zeidler
# Datum: 01.12.2004
# radioaktiv.py: Zeichnet ein radioaktiv-Gefahrensymbol
# doesn't use the color-capabilities of Xturtle in order
# to work also with turtle.py
# NOTE: In the first import statement
# replace Xturtle by turtle to see, how
# (buggy) the turtle acts here, when trying to
# fill sectors
from turtlenew import *
from Tkinter import mainloop
def quadrat(laenge):
for i in range(4):
forward(laenge)
left(90)
def kreisSektor(radius, winkel):
forward(radius)
left(90)
circle(radius, winkel)
left(90)
forward(radius)
left(120)
def move(x, y):
up()
forward(x)
left(90)
forward(y)
left(-90)
down()
def radioaktiv(radius1, radius2, seite, winkel = 60, randFarbe = "black",
fuellFarbe = "yellow"):
color(randFarbe)
move(-(seite / 2) , -(seite / 2))
fill(1)
quadrat(seite)
color(fuellFarbe)
fill(0)
move((seite / 2), (seite / 2))
color(randFarbe)
right(90 + winkel / 2)
for i in range(3):
fill(1)
kreisSektor(radius1,winkel)
left((360 - 3 * winkel)/3 + 60)
color(randFarbe)
fill(0)
up()
forward(radius2)
left(90)
down()
color(fuellFarbe)
fill(1)
circle(radius2)
color(randFarbe)
fill(0)
up()
left(90)
forward(radius2)
width(1)
reset()
width(5)
radioaktiv(80, 15, 200)
#mainloop()
#Gregor Lingl
#14.12.2005
#sierpinski_dreieck.py
from turtlenew2 import *
from Tkinter import mainloop
class Vec3(tuple):
def __new__(cls, x, y, z):
return tuple.__new__(cls, (x, y, z))
def __add__(self, other):
return Vec3(self[0]+other[0], self[1]+other[1], self[2]+other[2])
def __mul__(self, other):
return Vec3(self[0]*other, self[1]*other, self[2]*other)
def __rmul__(self, other):
return Vec3(self[0]*other, self[1]*other, self[2]*other)
def __sub__(self, other):
return Vec3(self[0]-other[0], self[1]-other[1], self[2]-other[2])
def __div__(self, other):
other = float(other)
return Vec3(self[0]/other, self[1]/other, self[2]/other)
def __neg__(self):
return Vec3(-self[0], -self[1], -self[2])
def __repr__(self):
return "(%.2f,%.2f,%.2f)" % self
def dreieck(laenge, stufe, f1, f2, f3): # f1, f2, f3 Farben der Ecken
if stufe == 0:
color((f1+f2+f3)/3)
down()
fill(1)
for i in range(3):
forward(laenge)
left(120)
fill(0)
up()
else:
c12 = (f1+f2)/2
c13 = (f1+f3)/2
c23 = (f2+f3)/2
dreieck(laenge / 2, stufe - 1, f1, c12, c13)
forward(laenge)
left(120)
dreieck(laenge / 2, stufe - 1, f2, c23, c12)
forward(laenge)
left(120)
dreieck(laenge / 2, stufe - 1, f3, c13, c23)
forward(laenge)
left(120)
reset()
speed(0)
up()
backward(240)
left(90)
backward(200)
right(90)
down()
tracer(1)
speed(4)
dreieck(480, 5, Vec3(1.0,0,0), Vec3(0,1.0,0), Vec3(0,0,1.0))
#mainloop()
# LogoMation-like turtle graphics
from math import * # Also for export
import Tkinter
class Error(Exception):
pass
_delay = 10 # default delay for drawing
class RawPen:
def __init__(self, canvas):
self._canvas = canvas
self._items = []
self._tracing = 1
self._arrow = 0
self._delay = _delay
self.degrees()
self.reset()
def degrees(self, fullcircle=360.0):
self._fullcircle = fullcircle
self._invradian = pi / (fullcircle * 0.5)
def radians(self):
self.degrees(2.0*pi)
def reset(self):
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._tofill = []
self.clear()
canvas._root().tkraise()
def clear(self):
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):
self._tracing = flag
if not self._tracing:
self._delete_turtle()
self._draw_turtle()
def forward(self, distance):
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):
self.forward(-distance)
def left(self, angle):
self._angle = (self._angle + angle) % self._fullcircle
self._draw_turtle()
def right(self, angle):
self.left(-angle)
def up(self):
self._drawing = 0
def down(self):
self._drawing = 1
def width(self, width):
self._width = float(width)
def color(self, *args):
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, arg, move=0):
x, y = start = self._position
x = x-1 # correction -- calibrated for Windows
item = self._canvas.create_text(x, y,
text=str(arg), 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):
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)
if self._tofill:
for item in self._tofill:
self._canvas.itemconfigure(item, fill=self._color)
self._items.append(item)
self._path = []
self._tofill = []
self._filling = flag
if flag:
self._path.append(self._position)
self.forward(0)
def circle(self, radius, extent=None):
if extent is None:
extent = self._fullcircle
x0, y0 = self._position
xc = x0 - radius * sin(self._angle * self._invradian)
yc = y0 - radius * cos(self._angle * self._invradian)
if radius >= 0.0:
start = self._angle - 90.0
else:
start = self._angle + 90.0
extent = -extent
if self._filling:
if abs(extent) >= self._fullcircle:
item = self._canvas.create_oval(xc-radius, yc-radius,
xc+radius, yc+radius,
width=self._width,
outline="")
self._tofill.append(item)
item = self._canvas.create_arc(xc-radius, yc-radius,
xc+radius, yc+radius,
style="chord",
start=start,
extent=extent,
width=self._width,
outline="")
self._tofill.append(item)
if self._drawing:
if abs(extent) >= self._fullcircle:
item = self._canvas.create_oval(xc-radius, yc-radius,
xc+radius, yc+radius,
width=self._width,
outline=self._color)
self._items.append(item)
item = self._canvas.create_arc(xc-radius, yc-radius,
xc+radius, yc+radius,
style="arc",
start=start,
extent=extent,
width=self._width,
outline=self._color)
self._items.append(item)
angle = start + extent
x1 = xc + abs(radius) * cos(angle * self._invradian)
y1 = yc - abs(radius) * sin(angle * self._invradian)
self._angle = (self._angle + extent) % self._fullcircle
self._position = x1, y1
if self._filling:
self._path.append(self._position)
self._draw_turtle()
def heading(self):
return self._angle
def setheading(self, angle):
self._angle = angle
self._draw_turtle()
def window_width(self):
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):
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):
x0, y0 = self._origin
x1, y1 = self._position
return [x1-x0, -y1+y0]
def setx(self, xpos):
x0, y0 = self._origin
x1, y1 = self._position
self._goto(x0+xpos, y1)
def sety(self, ypos):
x0, y0 = self._origin
x1, y1 = self._position
self._goto(x1, y0-ypos)
def towards(self, *args):
"""returns 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.
"""
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):
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 = start = 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=2):
""" maps a speed in 4 to 0 to delay given _canvas.after() in
_goto()
4 is fastests (0 ms delay)
2 is default (10 ms delay)
0 is slowest (20 ms delay)"""
## if speed >=0 and speed <=4: ## more elegantly:
if 0 <= speed <=4:
self._delay = 20 - (speed * 5)
def _draw_turtle(self,position=[]):
if not self._tracing:
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 for width
_height = 0.75 # 75% of window for height
_startx = 0 # start at upper left corner
_starty = 0
_title = "Turtle Graphics" # default title
class Pen(RawPen):
def __init__(self):
global _root, _canvas, _width, _height
if _root is None:
_root = Tkinter.Tk()
_root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
_root.title(_title)
if _width <= 1:
_width = _root.winfo_screenwidth() * _width
if _height <= 1:
_height = _root.winfo_screenheight() * _height
_root.geometry("%dx%d+%d+%d" % (_width, _height,
_startx, _starty))
if _canvas is None:
# XXX Should have scroll bars
_canvas = Tkinter.Canvas(_root, background="white")
_canvas.pack(expand=1, fill="both")
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
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 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 speed(speed=2): _getpen().speed(speed)
def setup(geometry=()):
global _width, _height, _startx, _starty
if len(geometry) == 4:
_width, _height, _startx, _starty = geometry
def title(title):
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)
# more text
write("end")
if __name__ == '__main__':
_root.mainloop()
if __name__ == '__main__':
demo()