Fractal tree

From Rosetta Code
Revision as of 14:38, 19 November 2015 by rosettacode>Naereen (→‎{{header|Python}}: Add an image)
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

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

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

Output:

See the XPL0 image and imagine it more orange than green: http://www.zenkinetic.com/Images/RosettaCode/fractalTree.jpg