// Tree growth sim class Pt { float x, y, z; Pt(float nx, float ny) { x = nx; y = ny; } } class Branch { float squigBias; float lengthBias; float direction; float fade; Pt points[]; Branch branches[]; Branch(Branch parent, int limit) { createBranch(parent); if (limit < 8) createSubBranches(limit); } void createBranch(Branch parent) { points = new Pt[3]; float dirChange; // Create new branch if (parent != null) { squigBias = random(parent.squigBias * .75, parent.squigBias * 1.1); lengthBias = random(parent.lengthBias * .45, parent.lengthBias*.90); dirChange = random(-squigBias, squigBias); direction = parent.direction + dirChange; points[0] = parent.points[points.length-1]; fade = random(parent.fade*.6, parent.fade); } else { squigBias = 55; lengthBias = 160; direction = -90.0f; dirChange = 0; points[0] = new Pt(width/2, height); fade = 1.0f; } float tX = (lengthBias * cos(radians(direction))) + points[0].x; float tY = (lengthBias * sin(radians(direction))) + points[0].y; // end points[points.length-1] = new Pt(tX, tY); // mid 1 float dX = (points[0].x + points[points.length-1].x) / 2; float dY = (points[0].y + points[points.length-1].y) / 2; points[1] = new Pt(dX + random(lengthBias * .2) - lengthBias * .1, dY + random(lengthBias * .2) - lengthBias * .1); // mid 2 //points[2] = new Pt(points[0].x + dX*.6, points[0].y + dY*.6 + random(5)); //b print ("Creating new branch: " + lengthBias + " " + direction + " " + dirChange + " tx: " + tX + "ty: " + tY + "\n"); } void createSubBranches(int limit) { branches = new Branch[4]; for (int i=0; i < branches.length; i++) { branches[i] = new Branch(this, limit+1); } } void drawBranch(float magnitude) { push(); translate(points[0].x, points[0].y); //rotateZ(magnitude); stroke(255 - 255*fade); /* for (int i=0; i < points.length-1; i++) { float scale = float(i)/points.length-2; stroke(255 * scale, 255 * scale, 255 * scale); line(points[i].x, points[i].y, points[i+1].x, points[i+1].y); }*/ beginShape(LINE_STRIP); //bezierVertex(points[0].x, points[0].y); bezierVertex(0, 0); bezierVertex(points[1].x- points[0].x, points[1].y- points[0].y); bezierVertex(points[2].x- points[0].x, points[2].y- points[0].y); bezierVertex(points[2].x- points[0].x, points[2].y- points[0].y); //curveVertex(0, 0); endShape(); //line(0, 0, points[points.length-1].x - points[0].x, points[points.length-1].y - points[0].y); pop(); if (branches != null) { for (int i=0; i < branches.length; i++) { branches[i].drawBranch(magnitude*.5); } } else { //print("No sub: " + points[0].x + " " + points[0].y + " " + points[2].x + " " + points[2].y); } } } Branch root; float sway = 0.0f; BFont metaBold; void setup() { ellipseMode(CENTER_DIAMETER); push(); size (1000, 1000); root = new Branch(null, 0); } void loop() { Branch current = root; background(255); sway += PI/360; push(); current.drawBranch(cos(sway)); pop(); delay(1); } void mousePressed() { root = new Branch(null, 0); }