Skip to content

Instantly share code, notes, and snippets.

@redblobgames
Created June 2, 2022 04:37
Show Gist options
  • Save redblobgames/2c0ca81d0e6b19da5d608ee4f731a45a to your computer and use it in GitHub Desktop.
Save redblobgames/2c0ca81d0e6b19da5d608ee4f731a45a to your computer and use it in GitHub Desktop.
Tree generator I wrote in 2011 - but it's for Flash
// Draw simple trees
// Author: [email protected]
// License: MIT
// TODO: read http://procworld.blogspot.com/2011/04/tree-bits.html
// TODO: read http://procworld.blogspot.com/2011/05/mango-sequoia-baobab.html
package {
import flash.display.*;
import flash.geom.Point;
import flash.events.*;
public class treedemo extends Sprite {
public function treedemo() {
stage.scaleMode = 'noScale';
stage.align = 'TL';
stage.frameRate = 60;
/*
scaleX = 48/30.0;
scaleY = 48/30.0;
*/
graphics.beginFill(0x998855);
graphics.drawRect(-1000, -1000, 2000, 2000);
graphics.endFill();
for (var i:int = 0; i < 20; i++) {
for (var j:int = 0; j < 20; j++) {
var layer:Shape = new Shape();
layer.x = 25 + 30*i;
layer.y = 25 + 30*j;
addChild(layer);
draw(layer.graphics);
}
}
}
public static var GREENS:Array = [0x525a29,0x576033,0x616d2f,0x6b703a,0x525633];
public static function draw(g:Graphics):void {
var minAngle:Number = -1.4;
var maxAngle:Number = +1.4;
var trunk_params:Object = {
multiplier: 1.0,
length_variation: 0.9,
children: 3,
segments: 5,
curvature: 0.1,
breadth: 1.0,
grow_towards_light: 0.0
};
var branch_params:Object = {
multiplier: 0.75,
length_variation: 0.7,
children: 2,
segments: 3,
curvature: 0.3,
breadth: 0.9,
grow_towards_light: 0.15
};
function B(p:Point, width:Number, length:Number, angle:Number, params:Object):void {
var i:int;
var newAngle:Number;
var newLength:Number;
var q:Point = p;
var branchPoints:Array = []; // TODO: side branches along the main trunk/branch
// Grow towards the light -- make angle closer to 0.0 (up)
angle = angle * (1.0 - params.grow_towards_light);
// Draw the main branch
g.lineStyle(width < 1.0? 0.0 : width, 0x000000, Math.min(1.0, width));
g.moveTo(p.x, p.y);
for (i = 0; i < params.segments; i++) {
newLength = length / params.segments * (1.0 + params.length_variation * (Math.random() - Math.random()));
q = q.add(Point.polar(newLength, 0.5 * Math.PI * (angle - 1.0)));
g.lineTo(q.x, q.y);
branchPoints.push({point: q, angle: angle});
angle = angle + params.curvature * (Math.random() - Math.random());
}
if (width > 0.1 && length > 1.0 && minAngle < angle && angle < maxAngle) {
// Produce child branches
for (i = 0; i < params.children; i++) {
newAngle = angle + (i/(params.children-1)-0.5+params.curvature*(Math.random()-Math.random()))*params.breadth;
B(q, width * params.multiplier, length * params.multiplier, newAngle, branch_params);
}
}
g.lineStyle();
g.beginFill(GREENS[int(Math.random()*GREENS.length)], 0.5);
g.drawCircle(q.x, q.y, 1.0+Math.sqrt(width));
g.endFill();
}
B(new Point(), 1.5, 5, 0, trunk_params);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment