<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Yet Another Coding Blog : graphics</title><link>http://blogs.msdn.com/avip/archive/tags/graphics/default.aspx</link><description>Tags: graphics</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Drawing Fractal Trees - Part 3</title><link>http://blogs.msdn.com/avip/archive/2008/07/24/drawing-fractal-trees-part-3.aspx</link><pubDate>Thu, 24 Jul 2008 03:02:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8768098</guid><dc:creator>Avi Pilosof</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/avip/comments/8768098.aspx</comments><wfw:commentRss>http://blogs.msdn.com/avip/commentrss.aspx?PostID=8768098</wfw:commentRss><wfw:comment>http://blogs.msdn.com/avip/rsscomments.aspx?PostID=8768098</wfw:comment><description>&lt;p&gt;&lt;strong&gt;The Application Itself&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Firstly, here's what we're aiming towards:&lt;/p&gt; &lt;p&gt;Live demo: &lt;a href="http://aumdmg.bay.livefilestore.com/y1pOiXwiHJm_knxiviY2rbb8hgbM5GKyYecD4NiveEhtVituHmaD00ixlYVyO6eLopmeoCx9D0MvbM/SilverTreeTestPage.html"&gt;&lt;strong&gt;Click to view live&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Download the code:&lt;br&gt;&lt;iframe style="border-right: #dde5e9 1px solid; padding-right: 0px; border-top: #dde5e9 1px solid; padding-left: 0px; padding-bottom: 0px; margin: 3px; border-left: #dde5e9 1px solid; width: 240px; padding-top: 0px; border-bottom: #dde5e9 1px solid; height: 66px; background-color: #ffffff" marginwidth="0" marginheight="0" src="http://cid-2d6b67738cd325f9.skydrive.live.com/embedrowdetail.aspx/Public/SilverTree/SilverTree.zip" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;Screenshot:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/avip/WindowsLiveWriter/DrawingFractalTreesPart3_7CC9/SilverTree_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="SilverTree Screenshot" src="http://blogs.msdn.com/blogfiles/avip/WindowsLiveWriter/DrawingFractalTreesPart3_7CC9/SilverTree_thumb_1.jpg" width="232" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Writing The Application&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Now, when I originally wrote the bones of the app it was very simple; everything fit in the single &lt;em&gt;Page.xaml.cs&lt;/em&gt; file; there's actually very little to it. Since then I've expanded it to cater for all sorts of UI niceties and expansion opportunities, so it's a little bigger (and that's what's in the ZIP above). I'll concentrate on the basics for the purposes of the blog post; you can download the full source and inspect the complexities.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 1: Creating the Final Command Set&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This step involves taking the Axiom and a set of rules, and using it to generate a final set of drawing commands/operations. The method below is in a class called &lt;em&gt;LSystem&lt;/em&gt;, which is also where the axiom and rules are stored:&lt;/p&gt; &lt;div&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; FinalCommandSet(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; depth)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; res = Axiom;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 1; i &amp;lt;= depth; i++)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (LSystemRule rule &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Rules)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;             res = res.Replace(rule.From, rule.To);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; res;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Given the "depth" of recursion, we just loop through the latest string we have and apply all the rules at each step, starting with the axiom.&lt;/p&gt;
&lt;p&gt;Now that we have this string, we need to walk through it and draw the final result.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2: The Recursive Drawing Algorithm&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; DrawSegment(Canvas uiRoot, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; commandString, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; stringPos,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;                 Point curPos, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; curAngle, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; curLength)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     Random rnd = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Random();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i=stringPos;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; ( i &amp;lt; commandString.Length )&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;char&lt;/span&gt; c = commandString[i];&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (c)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;'['&lt;/span&gt;:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;                 i = DrawSegment( uiRoot, commandString, i+1, curPos,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;                                 curAngle, curLength );&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;']'&lt;/span&gt;:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; i;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;             &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;'F'&lt;/span&gt;:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;                 Point newPos = FromAngleAndMagnitude(curPos, curAngle,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;                             curLength + rnd.Next(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Randomness/3));&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;                 DrawLine( uiRoot, curPos, newPos );&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;                 curPos = newPos;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;             &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;'P'&lt;/span&gt;:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DrawPetals &amp;amp;&amp;amp; (rnd.Next(100) &amp;lt; 90) )&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;                     DrawPetal(uiRoot, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Petal, curPos, curAngle);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;             &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;'-'&lt;/span&gt;:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;                 curAngle -= &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Angle + rnd.Next(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Randomness);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt;             &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;'+'&lt;/span&gt;:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  36:&lt;/span&gt;                 curAngle += &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Angle + rnd.Next(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Randomness);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  37:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  38:&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  39:&lt;/span&gt;         i++;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  40:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  41:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  42:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; i;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  43:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;First thing to note here is that the function is meant to be called recursively. The cases for '[' and ']' (lines 11 and 16) deal with that.&lt;/p&gt;
&lt;p&gt;Next up, notice the overall loop; it's pretty much: "Step through each character of the string, act on that character, update our current pen settings (angle/position) as you go, and then move onto the next character."&lt;/p&gt;
&lt;p&gt;Notice also that the function returns the final position in the string (&lt;em&gt;i&lt;/em&gt;)that it ended up on; this is so that when you call it recursively, it reads as far as it can, then tells the caller where to continue from (see line 12).&lt;/p&gt;
&lt;p&gt;At each call to the function, we pass in these args:&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2" width="400" border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="102"&gt;uiRoot&lt;/td&gt;
&lt;td valign="top" width="297"&gt;The canvas to which we'll be adding any drawn lines. This is the same through all recursive calls.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="102"&gt;commandString&lt;/td&gt;
&lt;td valign="top" width="297"&gt;The original/total string of commands. Stays the same through all calls.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="102"&gt;stringPos&lt;/td&gt;
&lt;td valign="top" width="297"&gt;The current position in the command string; this changes through each recursive call.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="102"&gt;curPos&lt;/td&gt;
&lt;td valign="top" width="297"&gt;The current position of the "pen" on the canvas; starts at the tree's origin, and changes with invocation of 'F'.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="102"&gt;curAngle&lt;/td&gt;
&lt;td valign="top" width="297"&gt;The current angle/heading of the "pen" on the canvas; starts at 90 degrees, and changes with invocations of '+'/'-'.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="102"&gt;curLength&lt;/td&gt;
&lt;td valign="top" width="297"&gt;The current length of a line when drawing with 'F'. This usually remains constant, but I added it in to allow for some funkier fractals that shrink with each recursion.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Drawing a Line&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Finally, drawing a single line on the canvas is a matter of adding a &lt;em&gt;Line&lt;/em&gt; shape to the canvas's &lt;em&gt;Children &lt;/em&gt;member (slow, but simple). However, we only know the current location, the direction of the line, and the length. We need to convert this to a Start/End set of points.&lt;/p&gt;
&lt;p&gt;A little trig:&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Point FromAngleAndMagnitude(Point origin,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; angle, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; magnitude)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; radians = DegreesToRadians(angle);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Point(&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;) (magnitude * Math.Cos(radians)) + origin.X,&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;) (magnitude * -Math.Sin(radians)) + origin.Y&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     );&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And that's pretty much it. Everything else is window dressing!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Further Reading&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Here's what happens when you take this technique just a &lt;em&gt;little&lt;/em&gt; further: &lt;a title="http://www.speedtree.com/gallery/" href="http://www.speedtree.com/gallery/"&gt;http://www.speedtree.com/gallery/&lt;/a&gt; 
&lt;li&gt;Here's more info about the topic in general: &lt;a title="http://vterrain.org/Plants/" href="http://vterrain.org/Plants/"&gt;http://vterrain.org/Plants/&lt;/a&gt; 
&lt;li&gt;Here's info about using fractals to generate whole scenes (not just plants): &lt;a title="http://vterrain.org/" href="http://vterrain.org/"&gt;http://vterrain.org/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Avi&lt;/p&gt;
&lt;p&gt;&lt;!-- AddThis Button BEGIN --&gt;
&lt;a href="http://www.addthis.com/bookmark.php" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=avip&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" title="Bookmark and Share" target="_blank"&gt;&lt;img src="http://s9.addthis.com/button1-share.gif" wid&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8768098" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/avip/archive/tags/silverlight/default.aspx">silverlight</category><category domain="http://blogs.msdn.com/avip/archive/tags/graphics/default.aspx">graphics</category></item><item><title>Drawing Fractal Trees - Part 2</title><link>http://blogs.msdn.com/avip/archive/2008/07/19/drawing-fractal-trees-part-2.aspx</link><pubDate>Sat, 19 Jul 2008 06:06:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8753241</guid><dc:creator>Avi Pilosof</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/avip/comments/8753241.aspx</comments><wfw:commentRss>http://blogs.msdn.com/avip/commentrss.aspx?PostID=8753241</wfw:commentRss><wfw:comment>http://blogs.msdn.com/avip/rsscomments.aspx?PostID=8753241</wfw:comment><description>&lt;p&gt;&lt;strong&gt;L-Systems&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We've established that drawing the tree will use the concept of self-similarity. To put this in action, we're going to use what's called an &lt;a href="http://en.wikipedia.org/wiki/L-system"&gt;L-System&lt;/a&gt;. Here's a crash-course...&lt;/p&gt;  &lt;p&gt;Firstly, we establish that we have a &amp;quot;pen&amp;quot; that at any given time has a current position and a current heading/angle. It's always touching the paper, so when it moves forward, you get a line drawn. If you ever learned &lt;a href="http://en.wikipedia.org/wiki/Turtle_graphics"&gt;LOGO&lt;/a&gt; in school, this will be familiar.&lt;/p&gt;  &lt;p&gt;Let's define a very simple set of operations. &lt;/p&gt;  &lt;table cellspacing="2" cellpadding="2" width="460" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="87"&gt;&lt;strong&gt;Operator&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="365"&gt;&lt;strong&gt;Meaning&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="88"&gt;F&lt;/td&gt;        &lt;td valign="top" width="364"&gt;Move forward by a fixed amount.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="89"&gt;+&lt;/td&gt;        &lt;td valign="top" width="363"&gt;Turn a little to one side.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="90"&gt;-&lt;/td&gt;        &lt;td valign="top" width="362"&gt;Turn a little to the other side.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="91"&gt;[&lt;/td&gt;        &lt;td valign="top" width="361"&gt;Remember your current position and heading, and store in a stack for later retrieval.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="92"&gt;]&lt;/td&gt;        &lt;td valign="top" width="360"&gt;Retrieve the previous position/heading from the stack.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;So if we feed something like &amp;quot;F+F+F+F&amp;quot; to our pen, we'll get a square, provided the angle that &amp;quot;+&amp;quot; uses is 90 degrees.&lt;/p&gt;  &lt;p&gt;Take something a little more complex, such as &amp;quot;F[-F][+F]&amp;quot;. This will draw a Y shape; walk it through on paper and see. The key thing to connect at this point is that the &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot; characters are perfectly represented by a recursive call to the same function that's doing the drawing. Save that for later.&lt;/p&gt;  &lt;p&gt;So we have our set of operators, we need one more thing: A way to generate an interesting string of operations that will draw the tree. The way we do that is by defining two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A starting point; an &amp;quot;axiom&amp;quot;.&lt;/li&gt;    &lt;li&gt;A rule (or set of rules) that transform a given set of operations into a new set of operations.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We then keep applying these rules to the resultant set of operations (starting with the axiom) as many times as we want. For example:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Axiom: F&lt;/li&gt;    &lt;li&gt;Rule: F =&amp;gt; +FF (this reads as: &amp;quot;Every time you see an 'F', replace it with '+FF'&amp;quot;)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Execution example:&lt;/p&gt;  &lt;table cellspacing="2" cellpadding="2" width="400" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="95"&gt;&lt;strong&gt;Iteration #&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="297"&gt;&lt;strong&gt;Current Set of Operations&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="95"&gt;0&lt;/td&gt;        &lt;td valign="top" width="297"&gt;F&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="95"&gt;1&lt;/td&gt;        &lt;td valign="top" width="297"&gt;+FF&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="95"&gt;2&lt;/td&gt;        &lt;td valign="top" width="297"&gt;++FF+FF&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="95"&gt;3&lt;/td&gt;        &lt;td valign="top" width="297"&gt;+++FF+FF++FF+FF&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Feed the final string above into our &amp;quot;pen&amp;quot;, and it will draw stuff. Not a tree though; not with &lt;em&gt;that&lt;/em&gt; rule. If you want a tree, go with a rule like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;F =&amp;gt; FF-[-F+F+F]+[+F-F-F] &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Wait, what?! Doesn't look anything like a tree, does it? But it turns out that when you apply that rule a few times to the axiom &amp;quot;F&amp;quot;, it generates a set of operations that draws something very similar to a tree (depending on what angle you rotate with each +/-).&lt;/p&gt;  &lt;p&gt;Check it out:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/avip/WindowsLiveWriter/DrawingFractalTreesPart2_BC4E/tree_2.gif"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="256" alt="tree" src="http://blogs.msdn.com/blogfiles/avip/WindowsLiveWriter/DrawingFractalTreesPart2_BC4E/tree_thumb.gif" width="341" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There is no randomness in this image; it's a direct drawing of the above rule (with 3-4 iterations of the rule), using a fixed distance for F and a fixed angle for +/-. Altering the distance that the pen moves with each F will make a larger/smaller tree; altering the angle can make a profound difference to the shape.&lt;/p&gt;  &lt;p&gt;There are different rules that will produce different looking plants. For more examples, see &lt;a href="http://spanky.fractint.org/www/fractint/lsys/plants.html"&gt;this page&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To me, this is mind-blowing. That such a simple system with such basic rules and operations can generate something that looks so eerily &amp;quot;natural&amp;quot; is a little spooky. And reminds me that I had the same effect with the &lt;a title="Two lines of code make for natural parabolic flight..." href="http://blogs.msdn.com/avip/archive/2008/06/23/trivial-physics-simulations-in-silverlight-part-1.aspx"&gt;physics tutorial&lt;/a&gt;: Simple rules can make complex behaviour. I think there's some deep philosophical insight buried there.&lt;/p&gt;  &lt;p&gt;What's left to do now is take this knowledge and apply it to a Silverlight program that can allow the user to alter the parameters in real-time, introduce some randomness, and maybe a little more life to the image.&lt;/p&gt;  &lt;p&gt;Stay tuned...&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Avi&lt;/p&gt;  &lt;p&gt;&lt;!-- AddThis Button BEGIN --&gt;
&lt;a href="http://www.addthis.com/bookmark.php" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=avip&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" title="Bookmark and Share" target="_blank"&gt;&lt;img src="http://s9.addthis.com/button1-share.gif" wid&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8753241" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/avip/archive/tags/silverlight/default.aspx">silverlight</category><category domain="http://blogs.msdn.com/avip/archive/tags/graphics/default.aspx">graphics</category></item><item><title>Drawing Fractal Trees - Part 1</title><link>http://blogs.msdn.com/avip/archive/2008/07/19/drawing-fractal-trees-part-1.aspx</link><pubDate>Sat, 19 Jul 2008 04:02:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8752564</guid><dc:creator>Avi Pilosof</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/avip/comments/8752564.aspx</comments><wfw:commentRss>http://blogs.msdn.com/avip/commentrss.aspx?PostID=8752564</wfw:commentRss><wfw:comment>http://blogs.msdn.com/avip/rsscomments.aspx?PostID=8752564</wfw:comment><description>&lt;p&gt;&lt;strong&gt;Table Of Contents&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Part 1: &lt;a href="http://blogs.msdn.com/avip/archive/2008/07/24/drawing-fractal-trees-part-1.aspx"&gt;Basic fractal theory&lt;/a&gt; (this page)&lt;/li&gt; &lt;li&gt;Part 2: &lt;a href="http://blogs.msdn.com/avip/archive/2008/07/19/drawing-fractal-trees-part-2.aspx"&gt;L-Systems - drawing trees&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Part 3: &lt;a href="http://blogs.msdn.com/avip/archive/2008/07/24/drawing-fractal-trees-part-3.aspx"&gt;Implementation in Silverlight, live demo, code download&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;A Brief Explanation of Fractals&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In plain English, a fractal is a shape whose constituent parts are really just copies (scaled down) of the whole.&amp;nbsp; Here's a simple example, the &lt;a href="http://en.wikipedia.org/wiki/Koch_curve"&gt;Koch Curve&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="204" alt="Koch Curve" src="http://blogs.msdn.com/blogfiles/avip/WindowsLiveWriter/DrawingFractalTrees_89F6/koch_thumb.gif" width="164" border="0"&gt; &lt;/p&gt; &lt;p&gt;Take a look at the first part made up of 4 line segments. Make a copy of that whole part in your head, shrink it down, and rotate it so that it fits on top of one of the line segments. Notice how that looks like the beginnings of the second part? Keep going (forever), and that's your fractal: Any little bit of it is just a scaled down copy of the rest of it. You can zoom in &lt;em&gt;infinitely&lt;/em&gt; and keep seeing the same pattern.&lt;/p&gt; &lt;p&gt;It's a very powerful concept that can generate &lt;a href="http://www.darkroastedblend.com/2008/04/most-beautiful-fractals.html"&gt;stunning images&lt;/a&gt; when taken further.&lt;/p&gt; &lt;p&gt;But what really strikes me about fractals is that they're &lt;em&gt;real&lt;/em&gt;; they're everywhere in the physical world. From &lt;a href="http://fisica.ciencias.uchile.cl/alejo/fractal_antenna/node7.html"&gt;lightning&lt;/a&gt; to &lt;a href="http://www.amazon.com/Fractal-River-Basins-Chance-Self-Organization/dp/0521004055"&gt;river networks&lt;/a&gt; to &lt;a href="http://en.wikipedia.org/wiki/Image:Fractal_Broccoli.jpg"&gt;broccoli&lt;/a&gt; to the layout of &lt;a href="http://blog.fractalspin.com/neat-stuff/fractals-are-everywhere-in-africa"&gt;African villages&lt;/a&gt;! And also, to trees, which is where we come in.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Fractals in Trees&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you look at the "Y" shape created by a stylised tree branch, it's identical in concept to the branch that it spawned off, which is identical to its parent branch, etc, etc, until you reach the trunk - which forms the "axiom" of this fractal.&lt;/p&gt; &lt;p&gt;This series of posts will describe a Silverlight program based on this observation that allows users to generate random fractal plants by defining an axiom, a rule to iterate over, and a set of preferences that they can tweak.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Avi&lt;/p&gt; &lt;p&gt;&lt;!-- AddThis Button BEGIN --&gt;
&lt;a href="http://www.addthis.com/bookmark.php" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=avip&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" title="Bookmark and Share" target="_blank"&gt;&lt;img src="http://s9.addthis.com/button1-share.gif" wid&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8752564" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/avip/archive/tags/silverlight/default.aspx">silverlight</category><category domain="http://blogs.msdn.com/avip/archive/tags/graphics/default.aspx">graphics</category></item></channel></rss>