Fractal tree

From Rosetta Code
Jump to: navigation, search
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

Contents

[edit] AutoHotkey

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

Library: GDIP
#SingleInstance, Force
#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

[edit] BASIC256

Asymmetric fractal tree image created by the BASIC-256 script
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

[edit] BBC BASIC

Fractal tree bbc.gif
      Spread = 25
Scale = 0.76
SizeX% = 400
SizeY% = 300
Depth% = 10
 
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

[edit] C

Library: SDL
Library: SGE
or
Library: cairo
#include <SDL/SDL.h>
#ifdef WITH_CAIRO
#include <cairo.h>
#else
#include <SDL/sge.h>
#endif
#include <cairo.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
 
#ifdef WITH_CAIRO
#define PI 3.1415926535
#endif
 
#define SIZE 800 // determines size of window
#define SCALE 5 // determines how quickly branches shrink (higher value means faster shrinking)
#define BRANCHES 14 // number of branches
#define ROTATION_SCALE 0.75 // determines how slowly the angle between branches shrinks (higher value means slower shrinking)
#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) {
#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);
#else
sge_AALine(surface,
(int)offsetx, (int)offsety,
(int)(offsetx + directionx * size), (int)(offsety + directiony * size),
SDL_MapRGB(surface->format, 0, 0, 0));
#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;
}


[edit] C++

FracTree cpp.png

 
#include <windows.h>
#include <string>
#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;
}
//--------------------------------------------------------------------------------------------------
 

[edit] Clojure

Translation of: Java
Library: Swing
Library: AWT
(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)

[edit] D

[edit] SVG Version

Translation of: Perl 6
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;
}

[edit] Turtle Version

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

Translation of: Logo
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");
}

[edit] Alternative version

Translation of: Java

Using DFL.

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

[edit] F#

Translation of: Perl 6
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>"

[edit] 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
}
}
 

[edit] Go

png converted from output ppm
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)
}
}

[edit] Haskell

Using
Library: HGL
from HackageDB

Using the method of the J contribution

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)

Use e.g.:

*Main> fractalTree 10

[edit] Icon and Unicon

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

WOpen provides graphics I/O

Translation of: Java

[edit] 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;
)

See the talk page for some implementation notes.

[edit] Java

Library: Swing
Library: AWT
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);
}
}

[edit] JavaScript

Library: HTML5
 
<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>
 

[edit] Liberty BASIC

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

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

[edit]

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

[edit] 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]]
 

MathFractalTree.png

[edit] NetRexx

Translation of: Java
Library: Swing
Library: AWT
/* 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
 

[edit] OCaml

Library: ocaml-cairo
#directory "+cairo"
#load "bigarray.cma"
#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*)

[edit] Perl

using the GD::Simple module.

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);
}


[edit] Perl 6

Image is created in SVG format.

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);
}

[edit] PHP

Image is created with GD module. Code adapted from the JavaScript version.

 
<?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);
?>
 


[edit] PicoLisp

This uses the 'brez' line drawing function from Bitmap/Bresenham's line algorithm#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) ) )

[edit] 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
Shorter version:
%!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

[edit] POV-Ray

#include "colors.inc"
#include "transforms.inc"
 
#declare CamLoc = <0, 5, 0>;
#declare CamLook = <0,0,0>;
camera
{
location CamLoc
look_at CamLook
rotate y*90
}
 
light_source
{
CamLoc
color White
}
 
#declare Init_Height = 10;
#declare Spread_Ang = 35;
#declare Branches = 14;
#declare Scaling_Factor = 0.75;
 
#macro Stick(P0, P1)
cylinder {
P0, P1, 0.02
texture { pigment { Green } }
}
#end
 
#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
#end
 
union {
FractalTree(<-2,0,0>, <1,0,0>, 1, Spread_Ang, Branches)
}

[edit] Prolog

SWI-Prolog has a graphic interface : XPCE.

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

[edit] PureBasic

#Spread_Ang     = 35
#Scaling_Factor = 0.75
#Deg_to_Rad = #PI / 180
#SizeH = 500
#SizeV = 375
#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

PB FractalTree.png

[edit] Python

Library: pygame
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())

[edit] Racket

Tree-racket.png
 
#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)
 

[edit] Ruby

Library: Shoes
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

[edit] Scala

Adapted from the Java version. Screenshot below.

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

ScalaTree.png

[edit] 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;

Original source: [1]

[edit] Smalltalk

This example is coded for Squeak Smalltalk.

 
Object subclass: #FractalTree
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'RosettaCode'
 

Methods for FractalTree class:

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

Now open a new Workspace and enter:

 
FractalTree new draw.
 


[edit] SVG

Fractal tree.svg

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

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

[edit] Tcl

Library: Tk
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

[edit] TUSCRIPT

Image is created in SVG-format

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

[edit] XPL0

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

[edit] zkl

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

Translation of: BBC BASIC
Translation of: XPL0
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"));
}();

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.

Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox