Fractal tree: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎Tcl: Added implementation)
(add SVG example)
Line 122: Line 122:
draw_tree .c [expr {$SIZE/2}] [expr {$SIZE-10}] 0.0 -1.0 $INITIAL_LENGTH \
draw_tree .c [expr {$SIZE/2}] [expr {$SIZE-10}] 0.0 -1.0 $INITIAL_LENGTH \
[expr {3.1415927 / 8}] $BRANCHES</lang>
[expr {3.1415927 / 8}] $BRANCHES</lang>

=={{header|SVG}}==

[[File:Fractal tree.svg|thumb|right]]
In the same style as [[Dragon curve#SVG]]. SVG has no parameterized definitions, so the recursion must be unrolled.

<div style="clear:both;"></div>
<lang xml><?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="320">
<style type="text/css"><![CDATA[
line { stroke: black; stroke-width: .05; }
circle { fill: black; }
]]></style>
<defs>
<g id="stem"> <line x1="0" y1="0" x2="0" y2="-1"/> </g>
<g id="l0"><use xlink:href="#stem"/></g>
<!-- These are identical except for the id and href. -->
<g id="l1"> <use xlink:href="#l0" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l0" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l2"> <use xlink:href="#l1" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l1" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l3"> <use xlink:href="#l2" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l2" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l4"> <use xlink:href="#l3" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l3" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l5"> <use xlink:href="#l4" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l4" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l6"> <use xlink:href="#l5" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l5" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l7"> <use xlink:href="#l6" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l6" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l8"> <use xlink:href="#l7" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l7" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
<g id="l9"> <use xlink:href="#l8" transform="translate(0, -1) rotate(-35) scale(.7)"/>
<use xlink:href="#l8" transform="translate(0, -1) rotate(+35) scale(.7)"/>
<use xlink:href="#stem"/></g>
</defs>
<g transform="translate(200, 320) scale(100)">
<use xlink:href="#l9"/>
</g>
</svg></lang>

Revision as of 13:19, 5 May 2010

Task
Fractal tree
You are encouraged to solve this task according to the task description, using any language you may know.

Generate and draw a fractal tree.

To draw a fractal tree is simple:

  1. Draw the trunk
  2. At the end of the trunk, split by some angle and draw two branches
  3. Repeat at the end of each branch until a sufficient level of branching is reached

C

Library: SDL
Library: SGE

<lang c>#include <SDL/SDL.h>

  1. include <SDL/sge.h>
  2. include <stdlib.h>
  3. include <time.h>
  4. include <math.h>
  1. define SIZE 800 // determines size of window
  2. define SCALE 5 // determines how quickly branches shrink (higher value means faster shrinking)
  3. define BRANCHES 14 // number of branches
  4. define ROTATION_SCALE 0.75 // determines how slowly the angle between branches shrinks (higher value means slower shrinking)
  5. define INITIAL_LENGTH 50 // length of first branch

double rand_fl(){

 return (double)rand() / (double)RAND_MAX;

}

void draw_tree(SDL_Surface * surface, double offsetx, double offsety, double directionx, double directiony, double size, double rotation, int depth){

 sge_AALine(surface,
     (int)offsetx, (int)offsety,
     (int)(offsetx + directionx * size), (int)(offsety + directiony * size),
     SDL_MapRGB(surface->format, 0, 0, 0));
 if (depth > 0){
   // draw left branch
   draw_tree(surface,
       offsetx + directionx * size,
       offsety + directiony * size,
       directionx * cos(rotation) + directiony * sin(rotation),
       directionx * -sin(rotation) + directiony * cos(rotation),
       size * rand_fl() / SCALE + size * (SCALE - 1) / SCALE,
       rotation * ROTATION_SCALE,
       depth - 1);
   
   // draw right branch
   draw_tree(surface,
       offsetx + directionx * size,
       offsety + directiony * size,
       directionx * cos(-rotation) + directiony * sin(-rotation),
       directionx * -sin(-rotation) + directiony * cos(-rotation),
       size * rand_fl() / SCALE + size * (SCALE - 1) / SCALE,
       rotation * ROTATION_SCALE,
       depth - 1);
 }

}

void render(SDL_Surface * surface){

 SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));
 draw_tree(surface,
     surface->w / 2.0,
     surface->h - 10.0,
     0.0, -1.0,
     INITIAL_LENGTH,
     PI / 8,
     BRANCHES);
 SDL_UpdateRect(surface, 0, 0, 0, 0);

}

