# Create a fractal Christmas tree

By , 22 Dec 2002

## What is a fractal?

A fractal is a shape that is symmetric in scale, meaning that it looks the same, or similar, magnified as it does unmagnified. There are many naturally occurring objects that exhibit this self-similarity in scale. Trees, coastlines, mountain ranges, and clouds are some examples.

## How do you make a fractal?

A fractal is typically made using recursion. Given a line segment, and operation is performed on that segment which generally yields one or more new segments. The same operation is then performed again, on the new segments. In order to prevent the program from going into an infinite loop, the recursion algorithm usually includes a test that prevents it from operating on a segment smaller than a single pixel.

## How does this program create a tree?

Creating a tree is very simple. Given the "stem" as a seed "branch":

1. Draw the branch
2. Select a point on the branch where two new branches will be placed, one on each side of the current branch
3. From the user inputs, determine the angle and length of these two new branches
4. Recurse using the left branch>/li>
5. Recurse using the right branch.

This is accomplished in very few lines of code:

```public void Start(Line seed)
{
h15=Math.Abs(seed.Size.Height)/5;
Fractal(seed, depth);
}

private void Fractal(Line l, int depth)
{
// draw the branch in a color based on its length
int len=l.Length;
if (len < 3)
{
gr.DrawLine(pbr3, l.StartPoint, l.EndPoint);
}
else if (len < h15)
{
gr.DrawLine(pbr2, l.StartPoint, l.EndPoint);
}
else
{
gr.DrawLine(pbr1, l.StartPoint, l.EndPoint);
}

while ( (depth != 0) && (l.Length > 1) )
{
// get the second segment when we split the line
Line l2=l.SplitAt(bp)[1];

// if no change, then exit.
if (l2.Length==l.Length)
{
return;
}

// get the left and right branch starting points
Line bp1=l.SplitAt(bp+MathEx.Dev(bpDev))[1];
Line bp2=l.SplitAt(bp+MathEx.Dev(bpDev))[1];

// the new "master" branch starting point has no randomness
l=l2;

// get the left and right branches
(int)(bp1.Length*bl/100+MathEx.Dev(blDev)));
(int)(bp2.Length*bl/100+MathEx.Dev(blDev)));

// recurse both branches
Fractal(lineLeft, depth-1);
Fractal(lineRight, depth-1);
}
}
```

You will notice that the above code looks a bit more complicated than it needs to be, what with all those `MathEx.Dev` function calls. These take the user's specified +/- deviation and adjust the branch angle, length, and position randomly. This makes our trees much more natural looking!

## A note about the user interface

The program is set up to autogenerate the tree when the main parameters (branch point, angle, and length) are changed. Changing the +/- deviation and color does not automatically regenerate the tree. After changing these parameters, click on the "Generate" button. Once you add randomness, click on the "Generate" button several times to see different trees.

On slow computers, you may want to turn off auto-generation.

Play with the "depth" spin control. This controls the level of recursion. Going higher than 4 can take a long time to generate the tree. You can get a better understanding of the algorithm by setting the depth to 1, then incrementing it.

## A note about the code

This program includes a rough prototype of what I call my "Application Automation Layer". Have fun exploring the concepts behind it. For example, the GUI is generated from a text file, and the color picker controls are "replicated":

The color channel (red, green, or blue):

```GUI:ColorChannelPicker
STATIC s1 at (0, 3) caption "#:"
SPIN spChannel at (15, 0) size (40, 20) storage value
options (min:0 max:255 step:1) \
onchange "ColorChannelChangeEvent(@, #)"
COLORBOX clrbox at (60, 0) size (20, 20) storage channelColor
GUIEND
```

The color picker (one of three), which has three color channels and the final color:

```GUI:ColorPicker
INHERIT inhRed at (0, 0) postfix R gui ColorChannelPicker
INHERIT inhGreen at (90, 0) postfix G gui ColorChannelPicker
INHERIT inhBlue at (180, 0) postfix B gui ColorChannelPicker
COLORBOX clrbox at (270, 0) size (60, 20) storage compositeColor
GUIEND
```

And the main GUI itself:

