How to draw a tree

Imagine you were describing how to draw a tree. You might say:

  1. Draw a vertical line
  2. At the top of the line, draw two smaller lines ("branches") in a v shape
  3. At the ends of each of those two branches, draw two even smaller branches
  4. Keep repeating the process, drawing smaller and smaller branches until the branches are too small to draw

This process of repeating the same design at a continually decreasing scale is an example of a Fractal. Using fractals to draw trees can give some interesting and beautiful patterns. In this assignment we will use a recursive branching function to create a fractal tree.

Steps to completing this assignment

  1. Create a new project. Our program will have two classes:

    You can use the following code as a starting point (you'll want to increase the size of the Applet to 800 x 800 in the html code):

    import java.awt.*;
    import java.applet.*;
    
    public class FractalTreeExample extends Applet 
    {
       Tree joyce;
       public void init() 
       {
          setBackground(Color.black);
          joyce = new Tree();
       }
    
       public void paint(Graphics g) 
       {
          joyce.draw(g);
       }
    }
    
    class Tree
    {
       double dFractionLength;
       int nSmallestBranch;
       double dBranchAngle;
       int nStartX, nStartY, nEndX, nEndY;
      
       public Tree()
       {
          dFractionLength = .8;
          nSmallestBranch = 10;
          dBranchAngle = .2;
          nStartX = 400;
          nStartY = 700;
          nEndX = 400;
          nEndY = 600;
       }
      
       public void draw(Graphics g)
       {
          g.setColor(Color.green);
          g.drawLine(nStartX,nStartY,nEndX,nEndY);
        }
    }

    Notice that the Applet class is pretty simple. We just create an instance of the Tree class and draw it to the screen.

    The trunk of the tree needs four values: the X and Y of the starting point and the X and Y of the end point. We will also have three member variables that will control:

    Adjusting these parameters will change the appearance of the tree.

  2. Now add a branch method to the Tree class. branch will first draw two smaller branches off the end of the tree. It will then call itself recursively to draw two smaller branches off the ends of the previous branches. My branch method took 5 arguments:

    Here's some pseudocode describing the branch function:

    1. declare two local double variables: dAngle1 and dAngle2. These will hold the angles of the branches. Set one to be dAngle plus dBranchingAngle and the other to dAngle minus dBranchingAngle. This will create the V shape of the branches.
    2. reduce dLength by multiplying it by dFractionLength. This will be the (shorter) length of the new branch.
    3. While the starting point of the new branches is just the endpoint of the previous branch or trunk, we'll have to use some trig to calculate the branches endpoints. Declare four local variables nEndX1 nEndY1 nEndX2 nEndY2. We can calculate the endpoints with code like:
      int nEndX1 = (int)(dLength*Math.cos(dAngle1) + nStartX);
      int nEndY1 = (int)(dLength*Math.sin(dAngle1) + nStartY);
    4. Now, draw the two lines with g.drawLine. The starting point of both lines is (nStartX,nStartY), but they will use different endpoints, e.g. (nEndX1,nEndY1).
    5. if dLength is larger than nSmallestBranch call branch twice, once for each of the endpoints, e.g. (nEndX1,nEndY1)

  3. Now, add a call to branch after the code in draw that draws the line. You'll send it

  4. Adding Scrollbars

    The program becomes more interesting when you can adjust dBranchAngle dFractionLength and nSmallestBranch. In my program, I initialized the Scrollbar that adjusts the brancing angle like this:

    branchAngle = new Scrollbar(Scrollbar.HORIZONTAL,20,10,0,200);

    Then, my adjustmentValueChanged looked like:

    public void adjustmentValueChanged(AdjustmentEvent e)
    {
       if(e.getSource().equals(branchAngle))
         joyce.dBranchAngle = e.getValue()/100.0;
         
       //and more java. . .