Fractal tree

From Rosetta Code
Revision as of 05:06, 6 March 2016 by Trizen (talk | contribs) (→‎{{header|Sidef}}: changed the keyword "require" to function call)
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


Cf.


AutoHotkey

Image - Link, since uploads seem to be disabled currently.

Library: GDIP

<lang AutoHotkey>#SingleInstance, Force

  1. NoEnv

SetBatchLines, -1

Uncomment if Gdip.ahk is not in your standard library
#Include, Gdip.ahk

FileOut := A_Desktop "\MyNewFile.png" TreeColor := 0xff0066ff ; ARGB TrunkWidth := 10 ; Pixels TrunkLength := 80 ; Pixels Angle := 60 ; Degrees ImageWidth := 670 ; Pixels ImageHeight := 450 ; Pixels Branches := 13 Decrease := 0.81

Angle := (Angle * 0.01745329252) / 2 , Points := {} , Points[1, "Angle"] := 0 , Points[1, "X"] := ImageWidth // 2 , Points[1, "Y"] := ImageHeight - TrunkLength

if (!pToken := Gdip_Startup()) { MsgBox, 48, Gdiplus error!, Gdiplus failed to start. Please ensure you have Gdiplus on your system. ExitApp } OnExit, Exit

pBitmap := Gdip_CreateBitmap(ImageWidth, ImageHeight) , G := Gdip_GraphicsFromImage(pBitmap) , Gdip_SetSmoothingMode(G, 4) , pBrush := Gdip_BrushCreateSolid(0xff000000) , Gdip_FillRectangle(G, pBrush, -5, -5, ImageWidth + 10, ImageHeight + 10) , Gdip_DeleteBrush(pBrush) , pPen := Gdip_CreatePen(TreeColor, TrunkWidth/Decrease) , Gdip_DrawLine(G, pPen, Points.1.X, Points.1.Y, Points.1.X, ImageHeight) , Gdip_DeletePen(pPen)

Loop, % Branches { NewPoints := {} pPen := Gdip_CreatePen(TreeColor, TrunkWidth) for Each, Point in Points { N1 := A_Index * 2 , N2 := (A_Index * 2) + 1 , NewPoints[N1, "X"] := Point.X + (TrunkLength * Sin(NewPoints[N1, "Angle"] := Point.Angle - Angle)) , NewPoints[N1, "Y"] := Point.Y - (TrunkLength * Cos(NewPoints[N1].Angle)) , NewPoints[N2, "X"] := Point.X + (TrunkLength * Sin(NewPoints[N2, "Angle"] := Point.Angle + Angle)) , NewPoints[N2, "Y"] := Point.Y - (TrunkLength * Cos(NewPoints[N2].Angle)) , Gdip_DrawLine(G, pPen, Point.X, Point.Y, NewPoints[N1].X, NewPoints[N1].Y) , Gdip_DrawLine(G, pPen, Point.X, Point.Y, NewPoints[N2].X, NewPoints[N2].Y) } TrunkWidth *= Decrease , TrunkLength *= Decrease , Points := NewPoints , Gdip_DeletePen(pPen) }

Gdip_SaveBitmapToFile(pBitmap, FileOut) , Gdip_DisposeImage(pBitmap) , Gdip_DeleteGraphics(G) Run, % FileOut

Exit: Gdip_Shutdown(pToken) ExitApp</lang>

BASIC256

Asymmetric fractal tree image created by the BASIC-256 script

<lang basic256>graphsize 300,300

level = 12 : len =63 # initial values x = 230: y = 285 rotation = pi/2

A1 = pi/27 : A2 = pi/8 # constants which determine shape C1 = 0.7 : C2 = 0.85

dim xs(level+1) : dim ys(level+1) # stacks

fastgraphics color black rect 0,0,graphwidth,graphheight refresh color green gosub tree refresh imgsave "Fractal_tree_BASIC-256.png", "PNG" end

tree: xs[level] = x : ys[level] = y gosub putline if level>0 then level = level - 1 len = len*C1 rotation = rotation - A1 gosub tree len = len/C1*C2 rotation = rotation + A1 + A2 gosub tree rotation = rotation - A2 len = len/C2 level = level + 1 end if x = xs[level] : y = ys[level] return

