19-Advanced Turtle Graphics

advertisement
Computer Science 111
Fundamentals of Programming I
Advanced Turtle Graphics
Recursive Patterns in Art and Nature
Recursive Patterns in Art
• The 20th century Dutch artist Piet Mondrian painted a
series of pictures that displayed abstract, rectangular
patterns of color
• Start with a single colored rectangle
• Subdivide the rectangle into two unequal parts (say, 1/3
and 2/3) and paint these in different colors
• Repeat this process until an aesthetically appropriate
“moment” is reached
Level 1: A Single
Filled Rectangle
Level 2: Split at the Aesthetically
Appropriate Spot
Level 3: Continue the
Same Process with Each Part
Level 4
Level 5
Level 6
Level 7
Level 8
Level 9
Design a Recursive Function
• The function expects a Turtle object, the corner points
of a rectangle, and the current level as arguments
• If the level is greater than 0
– Draw a filled rectangle with the given corner points
– Calculate the corner points of two new rectangles within the
current one and decrement the level by 1
– Call the function recursively to draw these two rectangles
Program Structure
from turtle import Turtle
import random
def drawRectangle(t, x1, y1, x2, y2):
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
t.pencolor(red, green, blue)
# Code for drawing goes here
# Definition of the recursive mondrian function goes here
def main(level = 1):
t = Turtle()
t.speed(0)
t.hideturtle()
x = 50
y = 50
mondrian(t, -x, y, x, -y, level)
The mondrian Function
def mondrian(t, x1, y1, x2, y2, level):
if level > 0:
drawRectangle(t, x1, y1, x2, y2)
vertical = random.randint(1, 2)
if vertical == 1:
# Vertical split
mondrian(t, x1, y1, (x2 - x1) // 3 + x1, y2,
level - 1)
mondrian(t, (x2 - x1) // 3 + x1, y1, x2, y2,
level - 1)
else:
# Horizontal split
mondrian(t, x1, y1, x2, (y2 - y1) // 3 + y1,
level - 1)
mondrian(t, x1, (y2 - y1) // 3 + y1, x2, y2,
level - 1)
Recursive Patterns in Nature
• A fractal is a mathematical object that
exhibits the same pattern when it is
examined in greater detail
• Many natural phenomena, such as
coastlines and mountain ranges, exhibit
fractal patterns
The C-curve
• A C-curve is a fractal pattern
• A level 0 C-curve is a vertical line segment
• A level 1 C-curve is obtained by bisecting a level
0 C-curve and joining the sections at right angles
• A level N C-curve is obtained by joining two
level N - 1 C-curves at right angles
Level 0 and Level 1
(50,50)
(50,50)
(0,0)
(50,-50)
(50,-50)
drawLine(50, -50, 50, 50)
drawLine(50, -50, 0, 0)
drawLine(0, 0, 50, 50)
Bisecting and Joining
(50,50)
(50,50)
(0,0)
(50,-50)
drawLine(50, -50, 50, 50)
(50,-50)
0 = (50 + 50 + -50 - 50) // 2
0 = (50 + -50 + 50 - 50) // 2
drawLine(50, -50, 0, 0)
drawLine(0, 0, 50, 50)
Generalizing
(50,50)
(50,50)
(0,0)
(50,-50)
drawLine(x1, y1, x2, y2)
(50,-50)
xm = (x1 + x2 + y1 ym = (x2 + y1 + y2 drawLine(x1, y1, xm,
drawLine(xm, ym, x2,
y2) // 2
x1) // 2
ym)
y2)
Recursing
(50,50)
(50,50)
(0,0)
(50,-50)
drawLine(x1, y1, x2, y2)
Base case
(50,-50)
xm = (x1 +
ym = (x2 +
cCurve(x1,
CCurve(xm,
x2 + y1
y1 + y2
y1, xm,
ym, x2,
Recursive step
- y2) // 2
- x1) // 2
ym)
y2)
The cCurve Function
def cCurve(t, x1, y1, x2, y2, level):
if level == 0:
drawLine(t, x1, y1, x2, y2)
else:
xm = (x1 + x2 + y1 - y2) // 2
ym = (x2 + y1 + y2 - x1) // 2
cCurve(t, x1, y1, xm, ym, level - 1)
cCurve(t, xm, ym, x2, y2, level - 1)
Note that recursive calls occur before any C-curve is drawn
when level > 0
Program Structure
from turtle import Turtle
def drawLine(t, x1, y1, x2, y2):
"""Draws a line segment between the endpoints."""
t.up()
t.goto(x1, y1)
t.down()
t.goto(x2, y2)
# Definition of the recursive cCurve function goes here
def main(level = 1):
t = Turtle()
t.speed(0)
t.hideturtle()
cCurve(t, 50, -50, 50, 50, level)
Call Tree for ccurve(0)
A call tree diagram shows the number of calls of a
function for a given argument value
ccurve
ccurve(0) uses one call, the top-level one
Call Tree for ccurve(1)
ccurve
ccurve
ccurve
ccurve(1) uses three calls, a top-level one and two
recursive calls
Call Tree for ccurve(2)
ccurve(2) uses 7 calls, a top-level one and 6
recursive calls
ccurve
ccurve
ccurve
ccurve
ccurve
ccurve
ccurve
Call Tree for ccurve(n)
ccurve(n) uses 2n+1 - 1 calls, a top-level one and 2n+1 - 2
recursive calls
ccurve
ccurve
ccurve
ccurve
ccurve
ccurve
ccurve
Call Tree for ccurve(2)
The number of line segments drawn equals the
number of calls on the frontier of the tree (2n)
ccurve
ccurve
ccurve
ccurve
ccurve
ccurve
ccurve
Summary
• A recursive algorithm passes the buck repeatedly to the
same function
• Recursive algorithms are well-suited for solving problems
in domains that exhibit recursive patterns
• Recursive strategies can be used to simplify complex
solutions to difficult problems
For Next Week
Finish Chapter 7
Download