diff --git a/tree.c b/tree.c
new file mode 100644
index 0000000..053356d
--- /dev/null
+++ b/tree.c
@@ -0,0 +1,139 @@
+
+#include <stdlib.h>
+#include <math.h>
+#include <helianthus.h>
+
+
+
+
+int seed;
+double t;
+
+const double segmentLength = 5;
+const double segmentWidth = 0.05;
+const double minWidth = 0.5;
+const double branchesPerSegment = 0.2;
+const double leafSize = 200;
+const double leafPerBranch = 1;
+const double leafThreshold = 1 + 200/5*0.05/4*0.5;
+
+
+double randomRange(double min, double max)
+  { return randomFloat()*(max - min) + min; }
+
+double randomIncrement(double deviation)
+  { return randomRange(-deviation, deviation); }
+
+double randomAmplifier(double deviation)
+  { return randomRange(1 - deviation, 1 + deviation); }
+
+
+void leaf(double x, double y, double size) {
+  double r = 0.5*size;//*randomAmplifier(0.5);
+  saveState();
+  noStroke();
+  circle(x, y, r);
+  restoreState();
+}
+
+
+void branch(double x, double y, double angle, double width) {
+  double da = sin(t*randomRange(0.5, 1) + randomIncrement(PI));
+
+  saveState();
+  while(TRUE) {
+    double length = segmentLength * randomAmplifier(0.1);
+
+    double s = sin(angle/180*PI);
+    double c = cos(angle/180*PI);
+    double nx = x + c*length;
+    double ny = y + s*length;
+    double nw = width - segmentWidth;
+    strokeWidth(width);
+    line(x, y, nx, ny);
+
+    if (width > leafThreshold && nw <= leafThreshold && randomFloat() < leafPerBranch && y > leafSize/2) {
+      double dl = randomRange(0, length);
+      leaf(x + c*dl, y + s*dl, leafSize);
+    }
+
+    if (width < minWidth || ny < 0)
+      break;
+
+    x = nx;
+    y = ny;
+    s += randomRange(0, 0.2);
+    c += randomIncrement(0.15);
+    angle = atan2(s, c)/PI*180;
+    width -= segmentWidth;
+
+    translate(x, y);
+    rotate(da*pow(minWidth/width, 2));
+    translate(-x, -y);
+
+    if (randomFloat() < branchesPerSegment) {
+      double k = randomRange(0.1, 0.3);
+      double w = sqrt(width*width*k);
+      if (w > minWidth) {
+        width = sqrt(width*width*(1-k));
+        double a = randomNumber(0, 1) ? angle - 90 + randomRange(0, 45)
+                                      : angle + 90 - randomRange(0, 45);
+        branch(x, y, a, w);
+      }
+    }
+  }
+  restoreState();
+}
+
+
+void tree(int seed, double x, double y, double width) {
+  srand(seed);
+  double angle = 90 + randomIncrement(30);
+  width *= randomAmplifier(0.5);
+  int s = randomNumber(0, 1000000);
+
+  saveState();
+  noStroke();
+  srand(s);
+  branch(x, y, angle, width);
+  restoreState();
+
+  saveState();
+  noFill();
+  srand(s);
+  branch(x, y, angle, width);
+  restoreState();
+}
+
+
+void init() {
+  seed = randomNumber(0, 1000000);
+}
+
+
+void draw() {
+  double w = worldGetWidth();
+  double h = worldGetHeight();
+  t += worldGetFrameTime();
+
+  if (keyWentDown("space")) seed = randomNumber(0, 1000000);
+
+  saveState();
+  translate(w/2, h*0.9);
+  scale(1, -1);
+
+  fill(colorByName("green"));
+  stroke(colorByName("black"));
+  tree(seed, 0, 0, 20);
+
+  restoreState();
+}
+
+
+int main() {
+  worldSetVariableFrameRate();
+  worldSetResizable(TRUE);
+  worldSetInit(&init);
+  worldSetDraw(&draw);
+  worldRun();
+}