putline: yn = -sin(rotation)*len + y xn = cos(rotation)*len + x line x,y,xn,yn x = xn : y = yn return</lang>

BBC BASIC

Output:








<lang bbcbasic>

     Spread = 25
     Scale = 0.76
     SizeX% = 400
     SizeY% = 300
     Depth% = 10

</lang><lang bbcbasic>

     VDU 23,22,SizeX%;SizeY%;8,16,16,128
     
     PROCbranch(SizeX%, 0, SizeY%/2, 90, Depth%)
     END
     DEF PROCbranch(x1, y1, size, angle, depth%)
     LOCAL x2, y2
     x2 = x1 + size * COSRAD(angle)
     y2 = y1 + size * SINRAD(angle)
     VDU 23,23,depth%;0;0;0;
     LINE x1, y1, x2, y2
     IF depth% > 0 THEN
       PROCbranch(x2, y2, size * Scale, angle - Spread, depth% - 1)
       PROCbranch(x2, y2, size * Scale, angle + Spread, depth% - 1)
     ENDIF
     ENDPROC</lang>

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>


C++

<lang cpp>

  1. include <windows.h>
  2. include <string>
  3. include <math.h>

//-------------------------------------------------------------------------------------------------- using namespace std;

//-------------------------------------------------------------------------------------------------- const float PI = 3.1415926536f;

//-------------------------------------------------------------------------------------------------- class myBitmap { public:

   myBitmap() : pen( NULL ) {}
   ~myBitmap()
   {

DeleteObject( pen ); DeleteDC( hdc ); DeleteObject( bmp );

   }
   bool create( int w, int h )
   {

BITMAPINFO bi; void *pBits; ZeroMemory( &bi, sizeof( bi ) ); bi.bmiHeader.biSize = sizeof( bi.bmiHeader ); bi.bmiHeader.biBitCount = sizeof( DWORD ) * 8; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biWidth = w; bi.bmiHeader.biHeight = -h;

HDC dc = GetDC( GetConsoleWindow() ); bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 ); if( !bmp ) return false;

hdc = CreateCompatibleDC( dc ); SelectObject( hdc, bmp ); ReleaseDC( GetConsoleWindow(), dc );

width = w; height = h;

return true;

   }
   void setPenColor( DWORD clr )
   {

if( pen ) DeleteObject( pen ); pen = CreatePen( PS_SOLID, 1, clr ); SelectObject( hdc, pen );

   }
   void saveBitmap( string path )
   {

BITMAPFILEHEADER fileheader; BITMAPINFO infoheader; BITMAP bitmap; DWORD* dwpBits; DWORD wb; HANDLE file;

GetObject( bmp, sizeof( bitmap ), &bitmap );

dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight]; ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) ); ZeroMemory( &infoheader, sizeof( BITMAPINFO ) ); ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );

infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8; infoheader.bmiHeader.biCompression = BI_RGB; infoheader.bmiHeader.biPlanes = 1; infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader ); infoheader.bmiHeader.biHeight = bitmap.bmHeight; infoheader.bmiHeader.biWidth = bitmap.bmWidth; infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );

fileheader.bfType = 0x4D42; fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER ); fileheader.bfSize = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;

GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );

file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL ); WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL ); WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL ); CloseHandle( file );

delete [] dwpBits;

   }
   HDC getDC()     { return hdc; }
   int getWidth()  { return width; }
   int getHeight() { return height; }

private:

   HBITMAP bmp;
   HDC	    hdc;
   HPEN    pen;
   int     width, height;

}; //-------------------------------------------------------------------------------------------------- class vector2 { public:

   vector2() { x = y = 0; }
   vector2( int a, int b ) { x = a; y = b; }
   void set( int a, int b ) { x = a; y = b; }
   void rotate( float angle_r )
   {

float _x = static_cast<float>( x ), _y = static_cast<float>( y ), s = sinf( angle_r ), c = cosf( angle_r ), a = _x * c - _y * s, b = _x * s + _y * c;

x = static_cast<int>( a ); y = static_cast<int>( b );

   }
   int x, y;

}; //-------------------------------------------------------------------------------------------------- class fractalTree { public:

   fractalTree()		      { _ang = DegToRadian( 24.0f ); }
   float DegToRadian( float degree ) { return degree * ( PI / 180.0f ); }
   void create( myBitmap* bmp )
   {

_bmp = bmp; float line_len = 130.0f;

vector2 sp( _bmp->getWidth() / 2, _bmp->getHeight() - 1 ); MoveToEx( _bmp->getDC(), sp.x, sp.y, NULL ); sp.y -= static_cast<int>( line_len ); LineTo( _bmp->getDC(), sp.x, sp.y);

drawRL( &sp, line_len, 0, true ); drawRL( &sp, line_len, 0, false );

   }

