Lab 5: Fractals

This assignment assumes that you have read up through Chapter 5, in particular sections 5.14 and 5.15 on recursion. Please bring your book to lab, as you will need it as a reference. Each lab assignment is more work than the previous one, so get started early.

The objectives for this assignment are for you to:

  • Get lots of practice in designing and debugging recursive functions.
  • Get more practice writing event driven and graphical programs.
  • Have some fun with fractals.
  • Pre-Lab Exercise

  • Watch this episode of Nova: Fractals: Hunting the Hidden Dimension (about 54 minutes)
  • Suggested Reading

  • Mandelbrot and Freeman, The Fractal Geometry of Nature. W.H. Freeman, 1983. ISBN: 0716711869.
  • Getting Started

    As in the previous lab, start by creating a directory just for this assignment, and changing to that directory:
    mkdir cse20211/lab5
    cd cse20211/lab5
    
    For this assignment, you will be using the simple graphics library created for this class. Follow that link, download the example program, and skim through the function reference. (Return to it later as needed.)

    Part 1: Fractal Puzzles

    Write a program (fractals.c) that opens a large window and waits for user input. Upon pressing any of the numbers 1 through 8, clear the screen, and then draw the indicated fractal shape below. Then, wait for another keypress and display the next desired fractal. Exit when the user presses 'q'.

    Each fractal shape should be drawn by a recursive function that stops recursing when the scale of drawing becomes too small. Your display may differ from the examples slightly, as long as the topology is clearly the same. For example, your tree should branch into two at each point, but need not be exactly the same height and width. You may need to peer at the image for a little while before you decode what is going on. (Click each for a bigger image.)

    1 - Sierpinski Triangle 2 - Shrinking Squares 3 - Spiral Squares 4 - Circular Lace
    5 - Snowflake 6 - Tree 7 - Fern 8 - Spiral of Spirals

    Note: completing the first two fractals is sufficient to earn a participation point for the lab.

    Part 2: Fractal Gallery

    Pick your favorite fractal shape, and write a program (gallery.c) that fills the screen with a gallery of 16 (or more) variations of that fractal simply by varying the basic parameters of size, location, angle, and so forth. Employ the techniques we discussed in class -- randomness, pruning, varying colors, etc -- to make the shapes realistic.

    There is one tricky requirement: Your program must contain only ONE recursive function. The function should have appropriate parameters to control the color, branching factor, size, etc. By calling the function multiple times with different parameters, you should be able to create significant variations in the shapes actually drawn.

    Some ideas to get you thinking:

  • A gallery of tree shapes and sizes, ranging from a low bush to a tall pine,
  • A gallery of distant galaxies, ranging from a tight cluster to a sweeping spiral.
  • A gallery of snowflakes, all varying in the number of arms, angle of spread, and so forth.
  • How to Proceed

    We talked about fractals quite a bit in class. To briefly review, a fractal is a self-similar structure, in which the components of any one part are identical to the whole, differing only in size and orientation. Fractals pop up everywhere in nature, from the structure of galaxies, to the shape of snowflakes, to the pattern of growth in plants.

    A fractal is most easily drawn on a computer by a recursive function. Any kind of recursive function must have a base case which terminates the recursion, and a recursive case which draws one piece of the figure, and then calls the function again (possibly several times) with slightly different arguments.

    Let's start by working out fractal #1, the Sierpinski Triangle.

    First, identify the basic shape of the fractal, and write a bit of code to draw it. The basic shape for #1 is the triangle, so write a function to draw that:

    void draw_triangle( int x1, int y1, int x2, int y2, int x3, int y3 )
    {
    	gfx_line(x1,y1,x2,y2);
    	gfx_line(x2,y2,x3,y3);
    	gfx_line(x3,y3,x1,y1);
    }
    
    Now, let's work on the recursive function, which usually has parameters similar to that of the basic shape. Write out the function body for fractal_triangle, It should have a base case, a drawing step, and a recursive step. The drawing step is easy, so add that first:
    void fractal_triangle( int x1, int y1, int x2, int y2, int x3, int y3 )
    {
    	/* Base case will go here. */
    
    	/* Drawing step. */
    	draw_triangle(x1,y1,x2,y2,x3,y3);
    
    	/* Recursive step will go here. */
    }
    
    Next, determine the recursive step. Each large triangle will consist of several small triangles, so call fractal_triangle recursively to create the smaller triangles:
    void fractal_triangle( int x1, int y1, int x2, int y2, int x3, int y3 )
    {
    	/* Base case will go here. */
    
    	/* Drawing step. */
    	draw_triangle(x1,y1,x2,y2,x3,y3);
    
    	/* Recursive step. */
    	fractal_triangle(x1,y1, (x1+x2)/2, (y1+y2)/2, (x1+x3)/2, (y1+y3)/2 );
    	fractal_triangle( /* coords of small triangle 2 */ );
    	fractal_triangle( /* coords of small triangle 3 */ );
    }
    
    The example above will compile and run, but it will recurse forever and eventually crash the program. (Try it if you like.) Every recursive function must have a base case to stop the recursion, so let's stop when the triangles get small:
    void fractal_triangle( int x1, int y1, int x2, int y2, int x3, int y3 )
    {
    	/* Base case. */
    	if( abs(x2-x1) < 5 ) return;
    
    	/* Drawing step. */
    	draw_triangle(x1,y1,x2,y2,x3,y3);
    
    	/* Recursive step. */
    	fractal_triangle(x1,y1, (x2+x3)/2, (y2+y3)/2, (x1+x3)/2, (y1+y3)/2 );
    	fractal_triangle( /* coords of small triangle 2 */ );
    	fractal_triangle( /* coords of small triangle 3 */ );
    }
    
    To sum up, here is a checklist for a good recursive fractal function:
  • It must have a base case which stops the recursion.
  • It must have a drawing step that actually displays something.
  • It must have a recursive step that calls itself with different arguments.
  • The recursive step must move towards the base case.
  • Turning In

    Please review the general instructions for lab reports.

    Turn in fractals.c, gallery.c, and report.txt. Your lab report should explain the final part of the assignment, explaning how it works from the user perspective, how the program works internally, and how you verified that the output of the program is correct.

    Turning In

    This assignment is due on Monday, October 15th at noon. Late assignments are not accepted.

    Please review the general instructions for turning in.