# Students: from samples import * import turtle def draw(tree, xScale, yScale, parentTime): """Draw the tree centered to the right of the current position, such that leaves end up separated vertically by yScale, and levels separated horizontally by xScale. The evolutionary time of the parent is the final parameter. """ # name the three pieces of the tuple label,first,second = tree isInternal = (first != ()) # by convention myTime = label if isInternal else 0 distance = (parentTime-myTime) * xScale # advance to node and draw label advance(distance) if isInternal: # if there are subtrees, draw those a = leafCount(first) b = leafCount(second) n = a + b lateral(-b/2 * yScale) draw(first, xScale, yScale, label) # recurse lateral(n/2 * yScale) draw(second, xScale, yScale, label) # recurse lateral(-a/2 * yScale) else: drawLabel(yScale, label) # remember to retreat from the node advance(-distance) #============================================================== def advance(distance): """Move forward given distance in current direction.""" turtle.forward(distance) def lateral(distance): """Assuming turtle starts (and ends) with rightward orientation, implement a vertical move of given distance. Positive value is oriented as downward. """ turtle.right(90) turtle.forward(distance) turtle.left(90) #=========== some utility functions we've written ============= _textLabels = [] def drawLabel(yScale,label): fontSize = round(0.9*yScale) turtle.penup() turtle.forward(10) version = turtle.TK.TclVersion if version < 3.55: turtle.write( ' '+str(label)[:5], font=("Arial", fontSize, "normal")) else: # following only works with Tcl 8.6 c = turtle.getcanvas() p = turtle.pos() a = turtle.heading() _textLabels.append(c.create_text(p[0],-p[1], text=label, angle=a, anchor = 'w', font=("Arial", fontSize, "normal"))) turtle.forward(-10) turtle.pendown() def leafCount(tree): """Return number of leaves of the tree.""" root,first,second = tree # unpack the tuple if first == second == (): return 1 # tree with one node else: return leafCount(first) + leafCount(second) def reset(): """Reset the state of the turtle canvas and position.""" c = turtle.getcanvas() for t in _textLabels: c.delete(t) turtle.clear() turtle.up() turtle.goto(0,0) # center of canvas turtle.down() turtle.setheading(0) reset() # reset on startup def savePostscript(filename): turtle.getscreen().getcanvas().postscript(file=filename) #==============================================================