Fractal tree

From Rosetta Code
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

or

Library: cairo

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

  1. ifdef WITH_CAIRO
  2. include <cairo.h>
  3. else
  4. include <SDL/sge.h>
  5. endif
  6. include <cairo.h>
  7. include <stdlib.h>
  8. include <time.h>
  9. include <math.h>
  1. ifdef WITH_CAIRO
  2. define PI 3.1415926535
  3. endif
  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) {
  1. ifdef WITH_CAIRO
 cairo_surface_t *surf = cairo_image_surface_create_for_data( surface->pixels,
                                                              CAIRO_FORMAT_RGB24,

surface->w, surface->h, surface->pitch );

 cairo_t *ct = cairo_create(surf);
 cairo_set_line_width(ct, 1);
 cairo_set_source_rgba(ct, 0,0,0,1);
 cairo_move_to(ct, (int)offsetx, (int)offsety);
 cairo_line_to(ct, (int)(offsetx + directionx * size), (int)(offsety + directiony * size));
 cairo_stroke(ct);
  1. else
 sge_AALine(surface,
     (int)offsetx, (int)offsety,
     (int)(offsetx + directionx * size), (int)(offsety + directiony * size),
     SDL_MapRGB(surface->format, 0, 0, 0));
  1. endif
 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>

D

Translation of Java, using DFL <lang d>import dfl.all; import std.math;

class FractalTree: Form {

   private const double DEG_TO_RAD = PI / 180.0;
   this() {
       width = 600;
       height = 500;
       text = "Fractal Tree";
       backColor = Color(0xFF, 0xFF, 0xFF);
       startPosition = FormStartPosition.CENTER_SCREEN;
       formBorderStyle = FormBorderStyle.FIXED_DIALOG;
       maximizeBox = false;
   }
   private void drawTree(Graphics g, Pen p, int x1, int y1, double angle, int depth) {
       if (depth == 0) return;
       int x2 = x1 + cast(int) (cos(angle * DEG_TO_RAD) * depth * 10.0);
       int y2 = y1 + cast(int) (sin(angle * DEG_TO_RAD) * depth * 10.0);
       g.drawLine(p, x1, y1, x2, y2);
       drawTree(g, p, x2, y2, angle - 20, depth - 1);
       drawTree(g, p, x2, y2, angle + 20, depth - 1);
   }
   
   protected override void onPaint(PaintEventArgs ea){
       super.onPaint(ea);
       Pen p = new Pen(Color(0, 0xAA, 0));
       drawTree(ea.graphics, p, 300, 450, -90, 9);
   }

}

int main() {

   int result = 0; 
   try {
       Application.run(new FractalTree);
   } catch(Object o) {
       msgBox(o.toString(), "Fatal Error", MsgBoxButtons.OK, MsgBoxIcon.ERROR);        
       result = 1;
   }   
   return result;

}</lang>

Haskell

Using

Library: HGL

from HackageDB

Using the method of the J contribution <lang haskell>import Graphics.HGL.Window import Graphics.HGL.Run import Control.Arrow import Control.Monad import Data.List

enumBase :: Int -> Int -> Int enumBase n = mapM (enumFromTo 0). replicate n. pred

psPlus (a,b) (p,q) = (a+p, b+q)

toInt :: Double -> Int toInt = fromIntegral.round

intPoint = toInt *** toInt

pts n =

 map (map (intPoint.psPlus (100,0)). ((0,300):). scanl1 psPlus. ((r,300):). zipWith (\h a -> (h*cos a, h*sin a)) rs) hs
 where
   [r,h,sr,sh] = [50, pi/5, 0.9, 0.75]
   rs   = take n $ map (r*) $ iterate(*sr) sr
   lhs  = map (map (((-1)**).fromIntegral)) $ enumBase n 2
   rhs  = take n $ map (h*) $ iterate(*sh) 1
   hs   = map (scanl1 (+). zipWith (*)rhs) lhs

fractalTree :: Int -> IO () fractalTree n =

  runWindow "Fractal Tree" (500,600)
   (\w -> setGraphic w (overGraphics ( map polyline $ pts (n-1))) >> getKey w)</lang>

Use e.g.:

*Main> fractalTree 10

J

<lang j>require'gl2'

L0=: 50 NB. initial length A0=: 1r8p1 NB. initial angle: pi divided by 8 dL=: 0.9 NB. shrink factor for length dA=: 0.75 NB. shrink factor for angle N=: 14 NB. number of branches

L=: L0*dL^1+i.N NB. lengths of line segments

NB. relative angles of successive line segments A=: A0*(dA^i.N) +/\@:*("1) _1 ^ #:i.2 ^ N

NB. end points for each line segment P=: 0 0+/\@,"2 +.*.inv (L0,0),"2 L,"0"1 A

P_C_paint=: gllines_jgl2_ bind (10 + ,/"2 P-"1<./,/P) wd 0 :0

pc P closeok;
xywh 0 0 250 300;
cc C isigraph rightmove bottommove;
pas 0 0;
pshow;

)</lang>

See the talk page for some implementation notes.

Java

Library: Swing
Library: AWT

<lang java>import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame;

public class FractalTree extends JFrame {

   private final double DEG_TO_RAD = Math.PI / 180.0;
   public FractalTree() {
       super("Fractal Tree");
       setBounds(100, 100, 800, 600);
       setResizable(false);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
   }
   private void drawTree(Graphics g, int x1, int y1, double angle, int depth) {
       if (depth == 0) return;
       int x2 = x1 + (int) (Math.cos(angle * DEG_TO_RAD) * depth * 10.0);
       int y2 = y1 + (int) (Math.sin(angle * DEG_TO_RAD) * depth * 10.0);
       g.drawLine(x1, y1, x2, y2);
       drawTree(g, x2, y2, angle - 20, depth - 1);
       drawTree(g, x2, y2, angle + 20, depth - 1);
   }
   @Override
   public void paint(Graphics g) {
       g.setColor(Color.BLACK);
       drawTree(g, 400, 500, -90, 9);
   }
   public static void main(String[] args) {
       new FractalTree().setVisible(true);
   }

}</lang>

JavaScript

Library: HTML5

<lang JavaScript> <html> <body> <canvas id="canvas" width="600" height="500"></canvas> <script type="text/javascript"> var elem = document.getElementById('canvas'); var context = elem.getContext('2d');

context.fillStyle = '#000'; context.lineWidth = 1;

var deg_to_rad = Math.PI / 180.0; var depth = 9;

function drawLine(x1, y1, x2, y2, brightness){ context.moveTo(x1, y1); context.lineTo(x2, y2); } function drawTree(x1, y1, angle, depth){ if (depth != 0){ var x2 = x1 + (Math.cos(angle * deg_to_rad) * depth * 10.0); var y2 = y1 + (Math.sin(angle * deg_to_rad) * depth * 10.0); drawLine(x1, y1, x2, y2, depth); drawTree(x2, y2, angle - 20, depth - 1); drawTree(x2, y2, angle + 20, depth - 1); } } context.beginPath(); drawTree(300, 500, -90, depth); context.closePath(); context.stroke(); </script> </body> </html> </lang>

<lang logo>to tree :depth :length :scale :angle

 if :depth=0 [stop]
 setpensize round :depth/2
 forward :length
 right :angle
 tree :depth-1 :length*:scale :scale :angle
 left 2*:angle
 tree :depth-1 :length*:scale :scale :angle
 right :angle
 back :length

end

clearscreen tree 10 80 0.7 30</lang>

Mathematica

<lang Mathematica>fractalTree[

 pt : {_, _}, \[Theta]orient_: \[Pi]/2, \[Theta]sep_: \[Pi]/9, 
 depth_Integer: 9] := Module[{pt2},
 If[depth == 0, Return[]];
 pt2 = pt + {Cos[\[Theta]orient], Sin[\[Theta]orient]}*depth;
 DeleteCases[
  Flatten@{
    Line[{pt, pt2}],
    fractalTree[pt2, \[Theta]orient - \[Theta]sep, \[Theta]sep, 
     depth - 1],
    fractalTree[pt2, \[Theta]orient + \[Theta]sep, \[Theta]sep, 
     depth - 1]
    },
  Null
  ]
 ]

Graphics[fractalTree[{0, 0}, \[Pi]/2, \[Pi]/9]] </lang>


OCaml

Library: ocaml-cairo

<lang ocaml>#directory "+cairo"

  1. load "bigarray.cma"
  2. load "cairo.cma"

let img_name = "/tmp/fractree.png" let width = 480 let height = 640

let level = 9 let line_width = 4.0

let color = (1.0, 0.5, 0.0)

let pi = 4.0 *. atan 1.0

let angle_split = pi *. 0.12 let angle_rand = pi *. 0.12

let () =

 Random.self_init();
 let surf = Cairo.image_surface_create Cairo.FORMAT_RGB24 ~width ~height in
 let ctx = Cairo.create surf in
 Cairo.set_antialias ctx Cairo.ANTIALIAS_SUBPIXEL;
 Cairo.set_line_cap ctx Cairo.LINE_CAP_ROUND;
 let draw_line (x,y) (dx,dy) =
   Cairo.move_to ctx x  (float height -. y);
   Cairo.line_to ctx dx (float height -. dy);
   Cairo.stroke ctx;
 in
 let set_color (r,g,b) v =
   Cairo.set_source_rgb ctx ~red:(r *. v) ~green:(g *. v) ~blue:(b *. v);
 in
 let trans_pos (x,y) len angle =
   let _x = cos angle
   and _y = sin angle in
   (x +. (_x *. len),
    y +. (_y *. len))
 in
 let rec loop ~level ~pos ~line_width ~line_len
              ~angle ~angle_split ~angle_rand ~intc =
   if level > 0 then begin
     (* draw the current segment *)
     Cairo.set_line_width ctx line_width;
     set_color color intc;
     let pos_to = trans_pos pos line_len angle in
     draw_line pos pos_to;
     (* evolution of the parameters *)
     let line_width = line_width *. 0.8
     and line_len   = line_len   *. 0.62
     and angle_split = angle_split *. 1.02
     and angle_rand  = angle_rand  *. 1.02
     and intc = intc *. 0.9
     in
     let next_loop =
       loop ~level:(pred level) ~pos:pos_to ~intc
            ~line_width ~line_len ~angle_split ~angle_rand
     in
     (* split *)
     let angle_left  = angle +. angle_split +. Random.float angle_rand
     and angle_right = angle -. angle_split -. Random.float angle_rand
     in
     next_loop ~angle:angle_left;
     next_loop ~angle:angle_right
   end
 in
 let pos = (float width *. 0.5, float height *. 0.1)
 and line_len = float height *. 0.3
 in
 loop ~level ~pos ~angle:(pi /. 2.0)
      ~angle_split ~angle_rand
      ~line_width ~line_len ~intc:1.0;
 Cairo_png.surface_write_to_file surf img_name
 (*Cairo_png.surface_write_to_channel surf stdout*)</lang>

Perl

using the GD::Simple module. <lang perl>use GD::Simple;

my ($width, $height) = (1000,1000); # image dimension my $scale = 6/10; # branch scale relative to trunk my $length = 400; # trunk size

my $img = GD::Simple->new($width,$height); $img->fgcolor('black'); $img->penSize(1,1);

tree($width/2, $height, $length, 270);

print $img->png;


sub tree {

       my ($x, $y, $len, $angle) = @_;
       return if $len < 1;
       $img->moveTo($x,$y);
       $img->angle($angle);
       $img->line($len);
       ($x, $y) = $img->curPos();
       tree($x, $y, $len*$scale, $angle+35);
       tree($x, $y, $len*$scale, $angle-35);

}</lang>


Perl 6

Image is created in wp:SVG format. <lang perl6>my ($width, $height) = (1000,1000); # image dimension my $scale = 6/10; # branch scale relative to trunk my $length = 400; # trunk size

say "<?xml version='1.0' encoding='utf-8' standalone='no'?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'> <svg width='100%' height='100%' version='1.1' xmlns='http://www.w3.org/2000/svg'>";

tree($width/2, $height, $length, 3*pi/2);

say "</svg>";

multi tree($, $, $length where { $length < 1}, $) {} multi tree($x, $y, $length, $angle) { my ($x2, $y2) = ( $x + $length * $angle.cos, $y + $length * $angle.sin); say "<line x1='$x' y1='$y' x2='$x2' y2='$y2' style='stroke:rgb(0,0,0);stroke-width:1'/>"; tree($x2, $y2, $length*$scale, $angle + pi/5); tree($x2, $y2, $length*$scale, $angle - pi/5); }</lang>

PicoLisp

This uses the 'brez' line drawing function from Bitmap/Bresenham's line algorithm#PicoLisp. <lang PicoLisp>(load "@lib/math.l")

(de fractalTree (Img X Y A D)

  (unless (=0 D)
     (let (R (*/ A pi 180.0)  DX (*/ (cos R) D 0.2)  DY (*/ (sin R) D 0.2))
        (brez Img X Y DX DY)
        (fractalTree Img (+ X DX) (+ Y DY) (+ A 30.0) (dec D))
        (fractalTree Img (+ X DX) (+ Y DY) (- A 30.0) (dec D)) ) ) )

(let Img (make (do 300 (link (need 400 NIL 0)))) # Create image 400 x 300

  (fractalTree Img 200 300 -90.0 10)              # Draw tree
  (out "img.pbm"                                  # Write to bitmap file
     (prinl "P1")
     (prinl 400 " " 300)
     (mapc prinl Img) ) )</lang>

PostScript

<lang postscript>%!PS %%BoundingBox: 0 0 300 300 %%EndComments /origstate save def /ld {load def} bind def /m /moveto ld /g /setgray ld /t /translate ld /r /rotate ld /l /lineto ld /rl /rlineto ld /s /scale ld %%EndProlog /PerturbateAngle {} def /PerturbateLength {} def % ** To add perturbations, define properly PerturbateAngle and PerturbateLength, e.g. % /PerturbateAngle {realtime 20 mod realtime 2 mod 1 eq {add} {sub} ifelse} def % /PerturbateLength {realtime 10 mod 100 div realtime 2 mod 1 eq {add} {sub} ifelse} def /fractree { % [INITLENGTH, SPLIT, SFACTOR, BRANCHES]

 dup 3 get 0 gt
 {
   0 0 m dup 0 get 0 exch l
   gsave
     dup 0 get 0 exch t
     dup 1 get PerturbateAngle r
     dup 2 get dup PerturbateLength s
     dup aload pop 1 sub 4 array astore fractree stroke
   grestore
   gsave
     dup 0 get 0 exch t
     dup 1 get neg PerturbateAngle r
     dup 2 get dup PerturbateLength s
     dup aload pop 1 sub 4 array astore fractree stroke
   grestore
 } if pop

} def % /BRANCHES 14 def /INITLENGTH 50 def /SPLIT 35 def /SFACTOR .75 def % % BB check %0 0 m 300 0 rl 0 300 rl -300 0 rl closepath stroke % 0 g 150 0 t [INITLENGTH SPLIT SFACTOR BRANCHES] fractree stroke % showpage origstate restore %%EOF</lang>

POV-Ray

<lang povray>#include "colors.inc"

  1. include "transforms.inc"
  1. declare CamLoc = <0, 5, 0>;
  2. declare CamLook = <0,0,0>;

camera {

 location CamLoc
 look_at CamLook
 rotate y*90

}

light_source {

 CamLoc
 color White

}

  1. declare Init_Height = 10;
  2. declare Spread_Ang = 35;
  3. declare Branches = 14;
  4. declare Scaling_Factor = 0.75;
  1. macro Stick(P0, P1)
 cylinder { 
   P0, P1, 0.02
   texture { pigment { Green } }
 }
  1. end
  1. macro FractalTree(O, D, S, R, B)
 #if (B > 0)
   Stick(O, O+D*S)
   FractalTree(O+D*S, vtransform(D, transform{rotate y*R}),
     S*Scaling_Factor, R, B-1)
   FractalTree(O+D*S, vtransform(D, transform{rotate -y*R}),
     S*Scaling_Factor, R, B-1)
 #end
  1. end

union {

 FractalTree(<-2,0,0>, <1,0,0>, 1, Spread_Ang, Branches)

}</lang>

Prolog

SWI-Prolog has a graphic interface : XPCE. <lang Prolog>fractal :- new(D, window('Fractal')), send(D, size, size(800, 600)), drawTree(D, 400, 500, -90, 9), send(D, open).


drawTree(_D, _X, _Y, _Angle, 0).

drawTree(D, X1, Y1, Angle, Depth) :-

       X2 is X1 + cos(Angle * pi / 180.0) * Depth * 10.0,
       Y2 is Y1 + sin(Angle * pi / 180.0) * Depth * 10.0,

new(Line, line(X1, Y1, X2, Y2, none)), send(D, display, Line), A1 is Angle - 30, A2 is Angle + 30, De is Depth - 1,

       drawTree(D, X2, Y2, A1, De),
       drawTree(D, X2, Y2, A2, De).

</lang>

PureBasic

<lang PureBasic>#Spread_Ang = 35

  1. Scaling_Factor = 0.75
  2. Deg_to_Rad = #PI / 180
  3. SizeH = 500
  4. SizeV = 375
  5. Init_Size = 100

Procedure drawTree(x1, y1, Size, theta, depth)

 Protected x2 = x1 + Cos(theta * #Deg_to_Rad) * Size, y2 = y1 + Sin(theta * #Deg_to_Rad) * Size
 LineXY(x1, y1, x2, y2, RGB(255, 255, 255))
 If depth <= 0
   ProcedureReturn
 EndIf
 ;draw left branch
 drawTree(x2, y2, Size * #Scaling_Factor, theta - #Spread_Ang, depth - 1)
 ;draw right branch
 drawTree(x2, y2, Size * #Scaling_Factor, theta + #Spread_Ang, depth - 1)

EndProcedure


OpenWindow(0, 0, 0, #SizeH, #SizeV, "Fractal Tree", #PB_Window_SystemMenu) Define fractal = CreateImage(#PB_Any, #SizeH, #SizeV, 32) ImageGadget(0, 0, 0, 0, 0, ImageID(fractal))

If StartDrawing(ImageOutput(fractal))

   drawTree(#SizeH / 2, #SizeV, #Init_Size, -90, 9)
 StopDrawing()
 SetGadgetState(0, ImageID(fractal))

EndIf

Repeat: Until WaitWindowEvent(10) = #PB_Event_CloseWindow</lang>

Python

Library: pygame

<lang python>from pygame.locals import * import pygame, sys, math

pygame.init()

WINDOWSIZE = 400 COLOR = (255, 255, 255) REDUCTION = 8.3/10 ANGLE = 27

window = pygame.display.set_mode((WINDOWSIZE, WINDOWSIZE)) pygame.display.set_caption("Fractal Tree")

screen = pygame.display.get_surface()

def getEnd(start, length, angle):

   x, y = start
   x += length*math.cos(math.radians(angle))
   y += length*math.sin(math.radians(angle))
   return (x, y)

def drawTrunk(surface, start, length, angle=-90, count=0):

   if count < 10:
       end = getEnd(start, length, angle)
       pygame.draw.line(surface, COLOR, start, end, 2)
       drawTrunk(surface, end, length*REDUCTION, angle-ANGLE, count+1)
       drawTrunk(surface, end, length*REDUCTION, angle+ANGLE, count+1)

def input(event):

   if event.type == QUIT:
       sys.exit(0)

drawTrunk(screen, (WINDOWSIZE/2, WINDOWSIZE-10), 45.0, -90) pygame.display.flip()

while True:

   input(pygame.event.wait())

</lang>


Ruby

Library: Shoes

<lang Ruby> Shoes.app(:title => "Fractal Tree", :width => 600, :height => 600) do

 background "#fff"
 stroke "#000"
 @deg_to_rad = Math::PI / 180.0
 
 def drawTree(x1, y1, angle, depth)
   if !(depth == 0)
     x2 = x1 + (Math.cos(angle * @deg_to_rad) * depth * 10.0).to_i
     y2 = y1 + (Math.sin(angle * @deg_to_rad) * depth * 10.0).to_i
     
     line x1, y1, x2, y2
     
     drawTree(x2, y2, angle - 20, depth - 1)
     drawTree(x2, y2, angle + 20, depth - 1)      
   end
 end
 
 drawTree(300,550,-90,9)

end </lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

 include "float.s7i";
 include "math.s7i";
 include "draw.s7i";
 include "keybd.s7i";

const float: DEG_TO_RAD is PI / 180.0;

const proc: drawTree (in integer: x1, in integer: y1, in float: angle, in integer: depth) is func

 local
   var integer: x2 is 0;
   var integer: y2 is 0;
 begin
   if depth <> 0 then
     x2 := x1 + trunc(cos(angle * DEG_TO_RAD) * flt(depth * 10));
     y2 := y1 + trunc(sin(angle * DEG_TO_RAD) * flt(depth * 10));
     lineTo(x1, y1, x2, y2, white);
     drawTree(x2, y2, angle - 20.0, depth - 1);
     drawTree(x2, y2, angle + 20.0, depth - 1);
   end if;
 end func;

const proc: main is func

 begin
   screen(600, 500);
   clear(curr_win, black);
   KEYBOARD := GRAPH_KEYBOARD;
   drawTree(300, 470, -90.0, 9);
   ignore(getc(KEYBOARD));
 end func;</lang>

Original source: [1]

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>

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>