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 (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();
}
}
}
}