private:

   void drawRL( vector2* sp, float line_len, float a, bool rg )
   {

line_len *= .75f; if( line_len < 2.0f ) return;

MoveToEx( _bmp->getDC(), sp->x, sp->y, NULL ); vector2 r( 0, static_cast<int>( line_len ) );

       if( rg ) a -= _ang;
       else a += _ang; 

r.rotate( a ); r.x += sp->x; r.y = sp->y - r.y;

LineTo( _bmp->getDC(), r.x, r.y );

drawRL( &r, line_len, a, true ); drawRL( &r, line_len, a, false );

   }
   myBitmap* _bmp;
   float     _ang;

}; //-------------------------------------------------------------------------------------------------- int main( int argc, char* argv[] ) {

   ShowWindow( GetConsoleWindow(), SW_MAXIMIZE );
   myBitmap bmp;
   bmp.create( 640, 512 );
   bmp.setPenColor( RGB( 255, 255, 0 ) );
   fractalTree tree;
   tree.create( &bmp );
   BitBlt( GetDC( GetConsoleWindow() ), 0, 20, 648, 512, bmp.getDC(), 0, 0, SRCCOPY );
   bmp.saveBitmap( "f://rc//fracTree.bmp" );
   system( "pause" );
   return 0;

} //-------------------------------------------------------------------------------------------------- </lang>

Clojure

Translation of: Java
Library: Swing
Library: AWT

<lang Clojure>(import '[java.awt Color Graphics] 'javax.swing.JFrame)

(defn deg-to-radian [deg] (* deg Math/PI 1/180)) (defn cos-deg [angle] (Math/cos (deg-to-radian angle))) (defn sin-deg [angle] (Math/sin (deg-to-radian angle)))

(defn draw-tree [^Graphics g, x y angle depth]

 (when (pos? depth)
   (let [x2 (+ x (int (* depth 10 (cos-deg angle))))

y2 (+ y (int (* depth 10 (sin-deg angle))))]

     (.drawLine g x y x2 y2)
     (draw-tree g x2 y2 (- angle 20) (dec depth))
     (recur     g x2 y2 (+ angle 20) (dec depth)))))

