Thursday, 21 May 2009

Pythagoras Tree

A Pythagoras tree is a simple vector graphics image:

The following F# program uses the F# for Visualization library to render this image:

#light

open System.Windows.Media
open FlyingFrog.Graphics

let pi = System.Math.PI

let rotate t = RotateTransform(t / pi * 180.).Value

let branches m =
[ m * rotate(pi/2. - asin(4. / 5.)) * scale(4. / 5., 4. / 5.) *
translate(0., 1.);
m * translate(-1., 0.) * rotate(-pi/2. + asin(3. / 5.)) *
scale(3. / 5., 3. / 5.) * translate(1., 1.) ]

let line_loop xys = Contour.Closed [ for x, y in xys -> line_to x y ]

let square = line_loop [1., 0.; 1., 1.; 0., 1.; 0., 0.]

let shape brush m =
Shape([ Interior brush;
Stroke(Brushes.DarkGreen, { width = 0.01 }) ],
[ Contour.map (fun p -> p * m) square ])

let trunks brush ms = Group(List.map (shape brush) ms)

let rec tree n ms =
if n=0 then [trunks Brushes.Green ms] else
let ms' = List.collect branches ms
trunks Brushes.BurlyWood ms :: tree (n-1) ms'

do
let view = View(Group[])
for n = 1 to 12 do
view.Scene <- Group(tree n [Matrix.Identity])
Run()

Download and run the demo!.

2 comments:

fededevita said...

List.collect?

I get the following:
The value, constructor, namespace or type 'collect' is not defined.

Am I missing something completely obvious?

Flying Frog Consultancy Ltd. said...

The List.collect function is new in the F# May 2009 CTP (version 1.9.6.16).