|

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":
- Draw the branch
- Select a point on the branch where two new branches will be placed, one on
each side of the current branch
- From the user inputs, determine the angle and length of these two new
branches
- Recurse using the left branch>/li>
- 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)
{
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) )
{
Line l2=l.SplitAt(bp)[1];
if (l2.Length==l.Length)
{
return;
}
Line bp1=l.SplitAt(bp+MathEx.Dev(bpDev))[1];
Line bp2=l.SplitAt(bp+MathEx.Dev(bpDev))[1];
l=l2;
Line lineLeft=bp1.Branch(360-ba+MathEx.Dev(baDev),
(int)(bp1.Length*bl/100+MathEx.Dev(blDev)));
Line lineRight=bp2.Branch(ba+MathEx.Dev(baDev),
(int)(bp2.Length*bl/100+MathEx.Dev(blDev)));
Fractal(lineLeft, depth-1);
Fractal(lineRight, depth-1);
}
}
Adding randomness
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
baDev options (min:0 max:9 step:1)
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.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 30 (Total in Forum: 30) (Refresh) | FirstPrevNext |
|
|
 |
|
|
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 | |
|
|
|
 |
|
|
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 | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
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 | |
|
|
|
 |
|
|
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 Graus Every line of code is a liability - Taka Muraoka
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
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 | |
|
|
|
 |