(defn fractal-tree [depth]

 (doto (proxy [JFrame] []

(paint [g] (.setColor g Color/BLACK) (draw-tree g 400 500 -90 depth)))

   (.setBounds 100 100 800 600)
   (.setResizable false)
   (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
   (.show)))

(fractal-tree 9)</lang>

Common Lisp

Translation of: Clojure

<lang lisp>;; (require :lispbuilder-sdl)

(defun deg-to-radian (deg)

 "converts degrees to radians"
 (* deg pi 1/180))

(defun cos-deg (angle)

 "returns cosin of the angle expressed in degress"
 (cos (deg-to-radian angle)))

(defun sin-deg (angle)

 "returns sin of the angle expressed in degress"
 (sin (deg-to-radian angle)))

(defun draw-tree (surface x y angle depth)

 "draws a branch of the tree on the sdl-surface"
 (when (plusp depth)
   (let ((x2 (+ x (round (* depth 10 (cos-deg angle)))))

(y2 (+ y (round (* depth 10 (sin-deg angle))))))

     (sdl:draw-line-* x y x2 y2 :surface surface :color sdl:*green*)
     (draw-tree surface x2 y2 (- angle 20) (1- depth))
     (draw-tree surface x2 y2 (+ angle 20) (1- depth)))))

(defun fractal-tree (depth)

 "shows a window with a fractal tree"
 (sdl:with-init ()
   (sdl:window 800 600 :title-caption "fractal-tree")
   (sdl:clear-display sdl:*black*)
   (draw-tree sdl:*default-surface* 400 500 -90 depth)
   (sdl:update-display)
   (sdl:with-events ()
     (:video-expose-event ()

(sdl:update-display))

     (:quit-event ()

t))))

(fractal-tree 9) </lang>

D

SVG Version

Translation of: Perl 6

<lang d>import std.stdio, std.math;

enum width = 1000, height = 1000; // Image dimension. enum length = 400; // Trunk size. enum scale = 6.0 / 10; // Branch scale relative to trunk.

void tree(in double x, in double y, in double length, in double angle) {

   if (length < 1)
       return;
   immutable x2 = x + length * angle.cos;
   immutable y2 = y + length * angle.sin;
   writefln("<line x1='%f' y1='%f' x2='%f' y2='%f' " ~
            "style='stroke:black;stroke-width:1'/>", x, y, x2, y2);
   tree(x2, y2, length * scale, angle + PI / 5);
   tree(x2, y2, length * scale, angle - PI / 5);

}

void main() {

   "<svg width='100%' height='100%' version='1.1'
    xmlns='http://www.w3.org/2000/svg'>".writeln;
   tree(width / 2.0, height, length, 3 * PI / 2);
   "</svg>".writeln;

}</lang>

Turtle Version

This uses the turtle module from the Dragon Curve task, and the module from the Grayscale Image task.

Translation of: Logo

<lang d>import grayscale_image, turtle;

void tree(Color)(Image!Color img, ref Turtle t, in uint depth,

                in real step, in real scale, in real angle) {
   if (depth == 0) return;
   t.forward(img, step);
   t.right(angle);
   img.tree(t, depth - 1, step * scale, scale, angle);
   t.left(2 * angle);
   img.tree(t, depth - 1, step * scale, scale, angle);
   t.right(angle);
   t.forward(img, -step);

}

void main() {

   auto img = new Image!Gray(330, 300);
   auto t = Turtle(165, 270, -90);
   img.tree(t, 10, 80, 0.7, 30);
   img.savePGM("fractal_tree.pgm");

}</lang>

Alternative version

Translation of: Java

Using DFL. <lang d>import dfl.all; import std.math;

class FractalTree: Form {

   private immutable 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(Exception e) {
       msgBox(e.msg, "Fatal Error", MsgBoxButtons.OK, MsgBoxIcon.ERROR);        
       result = 1;
   }   
   return result;

}</lang>

F#

Translation of: Perl 6

<lang fsharp>let (cos, sin, pi) = System.Math.Cos, System.Math.Sin, System.Math.PI

let (width, height) = 1000., 1000. // image dimension let scale = 6./10. // branch scale relative to trunk let length = 400. // trunk size

let rec tree x y length angle =

   if length >= 1. then
       let (x2, y2) = x + length * (cos angle),  y + length * (sin angle)
       printfn "<line x1='%f' y1='%f' x2='%f' y2='%f' style='stroke:rgb(0,0,0);stroke-width:1'/>"
           x y x2 y2
       tree x2 y2 (length*scale) (angle + pi/5.)
       tree x2 y2 (length*scale) (angle - pi/5.)

printfn "<?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.) printfn "</svg>"</lang>

Fantom

<lang fantom> using fwt using gfx

class FractalCanvas : Canvas {

 new make () : super() {}
 Void drawTree (Graphics g, Int x1, Int y1, Int angle, Int depth)
 {
   if (depth == 0) return
   Int x2 := x1 + (angle.toFloat.toRadians.cos * depth * 10.0).toInt;
   Int y2 := y1 + (angle.toFloat.toRadians.sin * depth * 10.0).toInt;
   g.drawLine(x1, y1, x2, y2);
   drawTree(g, x2, y2, angle - 20, depth - 1);
   drawTree(g, x2, y2, angle + 20, depth - 1);
 }
 override Void onPaint (Graphics g)
 {
   drawTree (g, 400, 500, -90, 9)
 }

}

class FractalTree {

 public static Void main ()
 {
   Window
   {
     title = "Fractal Tree"
     size = Size(800, 600)
     FractalCanvas(),
   }.open
 }

} </lang>

Go

png converted from output ppm

<lang go>package main

// Files required to build supporting package raster are found in: // * Bitmap // * Grayscale image // * Xiaolin Wu's line algorithm // * Write a PPM file

import (

   "math"
   "raster"

)

const (

   width  = 400
   height = 300
   depth  = 8
   angle  = 12
   length = 50
   frac   = .8

)

func main() {

   g := raster.NewGrmap(width, height)
   ftree(g, width/2, height*9/10, length, 0, depth)
   g.Bitmap().WritePpmFile("ftree.ppm")

}

func ftree(g *raster.Grmap, x, y, distance, direction float64, depth int) {

   x2 := x + distance*math.Sin(direction*math.Pi/180)
   y2 := y - distance*math.Cos(direction*math.Pi/180)
   g.AaLine(x, y, x2, y2)
   if depth > 0 {
       ftree(g, x2, y2, distance*frac, direction-angle, depth-1)
       ftree(g, x2, y2, distance*frac, direction+angle, depth-1)
   }

}</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

Icon and Unicon

<lang Icon>procedure main() WOpen("size=800,600", "bg=black", "fg=white") | stop("*** cannot open window") drawtree(400,500,-90,9) WDone() end

link WOpen

procedure drawtree(x,y,angle,depth) if depth > 0 then {

  x2 := integer(x + cos(dtor(angle)) * depth * 10)
  y2 := integer(y + sin(dtor(angle)) * depth * 10)
  DrawLine(x,y,x2,y2)   
  drawtree(x2,y2,angle-20, depth-1)
  drawtree(x2,y2,angle+20, depth-1)
  }

return end</lang>

WOpen provides graphics I/O

Translation of: Java

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 {

   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(Math.toRadians(angle)) * depth * 10.0);
       int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * 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

Implementation using HTML5 canvas element to draw tree structure. <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>

jq

The following generates SVG, which can be viewed by following the link below. <lang jq># width and height define the outer dimensions;

  1. len defines the trunk size;
  2. scale defines the branch length relative to the trunk;

def main(width; height; len; scale):

 def PI: (1|atan)*4;
 def precision(n):
   def pow(k): . as $in | reduce range(0;k) as $i (1; .*$in);
   if . < 0 then - (-. | precision(n))
   else 
     (10|pow(n)) as $power
   | (. * 10 * $power) | floor as $x | ($x % 10) as $r
   | ((if $r < 5 then $x else $x + 5 end) / 10 | floor) / $power
   end;
 def p2: precision(2);
 def tree(x; y; len; angle):
   if len < 1 then empty
   else
     (x + len * (angle|cos)) as $x2 
   | (y + len * (angle|sin)) as $y2
   | (if len < 10 then 1 else 2 end) as $swidth
   | (if len < 10 then "blue" else "black" end) as $stroke
   | "<line x1='\(x|p2)' y1='\(y|p2)' x2='\($x2|p2)' y2='\($y2|p2)' style='stroke:\($stroke); stroke-width:\($swidth)'/>",
     tree($x2; $y2; len * scale; angle + PI / 5),
     tree($x2; $y2; len * scale; angle - PI / 5)
   end
 ;

 "<svg width='100%' height='100%' version='1.1'
       xmlns='http://www.w3.org/2000/svg'>",
       tree(width / 2; height; len; 3 * PI / 2),
 "</svg>"

main(1000; 1000; 400; 6/10)</lang>

Output:

$ jq -r -n -r -f Fractal_tree_svg.jq > Fractal_tree.svg

Fractal_tree.svg


Liberty BASIC

LB includes Logo-type turtle commands, so can be drawn that way as well as that shown here. <lang lb>

NoMainWin

sw = 640 : sh = 480 WindowWidth = sw+8 : WindowHeight = sh+31 UpperLeftX = (DisplayWidth -sw)/2 UpperLeftY = (DisplayHeight-sh)/2 Open"Fractal Tree" For Graphics_nf_nsb As #g

  1. g "Down; Color darkgreen; TrapClose halt"

h$ = "#g"

'initial assignments initAngle = Acs(-1)*1.5 'radian equivalent of 270 degrees

   theta = 29 * (Acs(-1)/180) 'convert 29 degrees to radians
  length = 110 'length in pixels
   depth = 25   'max recursion depth
   'draw the tree
   Call tree h$, 320, 470, initAngle, theta, length, depth
   #g "Flush; when leftButtonDown halt" 'L-click to exit
   Wait

Sub halt handle$

   Close #handle$
   End

End Sub

Sub tree h$, x, y, initAngle, theta, length, depth

   Scan
   newX = Cos(initAngle) * length + x
   newY = Sin(initAngle) * length + y
   #h$ "Line ";x;" ";y;" ";newX;" ";newY
   length = length * .78
   depth = depth - 1
   If depth > 0 Then
       Call tree h$, newX, newY, initAngle-theta, theta, length, depth
       Call tree h$, newX, newY, initAngle+theta, theta, length, depth
   End If

End Sub

</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 / Wolfram Language

<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>

NetRexx

Translation of: Java
Library: Swing
Library: AWT

<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols binary

import java.awt.Color import java.awt.Graphics import javax.swing.JFrame

class RFractalTree public extends JFrame

 properties constant
   isTrue  = (1 == 1)
   isFalse = \isTrue
 -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 method RFractalTree() public
   super('Fractal Tree')
   setBounds(100, 100, 800, 600)
   setResizable(isFalse)
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
   return
 -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 method drawTree(g = Graphics, x1 = int, y1 = int, angle = double, depth = int) private
   if depth \= 0 then do
     x2 = x1 + (int Math.cos(Math.toRadians(angle)) * depth * 10.0)
     y2 = y1 + (int Math.sin(Math.toRadians(angle)) * 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)
     end
   return
 -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 method paint(g = Graphics) public
   g.setColor(Color.BLACK)
   drawTree(g, 400, 500, -90, 9)
   return
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 method main(args = String[])public static
   RFractalTree().setVisible(isTrue)
   return

</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 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>

PHP

Image is created with GD module. Code adapted from the JavaScript version. <lang php> <?php header("Content-type: image/png");

$width = 512; $height = 512; $img = imagecreatetruecolor($width,$height); $bg = imagecolorallocate($img,255,255,255); imagefilledrectangle($img, 0, 0, $width, $width, $bg);

$depth = 8; function drawTree($x1, $y1, $angle, $depth){

   global $img;
   
   if ($depth != 0){
       $x2 = $x1 + (int)(cos(deg2rad($angle)) * $depth * 10.0);
       $y2 = $y1 + (int)(sin(deg2rad($angle)) * $depth * 10.0);
       
       imageline($img, $x1, $y1, $x2, $y2, imagecolorallocate($img,0,0,0));
       
       drawTree($x2, $y2, $angle - 20, $depth - 1);
       drawTree($x2, $y2, $angle + 20, $depth - 1);
   }

}

drawTree($width/2, $height, -90, $depth);

imagepng($img); imagedestroy($img); ?> </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 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>

Shorter version:<lang postscript>%!PS-Adobe-3.0 %%BoundingBox: 0 0 300 300 /!0 { dup 1 sub dup 0 gt } def /trunk { 0 0 moveto 0 60 translate 0 0 lineto stroke } def

/branch { gsave scale rotate dup d exch sub d div setgray tree grestore } def /L { 30 .8 .8 branch } def /M {-10 .7 .7 branch } def /R {-35 .7 .7 branch } def /tree { trunk !0 { L M R } if pop } def

/d 10 def 5 setlinewidth 1 setlinecap 170 20 translate d tree pop %%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

File:Fractal-tree-python.png
Library: pygame

<lang python>import pygame, math

pygame.init() window = pygame.display.set_mode((600, 600)) pygame.display.set_caption("Fractal Tree") screen = pygame.display.get_surface()

def drawTree(x1, y1, angle, depth):

   if depth:
       x2 = x1 + int(math.cos(math.radians(angle)) * depth * 10.0)
       y2 = y1 + int(math.sin(math.radians(angle)) * depth * 10.0)
       pygame.draw.line(screen, (255,255,255), (x1, y1), (x2, y2), 2)
       drawTree(x2, y2, angle - 20, depth - 1)
       drawTree(x2, y2, angle + 20, depth - 1)

def input(event):

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

drawTree(300, 550, -90, 9) pygame.display.flip() while True:

   input(pygame.event.wait())</lang>

Racket

<lang racket>

  1. lang racket

(require graphics/turtles)

(define (tree n)

 (when (> n 1)
   (draw (/ n 2))
   (tprompt (split* (turn 60) (turn -60))
            (tree (/ n 2)))
   (draw (/ n 2))
   (turn 5)
   (tree (- n 1))))

(turtles #t) (move 100) (turn 90) (move -200) (tree 35) (save-turtle-bitmap "tree.png" 'png) </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>

Scala

Adapted from the Java version. Screenshot below. <lang scala>import swing._ import java.awt.{RenderingHints, BasicStroke, Color}

object FractalTree extends SimpleSwingApplication {

 val DEPTH = 9
 def top = new MainFrame {
   contents = new Panel {
     preferredSize = new Dimension(600, 500)
     override def paintComponent(g: Graphics2D) {
       draw(300, 460, -90, DEPTH)
       def draw(x1: Int, y1: Int, angle: Double, depth: Int) {
         if (depth > 0) {
           val x2 = x1 + (math.cos(angle.toRadians) * depth * 10).toInt
           val y2 = y1 + (math.sin(angle.toRadians) * depth * 10).toInt
           g.setColor(Color.getHSBColor(0.25f - depth * 0.125f / DEPTH, 0.9f, 0.6f))
           g.setStroke(new BasicStroke(depth))
           g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
           g.drawLine(x1, y1, x2, y2)
           draw(x2, y2, angle - 20, depth - 1)
           draw(x2, y2, angle + 20, depth - 1)
         }
       }
     }
   }
 }

}</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]

Sidef

Translation of: Perl

<lang ruby>func tree(img, x, y, scale=6/10, len=400, angle=270) {

   len < 1 && return;
   img.moveTo(x, y);
   img.angle(angle);
   img.line(len);
   var (x1, y1) = img.curPos;
   tree(img, x1, y1, scale, len*scale, angle+35);
   tree(img, x1, y1, scale, len*scale, angle-35);

}

require('GD::Simple');

var (width=1000, height=1000); var img = %s'GD::Simple'.new(width, height); img.fgcolor('black'); img.penSize(1, 1);

tree(img, width/2, height);

var file = %f'tree.png'; var fh = file.open('>:raw'); fh.print(img.png); fh.close;</lang>

Smalltalk

This example is coded for Squeak Smalltalk.

<lang smalltalk> Object subclass: #FractalTree

   instanceVariableNames: 
   classVariableNames: 
   poolDictionaries: 
   category: 'RosettaCode'

</lang>

Methods for FractalTree class:

<lang smalltalk> tree: aPoint length: aLength angle: anAngle

   | p a |
       
   (aLength > 10) ifTrue: [
       p := Pen new.
       p up.
       p goto: aPoint.
       p turn: anAngle.
       p down.
       5 timesRepeat: [
           p go: aLength / 5.
           p turn: 5.
       ].
       a := anAngle - 30.
       3 timesRepeat: [
           self tree: p location length: aLength * 0.7 angle: a.
           a := a + 30.
       ]
   ].

draw

   Display restoreAfter: [
       Display fillWhite.      
       self tree: 700@700 length: 200 angle: 0.
   ]

</lang>

Now open a new Workspace and enter:

<lang smalltalk> FractalTree new draw. </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>

Swift

Image - Link, since uploads seem to be disabled currently. In a playground: <lang swift> import UIKit

extension CGFloat {

 func degrees_to_radians() -> CGFloat {
   return CGFloat(M_PI) * self / 180.0
 }

}

extension Double {

 func degrees_to_radians() -> Double {
   return Double(M_PI) * self / 180.0
 }
 

}


class Tree: UIView {


 func drawTree(x1: CGFloat, y1: CGFloat, angle: CGFloat, depth:Int){
   if depth == 0 {
     return
   }
   let ang = angle.degrees_to_radians()
   let x2:CGFloat = x1 + ( cos(ang) as CGFloat) * CGFloat(depth) * (self.frame.width / 60)
   let y2:CGFloat = y1 + ( sin(ang) as CGFloat) * CGFloat(depth) * (self.frame.width / 60)
   
   let line = drawLine(x1, y1: y1, x2: x2, y2: y2)
 
   line.stroke()
   drawTree(x2, y1: y2, angle: angle - 20, depth: depth - 1)
   drawTree(x2, y1: y2, angle: angle + 20, depth: depth - 1)
 }
 
 func drawLine(x1:CGFloat, y1:CGFloat, x2:CGFloat, y2:CGFloat) -> UIBezierPath
 {
   
   let path = UIBezierPath()
   path.moveToPoint(CGPoint(x: x1,y: y1))
   path.addLineToPoint(CGPoint(x: x2,y: y2))
   path.lineWidth = 1
   return path
 }
 
 override func drawRect(rect: CGRect) {
   
   let color = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
   color.set()
   drawTree(self.frame.width / 2 , y1: self.frame.height * 0.8, angle: -90 , depth: 9 )
 }
 

}


let tree = Tree(frame: CGRectMake(0, 0, 300, 300)) tree </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>

TUSCRIPT

Image is created in SVG-format <lang tuscript> $$ MODE TUSCRIPT dest="fracaltree.svg" ERROR/STOP CREATE (dest,fdf-o,-std-) ACCESS d: WRITE/ERASE/RECORDS/UTF8 $dest s,text MODE DATA $$ header=* <?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: brown; stroke-width: .05; }
 ]]></style>

