Prelab 2 Notes

Here we discuss an interesting problem that has parallels with the work you are doing this week for Prelab 2 and Lab 2. There is nothing to turn in for this write-up – it is just for extra practice.

Enhancing our drawings

We saw that we can control the direction and angle of the drawing pen. What else can we control to enhance our square? Let’s check out the docs. Here we change the color of the line to be red and set the color of the interior of our square to be yellow. The key for the “fill” is invoking begin_fill before you draw the shape and then end_fill after you draw the shape.

pencolor("red")
fillcolor("yellow")
begin_fill()

# draw square
for i in range(4):
    forward(side_length)
    right(90)

end_fill()

Drawing a golden spiral

What about more interesting shapes? Specifically a Fibonacci spiral. A Fibonacci spiral is created by inscribing quarter circles inside squares whose edge length increases as the Fibonacci sequence. Let’s implement a function golden_spiral that has two parameters, the starting radius of the spiral and the number segments, and draws a Fibonacci spiral.

We can do so with a three step process:

  1. Define the Fibonacci sequence, and calculate Fibonacci numbers with a loop
  2. Identify a function in turtle for drawing portions of a circle
  3. Integrate circle drawing into the Fibonacci loop

Here is an implementation:

def golden_spiral(radius, segments):
    """
    Draw a Fibonacci spiral using Turtle. turtle package must be imported into namespace.
    
    Args:
        radius: Starting radius of the spiral
        segments: Number of quarter circle segments to draw after initial quarter circle.
            Must be >= 2.
    
    Returns:
        None
    """
    a = radius
    circle(a, 90)    
    b = radius
    circle(b, 90)    
    for i in range(segments-2): # segments-2 since first two segments already drawn
        c = a + b        
        circle(c, 90)
        # Prepare for next iteration of the loop
        a = b
        b = c

Note that if we invoke the golden_spiral function several times, each new spiral starts from where the last one finished. This reminds us that the pen has “state”, specifically an x and y position and a heading. Controlling that state is a key part of the lab. How could we control where the drawing starts? That is how could we modify our function to start drawing the spiral at a specific location on the screen? That is how could we implement the function with the following header?

def golden_spiral(x, y, radius, segments):

We need a way move the pen around the page. If we review the docs, we that there is a function setpos that sounds like it will do exactly what we want. If we try that out in the shell, e.g.

>>> setpos(100, 100)

we notice that every time we move the pen it draws a line. If we think about we would draw this picture (with pen and paper), we would pick our hand up from the page before moving. Again returning to the docs, we see there is a function penup for picking the pen up and thus not drawing while moving. With those pieces we can now enhance our golden_spiral function to start drawing at an arbitrary location.

def golden_spiral(x, y, radius, segments):
    penup()
    setpos(x, y)
    pendown() # Need to put the pendown to start drawing again
    ...

Recall that pen (turtle) also has a heading that you will need to control in a similar way. I suspect you might find similar code at the beginning of several of your functions. If we find ourselves with repeated code, we can often DRY it up with a function.