CSCI 150 - Foundations of Computer Science

Spring 2012

Homework 13: Fractals

In this assignment, you will use Pygame to create L-System Fractals.

Fractal Definitions

After completing the implementation as described below, you should be able to define a fractal in a manner similar to what you see in the files below. Be sure to compare the code with the mathematical definitions from the lecture, to see how they fit together. I have provided for you the Python definitions for the dragon curves. The images on the fractal description pages were generated by my solution to this assignment. Once you have completed the rest of the assignment, and you are able to run these two programs, you are to create the snowflake and triangle fractals as well, using the other files as guides.

Functions

Each of the following functions will be saved in a file named fractals.py.

Classes

Each of these classes will also be saved in fractals.py, alongside the above functions.

The Turtle Class

Complete the implementation of the Turtle class. Objects of this class represent a directional drawing cursor.
class Turtle(object):
    def __init__(self):
        self.pos = (0, 0)
        self.heading = 0
    
    # Update the position following the heading.
    # Assume a speed of 1.
    def move(self):
        
    # Adjust the heading by angle
    def turn(self, angle):
        
    # Teleport the turtle to the given position with the given heading
    def teleport(self, pos, heading):

Testing the Turtle class

>>> t = Turtle()
>>> t.move()
>>> t.pos
(1.0, 0.0)
>>> t.turn(math.pi/2)
>>> t.move()
>>> t.pos
(1.0, 1.0)
>>> t.turn(-math.pi/6)
>>> t.move()
>>> t.pos
(1.5, 1.8660254037844388)

The Fractal Class

Complete the implementation of the Fractal class. Objects of this class represent the current state and the grammar for an L-System fractal.
class Fractal(object):
    def __init__(self, start, productions):
        self.state = start
        self.productions = productions
        
    # Update the state to reflect n applications of the productions.
    def iterate(self, n):
        pass
            
    # Return a list of points corresponding to each location a Turtle
    # would visit if traversing this Fractal.  The points should be 
    # centered in the given area.
    #
    # Create a Turtle object.  It will be the parameter for each of the 
    # functions in the productions.
    #
    # You may find movePoints() to be helpful in your solution.
    #
    # You might also find helpful an example of calling functions from a list.
    def points(self, area):
        pass

Testing the Fractal class

The following transcript shows how to test the iterate() method.
>>> f = Fractal([0], {0:[0,1,0,2,0]})
>>> f.iterate(2)
>>> f.state
[0, 1, 0, 2, 0, 1, 0, 1, 0, 2, 0, 2, 0, 1, 0, 2, 0]
>>> f.iterate(1)
>>> f.state
[0, 1, 0, 2, 0, 1, 0, 1, 0, 2, 0, 2, 0, 1, 0, 2, 0, 1, 0, 1, 0, 2, 0, 1, 0, 1, 0, 2, 0, 2, 0, 1, 0, 2, 0, 2, 0, 1, 0, 2, 0, 1, 0, 1, 0, 2, 0, 2, 0, 1, 0, 2, 0]
>>> g = Fractal([0,1], {1:[1,2,3,0], 3:[0,1,4,3]})
>>> g.iterate(1)
>>> g.state
[0, 1, 2, 3, 0]
>>> g.iterate(1)
>>> g.state
[0, 1, 2, 3, 0, 2, 0, 1, 4, 3, 0]
>>> g.iterate(1)
>>> g.state
[0, 1, 2, 3, 0, 2, 0, 1, 4, 3, 0, 2, 0, 1, 2, 3, 0, 4, 0, 1, 4, 3, 0]
The points() method is most easily tested by using one of terdragon.py or dragon.py.

The Event Loop

You should copy and paste the following function into fractals.py. It will serve as the event loop for displaying the fractals.
def render(fractal, n, size = (400,400), background=(0,0,255), foreground=(255,255,255)):
    pygame.init()
    screen = pygame.display.set_mode(size)
    fractal.iterate(n)
    points = fractal.points(size)
    print("Rendered", len(points), "points")
    running = True
    
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            else:
                screen.fill(background)
                pygame.draw.lines(screen, foreground, False, points)
                pygame.display.flip()
                
    pygame.quit()

Grading