int main(){

 SDL_Surface * screen;
 SDL_Event evt;
 SDL_Init(SDL_INIT_VIDEO);
 srand((unsigned)time(NULL));
 screen = SDL_SetVideoMode(SIZE, SIZE, 32, SDL_HWSURFACE);
 render(screen);
 while(1){
   if (SDL_PollEvent(&evt)){
     if(evt.type == SDL_QUIT) break;
   }
   SDL_Delay(1);
 }
 SDL_Quit();
 return 0;

}</lang>

Tcl

Library: Tk

<lang tcl>package require Tk

set SIZE 800 set SCALE 4.0 set BRANCHES 14 set ROTATION_SCALE 0.85 set INITIAL_LENGTH 50.0

proc draw_tree {w x y dx dy size theta depth} {

   global SCALE ROTATION_SCALE
   $w create line $x $y [expr {$x + $dx*$size}] [expr {$y + $dy*$size}]
   if {[incr depth -1] >= 0} {

set x [expr {$x + $dx*$size}] set y [expr {$y + $dy*$size}] set ntheta [expr {$theta * $ROTATION_SCALE}]

# Draw left branch draw_tree $w $x $y \ [expr {$dx*cos($theta) + $dy*sin($theta)}] \ [expr {$dy*cos($theta) - $dx*sin($theta)}] \ [expr {$size * (rand() + $SCALE - 1) / $SCALE}] $ntheta $depth # Draw right branch draw_tree $w $x $y \ [expr {$dx*cos(-$theta) + $dy*sin(-$theta)}] \ [expr {$dy*cos(-$theta) - $dx*sin(-$theta)}] \ [expr {$size * (rand() + $SCALE - 1) / $SCALE}] $ntheta $depth

   }

}

pack [canvas .c -width $SIZE -height $SIZE] draw_tree .c [expr {$SIZE/2}] [expr {$SIZE-10}] 0.0 -1.0 $INITIAL_LENGTH \

   [expr {3.1415927 / 8}] $BRANCHES</lang>

SVG

In the same style as Dragon curve#SVG. SVG has no parameterized definitions, so the recursion must be unrolled.

<lang xml><?xml version="1.0" standalone="yes"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"

"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg xmlns="http://www.w3.org/2000/svg"

    xmlns:xlink="http://www.w3.org/1999/xlink"
    width="400" height="320">
 <style type="text/css"><![CDATA[
   line { stroke: black; stroke-width: .05; }
   circle { fill: black; }
 ]]></style>

<defs>

 <g id="stem"> <line x1="0" y1="0" x2="0" y2="-1"/> </g>

 <g id="l0"><use xlink:href="#stem"/></g>
 <g id="l1"> <use xlink:href="#l0" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l0" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l2"> <use xlink:href="#l1" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l1" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l3"> <use xlink:href="#l2" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l2" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l4"> <use xlink:href="#l3" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l3" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l5"> <use xlink:href="#l4" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l4" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l6"> <use xlink:href="#l5" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l5" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l7"> <use xlink:href="#l6" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l6" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l8"> <use xlink:href="#l7" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l7" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>
 <g id="l9"> <use xlink:href="#l8" transform="translate(0, -1) rotate(-35) scale(.7)"/>
             <use xlink:href="#l8" transform="translate(0, -1) rotate(+35) scale(.7)"/>
             <use xlink:href="#stem"/></g>

</defs>

<g transform="translate(200, 320) scale(100)">

 <use xlink:href="#l9"/>

</g>

</svg></lang>