class Point{
float z,dx,dy,width,depth;
InterpolatedVar length;
Vector children = new Vector();
color leafColor;
PApplet parent;
public Point(PApplet parent, float dx, float dy, float width, float length, float depth){
this.dx = dx;
this.dy = dy;
this.width = width;
this.length = new SOLagInterpolatedVar(parent,0,random(5,12),random(4,10));
this.length.setVal(length);
this.depth = depth;
this.parent = parent;
if (Math.random() > .1){
leafColor = color(0,(float)(.4f+.3*Math.random()),0,.25f);
}
else leafColor = color((float)(.6f+.4*Math.random()),(float)(.6f+.3*Math.random()),0,.25f);
}
 
public void render(float x, float y){
float angle;
if (Math.random() > .95 && depth > 2){
angle = random(-.01*depth,.01*depth);
float tx;
tx = (float)(Math.cos(angle)*dx + Math.sin(angle)*dy);
dy = (float)(-Math.sin(angle)*dx + Math.cos(angle)*dy);
dx = tx;
}
stroke(.2,.3,0);
strokeWeight(width);
line((int)x,(int)y,(int)(x+dx*length.getVal()),(int)(y+dy*length.getVal()));
//if (children.size() == 0){
if (depth > 3 ){
noStroke();
fill(leafColor);
ellipse((int)((x+dx*length.getVal())-length.getVal()/2),(int)((y+dy*length.getVal())-length.getVal()/2),(int)length.getVal(),(int)length.getVal());
 
}
Point p;
for (int i =0; i < children.size(); i++){
p = (Point)children.elementAt(i);
p.render(x+dx*length.getVal(), y + dy*length.getVal());
}
}
public void branch(){
float bx,by, angle,mlength;
if (children.size()==0){
for (int i =0; i < (int)(2 + (numBranches.getVal()-2)*Math.random()); i++){
 
angle = random(-branchAngle.getVal(),branchAngle.getVal());
 
float tx;
tx = (float)(Math.cos(angle)*dx + Math.sin(angle)*dy);
by = (float)(-Math.sin(angle)*dx + Math.cos(angle)*dy);
bx = tx;
children.add(new Point(parent,bx,by, width*.65f,(float)(length.getTargetVal() * (.4f + stretch.getVal()*Math.random())),depth + 1));
}
}
else {
Point p;
for (int i =0; i < children.size(); i++){
p = (Point)children.elementAt(i);
p.branch();
}
}
}
}
//created=08 Sep 07
//updated=30 Sep 07
//description=Branching tree generator.
//title=Tree
//publish=true
 
import SGGUI.*;
import InterpolatedVar.*;
 
 
SGGUI controller;
VerticalLayout layout;
SGSlider numBranches, branchAngle, stretch;
SGButton newTree;
 
PFont fnt;
 
Point trunk;
float swide = 1;
 
void setup(){
size(550,450);
 
frameRate(45);
trunk = new Point(this, 0,-1,20,75,2);
 
fnt = loadFont("writing.vlw");
textFont(fnt);
textMode(SCREEN);
controller = new SGGUI(this,fnt);
numBranches = new SGSlider("Num Branches",4,1,2,10);
branchAngle = new SGSlider("Branch Angle",1,.1,0,2);
stretch = new SGSlider("Stretch",.6,.05,.3,1);
newTree = new SGButton("New Tree" );
newTree.addGUIListener(this);
 
controller.GUI_HIGHLIGHT = color(0,100,0,100);
layout = new VerticalLayout(controller,10,10,150);
layout.title = "";
layout.add(numBranches);
layout.add(branchAngle);
layout.add(stretch);
layout.add(newTree);
controller.add(layout);
colorMode(RGB,1.0);
ellipseMode(CORNER);
smooth();
 
fullTree();
}
 
void draw(){
noStroke();
background(255,255,255);
fill(0,0,0,.1);
ellipseMode(CENTER);
ellipse(width/2,420+5,swide*100,swide*30);
ellipse(width/2,420+5,swide*80,swide*20);
ellipseMode(CORNER);
trunk.render(width/2,420);
}
 
 
void mouseClicked(){
if (controller.getMouseConsumed() == 0){
trunk.branch();
swide*=1.1;
println("boo");
}
}
 
void keyPressed(){
if (key == ' ' ){
trunk = new Point(this, 0,-1,20,75,2);
swide= 1;
}
else if (key == 't'){
fullTree();
}
}
 
void fullTree(){
trunk = new Point(this, 0,-1,20,75,2);
trunk.branch();
trunk.branch();
trunk.branch();
trunk.branch();
swide= 1;
}
 
void GUIEventPerformed(GUIEvent e){
 
fullTree();
 
}