```GUI:MainForm
STATIC s1 at (10, 13) caption "Branch Point:"
STATIC s2 at (10, 33) caption "Branch Angle:"
STATIC s3 at (10, 53) caption "Branch Size:"
STATIC s4 at (150, 13) caption "%"
STATIC s5 at (150, 33) caption "degrees"
STATIC s6 at (150, 53) caption "%"

STATIC s7 at (200, 13) size (100, 15) caption
"Deviation +/- :" options (rightjustify)
STATIC s8 at (200, 33) size (100, 15) caption
"Deviation +/- :" options (rightjustify)
STATIC s9 at (200, 53) size (100, 15) caption
"Deviation +/- :" options (rightjustify)

SPIN spBP at (100, 10) size (50, 20) storage branchPoint
options (min:20 max:80 step:1) \
onchange "AutoUpdateCheck"
SPIN spBPDev at (300, 10) size (50, 20) storage
bpDev options (min:0 max:9 step:1)

SPIN spBA at (100, 30) size (50, 20) storage
branchAngle options (min:20 max:160 step:1) \
onchange "AutoUpdateCheck"
SPIN spBADev at (300, 30) size (50, 20) storage

SPIN spBS at (100, 50) size (50, 20) storage
branchSize options (min:20 max:80 step:1) \
onchange "AutoUpdateCheck"
SPIN spBSDev at (300, 50) size (50, 20) storage
bsDev options (min:0 max:9 step:1)

STATIC s10 at (350, 13) caption "%"
STATIC s11 at (350, 33) caption "degrees"
STATIC s12 at (350, 53) caption "%"

STATIC s13 at (10, 83) caption "Large Branches:"
INHERIT inhColor1 at (100, 80) prefix clr1 gui ColorPicker

STATIC s14 at (10, 108) caption "Small Branches:"
INHERIT inhColor2 at (100, 105) prefix clr2 gui ColorPicker

STATIC s15 at (10, 133) caption "Leaves:"
INHERIT inhColor3 at (100, 130) prefix clr3 gui ColorPicker

BUTTON btnGenerate at (10, 170) size (80, 25)
caption "Generate!" \
onselect "EventUpdateTree"

CHECKBOX ckAutoGen at (100, 175) size (100, 20) caption
"Auto Generate" storage autoUpdate

STATIC s16 at (200, 178) size (70, 15) options
(rightjustify) caption "Depth:"
SPIN spDepth at (275, 175) size (50, 20) storage
depth options (min:1 max:10 step:1) \
onchange "AutoUpdateCheck"

OWNERDRAW fractalTree at (10, 200) options
(autosizeW:10 autosizeH:10) \
onpaint "EventPaintTree()"  \
onsize "EventUpdateTree()"

GUIEND
```

## Prior art

Many years ago I wrote a program for the Reuben H. Fleet Space Theatre in San Diego, California (http://www.rhfleet.org/ [^]) as part of their symmetry exhibit. I believe the exhibit is now permanently on display. This program is based on one of the two exhibits that I made for the Space Theatre. The other exhibit demonstrated the self-similiarity of coastlines.

A list of licenses authors might use can be found here

 Marc Clifton United States Member
Marc is the creator of two open source projets, MyXaml, a declarative (XML) instantiation engine and the Advanced Unit Testing framework, and Interacx, a commercial n-tier RAD application suite.  Visit his website, www.marcclifton.com, where you will find many of his articles and his blog.

Marc lives in Philmont, NY.

Votes of 3 or less require a comment

 Search this forum Profile popups    Spacing RelaxedCompactTight   Noise Very HighHighMediumLowVery Low   Layout Open AllThread ViewNo JavascriptPreview   Per page 102550
 First PrevNext
 My vote of 5 JamesHollowell 18 Dec '12 - 14:49
 My vote of 5 Mohsen Kazemi 1 Jul '10 - 10:13
 database Member #3841341 23 Feb '07 - 19:41
 hi can i project this faractal tree on database which represent family data   i wonder if it is possible ?   asmaa Sign In·View Thread·Permalink
 Printing Heath Stewart 2 Jan '03 - 6:52
 How about using .NET's simple print functionality to allow a user to print the rendered image? Or even save it as an image? Every geek needs a fractal Christmas tree!   "Well, I wouldn't say I've been missing it, Bob." - Peter Gibbons Sign In·View Thread·Permalink
 Re: Printing Marc Clifton 2 Jan '03 - 7:04
 Great Idea!   Marc   Help! I'm an AI running around in someone's f*cked up universe simulator.Sensitivity and ethnic diversity means celebrating difference, not hiding from it. - Christian GrausEvery line of code is a liability - Taka Muraoka Sign In·View Thread·Permalink
 Very interesting Sameh Ahmed 27 Dec '02 - 22:41
 dataMatrix David Stone 23 Dec '02 - 13:34
 Marc, in your dataMatrix class, why did you choose to do SetCell and GetCell instead of using properties, or better yet, an Indexer???   I don't know whether it's just the light but I swear the database server gives me dirty looks everytime I wander past. -Chris Maunder   Microsoft has reinvented the wheel, this time they made it round. -Peterchen on VS.NET Sign In·View Thread·Permalink
 Re: dataMatrix Marc Clifton 23 Dec '02 - 14:00
 the dumb answer is that the dataMatrix was a quick port from a C++ class that I've used for years, even before STL came on the scene.   and yes, I completely agree--but I also am such a newbie to C# that I have to look up what you mean by an "Indexer". Learning a new language might be simple, but all the supporting .NET stuff is sometimes overwhelming, especially since I'm still living in the C++/MFC world with all my customers!   So I do fun little projects like this in C#.   Marc   Help! I'm an AI running around in someone's f*cked up universe simulator.Sensitivity and ethnic diversity means celebrating difference, not hiding from it. - Christian GrausEvery line of code is a liability - Taka Muraoka Sign In·View Thread·Permalink
 Re: dataMatrix freshthinking 14 Jun '03 - 0:26
 If you use properties when the code is compiled the property is converted into get... and set... methods by the compiler. Sign In·View Thread·Permalink
 Pretty :-) Taka Muraoka 23 Dec '02 - 11:51