$$ WRITE/NEXT d header $$ defsbeg=* <defs>

 <g id="stem"> <line x1="0" y1="0" x2="0" y2="-1"/> </g>
 <g id="l"><use xlink:href="#stem"/></g>

$$ WRITE/NEXT d defsbeg $$ LOOP n=10,21 $$ id=n+1,lastnr=VALUE(n) $$ g=*

 <g id="{id}"> <use xlink:href="#{n}" transform="translate(0, -1) rotate(-35) scale(.7)"/>
 <use xlink:href="#{n}" transform="translate(0, -1) rotate(+35) scale(.7)"/> <use xlink:href="#stem"/></g>

$$ WRITE/NEXT d g $$ ENDLOOP $$ defsend = * </defs> <g transform="translate(200, 320) scale(100)">

 <use xlink:href="#{lastnr}"/>

</g> $$ MODE TUSCRIPT WRITE/NEXT d defsend WRITE/NEXT d "</svg>" ENDACCESS d </lang>

XPL0

Output

<lang XPL0>include c:\cxpl\codes;

proc DrawBranch(Lev, Dir, Len, X, Y); int Lev; real Dir, Len; int X, Y; int Red, Grn; [Move(X, Y); X:= X + fix(Len*Cos(Dir)); Y:= Y + fix(Len*Sin(Dir)); Red:= 255-Lev*8; Grn:= Lev*12+100; Line(X, Y, Red<<16+Grn<<8); if Lev < 12 then \limit level of recursion

       [DrawBranch(Lev+1, Dir-0.4, Len*0.8, X, Y);     \left
        DrawBranch(Lev+1, Dir+0.1, Len*0.8, X, Y);     \right
       ];

];