|
|
Being the total nerd that I am though, I'd like to know a bit more about the AAL.
I read the white paper on your web site but without examples, it's all a bit abstract. For example, the GUI description file seems to be simply a resource file that is read at runtime.
Your white paper talks about the AAL speeding up and improving the development process so I'd like to know more! Are you selling this as a development tool or is it something you just use for youself?
he he he. I like it in the kitchen! - Marc Clifton (on taking the heat when being flamed)
Awasu v0.4a[^]: A free RSS reader with support for Code Project.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I read the white paper on your web site but without examples, it's all a bit abstract.
Yes, I agree. In fact, those articles are so old it's laughable.
Let me first give a really brief description of what it DOES:
1. Provides a common data exchange mechanism between technologies that have different data representation schemes. A typical example is the data representation differences between 1) the application, 2) the database, 3) the visualization program, such as Visio, 4) the GUI.
2. Decouples unrelated objects by using a meta-interface (for example, a bridge design pattern). This reduces build time dependencies and problems related to changes in object designs.
3. Promotes component-based development. The application itself is considered another technology which is merely another plug-in to the framework. Each component of the AAL is itself a DLL that registers itself into the AAL framework. Components communicate via an instrumented messaging system (see #4 below) and exchange data via an instrumented data exchange mechanism.
4. A fallout of this scheme is that an application is automatically instrumented—data exchanges, event invocation, object to object messaging all include instrumentation, so that it is very easy to trace an application.
I'll put together a pretty picture for you soon. Uwe Keim also expressed an interest in this!
For example, the GUI description file seems to be simply a resource file that is read at runtime.
Yes. The advantages are not so much in the "resource file" but in the underlying implementation of the GUI objects (which are derived from MFC). One thing that is lacking in a typical Windows resource file is the association between the resource and the data container for that resource. For example, a list will have an index and the list itself (we'll ignore multiple selection lists for right now). Instead of making this association in the resource file, the programmer has to create a derived class and declare variables in C++, then do the data exchange.
Instead, the AAL uses a generic DataContainer mechanism. A typical scenario is this--the database module reads in a list and stores it in the DataContainer using the generic DataMatrix object. The GUI list reads it out of the DataContainer, transferring the information in the DataMatrix to the list control. In that process, I can do all sorts of nifty things--hide columns in the DataMatrix that are useful but we don't want to display in the list, for example.
Now, the above describes what I would call common sense programming and doesn't need scripts, etc., but the problem I encountered, and the reason for the AAL, is described next.
Are you selling this as a development tool or is it something you just use for youself?
No, I'm not selling it, and I'm more than happy to give it away for free (remember what you said: every line of code is a liability). There are really two camps--those that don't have a problem with non-standard approaches, and those people that do. I'm not going to argue until I'm blue in the face with those that do have a problem. I just won't work with them. Arrogant? No. I just know my limits.
The concept of the AAL was originally created to support a multi-developer effort for Space Systems/Loral. We were writing a program to automate the design of satellites. It had a large Oracle database, about 8 different unrelated but interconnected modules, interfaced with Visio, etc.
I needed a framework that allowed me to debug things that junior programmers were doing. I needed a framework that enforced a particular coding style and promoted some sort of consistency. I needed to break the concept that the database group did database stuff and the C++ group did C++ stuff.
And I needed a system that could be modified literally overnight to accomodate changing requirements. Before Agile Programming, before Extreme Programming, there was little ol' me with my Application Coordinator (what it was called then).
After I left Integration Partners (who had the contract with Space Systems/Loral) I rewrote the whole thing an called it the Application Automation Layer. It includes a script engine to provide the meta-glue for all the technology components. I've used it successfully for the last 4 years now on numerous customer contracts and applications. I think it saves me tons of time because I can do rapid prototyping AND the system, being component based and script driven, is highly flexible to changing customer requirements. I seem to get a lot of those customers--people don't really know what they want until they see something and go, hmmm...that's not really what I had in mind. I love it!
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 Graus Every line of code is a liability - Taka Muraoka
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sounds really good. I'd be interested to hear more.
I haven't done any independent contracting for ages so I don't really need something like this but in the past, I would prototype in VB and then do the real work in whatever. Ties in well with the "build one to throw away" philosophy as well.
I'm curious about your scripting engine - how sophisticated is it? I wrote a reasonably funky one for Awasu because I didn't want to embed Python (or something similar). I know I had a good reason at the time but I'll be buggered if I can remember what is was! So it looks like I'm going to ditch all that work and go for external, third-party scripting. Sigh...
he he he. I like it in the kitchen! - Marc Clifton (on taking the heat when being flamed)
Awasu v0.4a[^]: A free RSS reader with support for Code Project.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'm curious about your scripting engine - how sophisticated is it?
Well, "funky" might be the word to apply to mine also. It basically does three things
1. it extracts the message address 2. it decodes parameters 3. it builds a data packet for those parameters 4. it sends the whole kit & kaboodle off to the message manager
Of course, there are separate script engines to process reports, menus, guis, database models, state systems, etc., but those just load up the various structures.
Oddly enough, I've written complete applications using just the script engine.
Here's an example:
MACRO:LoadComboBox DBMgr.QueryMultiRow(dp_DB, DBConn, "select ID, NAME from MY_LIST", myList) WinMgr.UpdateControlList(dp_controlName, MyForm, MyComboBox) MACROEND
The first line specifies an SQL statement to execute using the "DBConn" connection, putting the results into "myList", using the data packet described by "dp_DB" (another script).
The "DBMgr" is the technology plug in and "QueryMultiRow" is a function that is registers with the message manager.
Similarly, the next line tells the window manager plug-in )WinMgr) to update the control list (UpdateControlList). The GUI would be defined like this:
GUI:MyForm ... COMBOBOX ... storage myIndex list storage myList ... GUIEND
When the control gets the "update list" command, it extracts the list from the global data container and pops it into the MFC CComboBox control. "list storage" specifies the list name and "storage" specifies the index of the selected item.
Now, I've done in two lines of script what I've seen programmers set up in 50 lines of C++, what with setting up the DB query, transferring contents to the combo box, etc.
I don't think what I've done is rocket science. But I do think it goes way beyond what most programmers have thought about when writing a large scale application. Cut & Paste is like television. People stop thinking--maybe, if I've cut and pasted this function and tweeked it 5 different times, there's a more generic way of doing this? Of course, now I'll have to go back and change all my code, so I guess I'll just keep C&P'ing.
Another advantage to all of this is that when you're writing an app with the AAL, you're debugging the exchange of information and its presentation/format, instead of the all the supporting code necessary in its acquisition and deposition (is that the right word?) of information. And acquisition has multiple layers--I've spent hours figuring out how to write a cool SQL statement, which is much better time spend than loading up a DataView "by hand", passing it off to the control, having it extract the useful information--argh, by the time I'm done with that, I've written a piece of code that is completely custom to my needs at that moment. Into the trash it goes the next day, probably.
Oops. I'm rambling. But this is good--it's getting me to write down stuff about the AAL.
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 Graus Every line of code is a liability - Taka Muraoka
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Marc Clifton wrote: People stop thinking--maybe, if I've cut and pasted this function and tweeked it 5 different times, there's a more generic way of doing this?
Not necessarily. I keep all my stuff in (runtime-configurable) libraries but I can see a lot of advantages in a scripted solution.
Marc Clifton wrote: so I guess I'll just keep C&P'ing.
Not that there's anything wrong with that 
Marc Clifton wrote: But this is good--it's getting me to write down stuff about the AAL.
I can feel a book coming along! You should take work this further - it sounds really good. Is this what you were talking in your OPEN article? I'd like to request a copy of the source...
he he he. I like it in the kitchen! - Marc Clifton (on taking the heat when being flamed)
Awasu v0.4a[^]: A free RSS reader with support for Code Project.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 You could draw circles at every nth segment! Or some vertical white lines to every point whoses depth is >x (with a yellow filled bézier-curve, as flame)
--pascal 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hi Uwe,
I'm posting this message in the article's discussion board just so that other readers of the message posts know how to fix this problem, since we resolved it via private email.
The mainform.txt must be unzipped and placed in the same directory as the fractalTree.exe file. The program dynamically generates the form and, being a prototype, lots of error handling is currently missing!
Also, if you build the app, build it in debug mode, or copy the mainform.txt file to the release build output directory.
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 Graus Every line of code is a liability - Taka Muraoka
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I like it
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
A nice Christmas theme
---
Shog9 The siren sings a lonely song - of all the wants and hungers The lust of love a brute desire - the ledge of life goes under
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Delightful application for fractals! How about adding some nice snowflakes?
"How many times do I have to flush before you go away?" - Megan Forbes, on Management (12/5/2002)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|