Tree generator V1
A small script to draw Tree from perlin noise.
/**
* Copyright mookymook49 ( http://wonderfl.net/user/mookymook49 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/8OS4
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.display.BitmapDataChannel;
import com.bit101.components.*;
/**
* ...
* @author Alexandre Delattre / grafyweb
*/
public class TreeGenerator extends Sprite
{
//////////////////////////////////
public static var _maxDepth:int = 4;
public static var _angleCh:Number = 1;
public static var _courb:Number = 1;
public static var _qteB:Number = 200;
public static var _lengthCoef:Number = 1.4;
public static var _regular:Number = 5;
/////////////////////////////////
public static var perlin:BitmapData;
public static var canvas:BitmapData;
public var arbre:branche;
public static var _rapPerlinX:Number;
public static var _rapPerlinY:Number;
public var uiT:uiTree;
public var seed:Number;
public var offset:Array;
public var channels:uint = BitmapDataChannel.RED | BitmapDataChannel.GREEN | BitmapDataChannel.BLUE ;
public function TreeGenerator():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
this.initPerlin();
TreeGenerator._rapPerlinX = 100 / stage.stageWidth;
TreeGenerator._rapPerlinY = 100 / stage.stageHeight;
this.initTree();
this.uiT = new uiTree(this);
this.uiT.initCommand();
this.addChild(uiT);
this.addEventListener(Event.ENTER_FRAME, refresh);
}
private function refresh(e:Event):void {
arbre.refreshNodes();
this.drawCanvas();
}
public function refreshPerlin():void {
perlin.perlinNoise(TreeGenerator._regular,TreeGenerator._regular, 2, seed, false, true, channels, false,offset);
}
public function initPerlin():void {
///////PERLIN
perlin = new BitmapData(100, 100, true, 0xffffffff);
seed = Math.floor(Math.random() * 10);
offset = [new Point(0, 0), new Point(0, 0)];
channels = BitmapDataChannel.RED | BitmapDataChannel.GREEN | BitmapDataChannel.BLUE ;
perlin.perlinNoise(TreeGenerator._regular,TreeGenerator._regular, 2, seed, false, true, channels, false,offset);
var bmp_perlin:Bitmap = new Bitmap(perlin);
}
public function initTree():void {
//////CANVAS
TreeGenerator.canvas = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);
var bmp_canvas:Bitmap = new Bitmap(TreeGenerator.canvas);
this.addChild(bmp_canvas);
/////TREE
var base:Point = new Point(stage.stageWidth / 2, stage.stageHeight );
arbre = new branche();
this.addChild(arbre);
arbre.init();
arbre._position = new Point(stage.stageWidth / 2, stage.stageHeight);
arbre.initNodes();
}
public function drawCanvas():void {
arbre.drawStructure();
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
//import node;
import flash.display.BitmapDataChannel;
import flash.display.CapsStyle;
/**
* ...
* @author grafyweb
*/
class branche extends Sprite
{
public var _position:Point = new Point(0, 0);
public var _direction:Number = 0;//in radian
public var _segment:int = 20;//quantity of segments
public var _length:Number = 250;//in pixel
public var _maxAngle:Number = 0.8;//radian
public var _pourcStrength:Number = 0.9;//0<x<1
//////////
public var _GOLD:Number = 10;//(1 + Math.sqrt(5)) / 2;
private var _pourcGold:Number = 1;//%
private var _valGold:Vector.<Number> = new Vector.<Number>();
//////////////
private var branches:Vector.<branche> = new Vector.<branche>();
private var nodes:Vector.<node> = new Vector.<node>();
/////////////////
public var _depth:int = 0;
public var _minSeuilBranch:int = 10; //between 0 and 255
public var _maxSeuilBranch:Number = 200;
public var _childrens:Vector.<branche> = new Vector.<branche>();
//////////////////
public var _baseWidth:Number = 20;
public function branche(depth:int = 0)
{
this._depth = depth;
}
public function init():void {
this.calcGold();
this.alpha = (((TreeGenerator._maxDepth - this._depth) / TreeGenerator._maxDepth) * 0.8) + 0.2;
this._maxAngle = TreeGenerator._courb;
this._maxSeuilBranch = TreeGenerator._qteB;
}
public function initNodes():void {
for (var i:int = 0; i < this._segment; i++) {
var tpNode:node = new node();
if (i == 0) {
tpNode._position = this._position;
}else {
tpNode._position = this.polarPosition(this.nodes[i-1]._position,this.nodes[i-1]._direction,this.nodes[i-1]._norme);
}
tpNode._norme = (this._length / this._segment) * (1 - this._pourcGold) + (this._valGold[i] * this._pourcGold);
var col:uint = TreeGenerator.perlin.getPixel32(tpNode._position.x*TreeGenerator._rapPerlinX, tpNode._position.y*TreeGenerator._rapPerlinY);
tpNode._influance = col & 0xFF;
tpNode._strength = ((this._segment - i) / this._segment)*this._pourcStrength;
if (i == 0) {
tpNode._direction = this.influanceDirection(this._direction,tpNode._influance,tpNode._strength);
}else {
tpNode._direction = this.influanceDirection(this.nodes[i-1]._direction,tpNode._influance,tpNode._strength);
}
var colG:uint = col >> 8 & 0xFF;
var seuil:int = this._maxSeuilBranch - ((this._maxSeuilBranch - this._minSeuilBranch) / this._segment) * i;
if (i>0 && colG > seuil && this._depth < TreeGenerator._maxDepth) {
tpNode.addBranche(this,col >> 16 & 0xFF,(this._baseWidth/this._segment)*(this._segment-i));
}
this.nodes.push(tpNode);
}
}
public function refreshNodes():void {
for (var i:int = 0; i < this.nodes.length; i++) {
var tpNode:node = this.nodes[i];
if (i == 0) {
tpNode._position = this._position;
}else {
tpNode._position = this.polarPosition(this.nodes[i-1]._position,this.nodes[i-1]._direction,this.nodes[i-1]._norme);
}
var col:uint = TreeGenerator.perlin.getPixel32(tpNode._position.x*TreeGenerator._rapPerlinX, tpNode._position.y*TreeGenerator._rapPerlinY);
tpNode._influance = col & 0xFF;
if (i == 0) {
tpNode._direction = this.influanceDirection(this._direction,tpNode._influance,tpNode._strength);
}else {
tpNode._direction = this.influanceDirection(this.nodes[i-1]._direction,tpNode._influance,tpNode._strength);
}
tpNode.refreshBranche();
}
}
private function calcGold():void {
var bLength:Number = this._length / this._segment;
var lg:Number = this._length;
for (var i:int = 0; i < this._segment; i++) {
var val:Number = lg / this._GOLD;
lg = lg - val;
this._valGold.push(val);
}
}
private function influanceDirection(dir:Number, inf:int, str:Number ):Number {
var pourc:Number = (inf - 128) / 128;
return dir + ((this._maxAngle * pourc)*(1-str));
}
private function polarPosition(pos:Point, angle:Number, norme:Number):Point {
var pt:Point = new Point();
pt.x = pos.x - (Math.sin(angle) * norme);
pt.y = pos.y - (Math.cos(angle) * norme);
return pt;
}
public function drawStructure():void {
this.graphics.clear();
for (var i:int = 0; i < this.nodes.length;i++ ) {
this.graphics.lineStyle((this._baseWidth/this._segment)*(this._segment-i), 0x000000, 1,true,"normal",CapsStyle.ROUND);
this.graphics.moveTo(this.nodes[i]._position.x, this.nodes[i]._position.y);
var tpPt:Point = polarPosition(this.nodes[i]._position, this.nodes[i]._direction, this.nodes[i]._norme);
this.graphics.lineTo(tpPt.x, tpPt.y);
}
for (i = 0; i < this._childrens.length; i++) {
this._childrens[i].drawStructure();
}
}
}