Imagine you were describing how to draw a tree. You might say:
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.
Applet
class
Tree
class
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.
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:
double dLength
the length of the previous branch (or trunk)
int nStartX
the X coordinate of the starting point of the new branch (which is the
same as the end point of the previous branch)
int nStartY
the Y coordinate of the branch's starting point
double dAngle
the angle of the previous branch (or trunk) in radians
Graphics g
Here's some pseudocode describing the branch
function:
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.
dLength
by multiplying it by dFractionLength
. This
will be the (shorter) length of the new branch.
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);
g.drawLine
. The starting point of both lines
is (nStartX,nStartY)
, but they will use different endpoints,
e.g. (nEndX1,nEndY1)
.
dLength
is larger than nSmallestBranch
call branch
twice, once for each of the endpoints,
e.g. (nEndX1,nEndY1)
branch
after the code in draw
that
draws the line. You'll send it
100
(the length of the trunk)
nEndX
and nEndY
(the endpoint of the trunk is
the starting point of the next branch)
3*Math.PI/2
(The angle of the trunk--a vertical angle in Java's system of radians)
g
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. . .