[SetVid($112); \set 640x480x24 video graphics mode DrawBranch(0, -3.14159/2.0, 80.0, 360, 460); if ChIn(1) then []; \wait for keystroke SetVid(3); \restore normal text mode ]</lang>

zkl

Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl

Translation of: BBC BASIC
Translation of: XPL0

<lang zkl>fcn fractalTree(){

  scale:=0.76;
  sizeX:=400; sizeY:=300;
  bitmap:=PPM(sizeX*2,sizeY*2,0xFF|FF|FF);
  branch:='wrap(x1,y1,size,angle,depth){
     ar:=angle.toRad();
     x2:=x1 - size*ar.cos();
     y2:=y1 + size*ar.sin();
     color:=(0xff-depth*8).shiftLeft(16) + (depth*12+100).shiftLeft(8);
     bitmap.line(x1,y1, x2,y2, color);
     if(depth){
        self.fcn(x2,y2,scale*size,angle - 30,depth - 1,vm.pasteArgs(5));

self.fcn(x2,y2,scale*size,angle + 8, depth - 1,vm.pasteArgs(5));

     }
  };
  branch(sizeX,0,sizeY/2,90.0,10);
  bitmap.write(File("foo.ppm","wb"));

}();</lang> The funkyness (pasteArgs) in the recursion (self.fcn) is due to the closure ('wrap): the closed over args are stashed in the arglist, they need to be added to the parameters when recursing.