class GrowTree{ float x,y; int direction, growthStep; LSystem lsystem; ParticleSystem treePhysics; Particle [] particle; Node [] node; boolean sucking = false; int drawStackSize = 0; float nodeVelocity = 50; GrowTree(float x, float y, int direction, String axiom, String [] ruleset, int iterations){ this.x = x; this.y = y; this.direction = direction; //treePhysics = new ParticleSystem(0.0, 0.05); //////////////// treePhysics = new ParticleSystem(0.0, 0.3); //treePhysics = new ParticleSystem(0.08, -0.01); //treePhysics = new ParticleSystem(0.08, 0.2); lsystem = new LSystem(axiom, ruleset); lsystem.iterate(iterations); makeTree(); } void draw(){ for(int i = 0; i < drawStackSize; i++){ color c = color(10*(sq(sqrt( (map(particle[i].position().x(), // value to map height/4, height/2, // lower + upper bound of the value's current range 0, svgs.length-1))))), // lower + upper bound of the value's target range map(particle[i].position().y(),0,height,0,100), random(100,150)); if(node[i].active){ if(node[i].parent != -1){ float Handle1_x = particle[node[i].parent].position().x(); float Handle1_y = particle[i].position().y(); float Handle2_x = particle[i].position().x(); float Handle2_y = particle[node[i].parent].position().y()+3; noFill(); stroke(s);//,200); strokeWeight(sq(node[i].size)/2); //strokeWeight(8); bezier(particle[i].position().x(), particle[i].position().y(), Handle1_x, Handle1_y, Handle2_x, Handle2_y, particle[node[i].parent].position().x(), particle[node[i].parent].position().y()); } if(node[i].timer > -2){ node[i].timer--; } if(node[i].timer == 0){ growBurst(i); } } if((particle[i].position().x() > width/2 + random(0,600)) || (particle[i].position().x() < width/2 - random(0,600)) && (particle[i].position().y() < 50000) //|| ){ if(random(0,10) > 4){ pushMatrix(); noStroke(); translate(particle[i].position().x(), particle[i].position().y()); scale(2*cos((sq(particle[i].position().x())))); scale(2*cos((sq(particle[i].position().y())))); rotate(node[i].size*2); rotate(random(0,3)); drawSVG(int(sq(sqrt( // svg_id (map(particle[i].position().y(), // value to map 0, height, // lower + upper bound of the value's current range 0, svgs.length-1)) // lower + upper bound of the value's target range %svgs.length))), // modulo svg array 0, // path_x 0, // path_y 0.2, 0, // path_rotate c); popMatrix(); } } } treePhysics.tick(); } //fires out more nodes from nodes that are "pregnant" (have children) void growBurst(int i){ if(node[i].child != null){ for(int j = 0; j < node[i].child.length; j++){ particle[node[i].child[j]].moveTo(particle[i].position().x(), particle[i].position().y(), 0.0); float xVel = cos(node[node[i].child[j]].angle) * nodeVelocity; float yVel = sin(node[node[i].child[j]].angle) * nodeVelocity; particle[node[i].child[j]].setVelocity(xVel, yVel, 0.0); node[node[i].child[j]].active = true; } } } //generates Nodes and Particles to grow the tree from LSystem class void makeTree(){ float angle = PI + HALF_PI; Vector drawStack = new Vector(0); Vector pushPop = new Vector(0); int pushPopDepth = 0; int parent = 0; drawStack.add(new Node(angle, 0.01, 60, -1)); //////////////////////////////////////////////////////// drawStackSize++; for(int i = 0; i < lsystem.tree.length(); i++){ float angleStep = random(-3,3); switch(lsystem.tree.charAt(i)){ case 'F': drawStack.add(new Node(angle, 0.5 + random(pushPopDepth*0.2), 5 - constrain(pushPopDepth, 0, 4), parent)); drawStackSize++; parent = drawStackSize-1; break; case '+': angle += angleStep; break; case '-': angle -= angleStep; break; case '[': pushPop.add(new Node(angle, 0.5 + random(pushPopDepth*0.2), 5 - constrain(pushPopDepth, 0, 4), parent)); pushPopDepth++; break; case ']': Node temp = (Node)pushPop.remove(pushPopDepth-1); pushPopDepth--; angle = temp.angle; parent = temp.parent; break; } } particle = new Particle[drawStackSize]; node = new Node[drawStackSize]; node[0] = (Node)drawStack.get(0); node[0].active = true; particle[0] = treePhysics.makeParticle(1.0, x, y, 0.0); //particle[0].makeFixed(); for(int i = 1; i < drawStackSize; i++){ node[i] = (Node)drawStack.get(i); if(node[node[i].parent].child != null){ node[node[i].parent].child = append(node[node[i].parent].child, i); } else{ node[node[i].parent].child = new int[1]; node[node[i].parent].child[0] = i; } particle[i] = treePhysics.makeParticle(node[i].weight, x, y, 0.0); } } } //information about how to draw the tree dynamically is stored in the Node object static class Node{ float angle, weight; int parent, timer, size; int [] child; boolean active; Node(float angle, float weight, int size, int parent){ this.angle = angle; this.parent = parent; this.weight = weight; this.size = size; timer = 5; active = false; } }