Assignment 10
Up Assignment 1 Assignment 2 Assignment 3 Assignment 4 Assignment 5 Assignment 6 Assignment 7 Assignment 8 Assignment 9 Assignment 10

 

Graphics: A Fractal Program

Due: Friday, Dec 7, 5:00 PM

PART 1

Fractal Snowflake.  Use recursion to generate a fractal snowflake.  This snowflake is an example of a fractal computation, but we don't need to know anything about fractals to solve it.

There are several ways to describe a fractal snowflake.  The best way for this assignment is to first draw an equilateral triangle like this:
____________________
\                              /
  \                          /
    \                      /
      \                  /
        \              /
          \          /
            \      /
              \ /

Then draw a second one on top of this, same size, but rotated 180 degrees (thus generating the Star of David :-).  You will note that the upper part of the figure will then look like the version described earlier.  Now repeat this process for each of the corners of the figure (there are six of them!), until a suitably small triangle is reached.

Draw your snowflake on a Form.  Experiment with sizes to get it to look nice (hint: make the form large!).  You may want to experiment with filled versus unfilled triangles and different colors for the successively smaller layers.

Hint: Perhaps the hardest thing about this assignment is figuring out the coordinates of the various images.  I suggest that you start with the smallest version, and then scale it up suitably.  There are two things to figure out from a given center: the new centers, and the vertices of the two triangles.  If we map this out on a 6-by-6 grid, the centers are given by:

     (3,1)
(1,2)     (5,2)
     (3,3)
(1,4)     (5,4)
     (3,5)

and the vertices by:

       (3,0)
(0,1.5)     (6,1.5)
       (3,3)
(1,4.5)     (6,4.5)
       (3,6)

If this doesn't make sense to you, draw a 6x6 grid and map out the above coordinates.

PART 2

Modified Paint Program with Undo Facility.  Modify your (or my) solution to Assignment 9 (the Paint Program) so that it keeps track of all line segments that it draws between times that the Clear button is pressed.  Each line segment is specified by its endpoints, color, and line width (and thus you will have to define a small data structure to capture this).  The sequence of line segments should be represented by some kind of a linked list.  Then, do the following:

  1. Define an OnPaint method that re-draws the panel whenever the window is uncovered, resized, moved, etc.
     
  2. Add an Undo button such that, every time it is pressed, the most recently drawn line segment goes away.

Hints:

First off, using the Design View, add a handler for the Panel's Paint exception.  Suppose this is called Panel_Paint.  In this method you should first grab the Panel's graphics context like this:

    Graphics g = e.Graphics;

where e is the argument to Panel_Paint.  Then you write the code to redraw all the lines.

Second, to keep track of all the lines, you need to store them in a linked list.  But it would be a mistake to use the List class data type that I described in class (and in Chapter 24), because it does not have the right functionality.  Instead, do the following:

  1. Define a class called Line that just stores the endpoint coordinates, color, and width of a line.  So, for example, if line is an instance of this class, you just do something like line.X0, line.Y0, line.X1, line.Y1, line.Color, and line.Width to retrieve its data.
     
  2. Define a ListNode class just like I did in class or as described in Chapter 24.  The Data part of these nodes will contain Lines.
     
  3. Define instance variables firstNode and lastNode in your Form's class.  Initially, these will be null, because the list is empty.  Then, using the ideas from Chapter 24, you should be able to add nodes to the end of this list (i.e. every time a new line is drawn when the mouse is moved), remove nodes from the end (i.e. when the Undo button is pressed), and traverse the entire list without destroying it (i.e. when you have to redraw all the lines).  I suggest writing methods:
        private void addLine(Line ln)   and 
        private void removeLine()
    for this purpose (but for the latter, do not generate an exception when the list is empty, since there's nothing wrong with pressing the Undo button when there's nothing on the screen).  Traversing the list is done trivially
    using the .Next property on ListNodes.