Quantcast
Channel: Library Questions - Processing 2.x and 3.x Forum
Viewing all articles
Browse latest Browse all 2896

Create 3D Tree where child branches are smaller than parent

$
0
0

Hi. I've found some code for simulating the growth of a tree which I have altered a little. However, I could really do with some help.

The code draws a line and then when that line reaches a certain distance it divides and new lines are drawn. However, each new line is currently the same length as the one that came before. I would like to have each new line 2/3rds the size of the one that came before. I'm sure I'm missing something really obvious but I've been scratching my brain and can't seem to work it out.

Any help would be much appreciated! Thanks, Michael.

import toxi.geom.*;

import peasy.*;
import peasy.org.apache.commons.math.*;
import peasy.org.apache.commons.math.geometry.*;
PeasyCam cam; //use PeasyCam

Branch tree;

void setup() {


  cam = new PeasyCam (this, width/2);
  cam.setMinimumDistance(20);
  cam.setDistance(200);
  cam.setMaximumDistance(10000);
  size(1000, 700, P3D);

  stroke(255, 50);
  tree = new Branch(new Vec3D(0, -1, 0), 5);
  tree.start = new Vec3D(0, 0, 0);
}

void draw() {
  background(0);

  tree.update();
  tree.draw();


}
class Branch {
  float spltLength = 20;
  int numChildren = 4;
  float maxAngle = PI/1.5;
  float energy;

  Vec3D start;
  Vec3D end;
  Vec3D direction;
  Branch[] children;

  Branch( Vec3D direction, float energy) {
    this.direction = direction;
    this.energy = 5;

  }

  void update() {


    // grow
    float factor = 1 + energy/(5*sq(direction.magnitude()));
    direction = direction.scale(factor);
    end = start.add(direction);

    // if splitLength is reached, create children and update them
    if (direction.magnitude() >= spltLength) {
      energy = 0;

  // direction = direction.scale(0);
      // create child-branches if they don't exist

      if (children == null) {
        createChildren();
      }
      for (int i =0; i<children.length; i++) {
        children[i].start = end;
        children[i].update();
      }
    }
  }

  void createChildren() {
    children = new Branch[numChildren];
    for (int i = 0; i<numChildren; i++) {


      // this is not so elegant, there may be slick solution for it
      Vec3D axis = new Vec3D();
      boolean isPerpendicular = false;
      // find a perpendicular vector
      while (!isPerpendicular) {
        axis = Vec3D.randomVector() ;
        if (direction.dot(axis)!=0) {
          isPerpendicular = true;
        }
      }
      axis.cross(direction);
      //rotate vector
      Vec3D dir = direction.copy().rotateAroundAxis(axis, random(-maxAngle, maxAngle));
      dir.normalize();
      // calculate energy
      float en = map(abs(dir.angleBetween(direction, true)), 0, maxAngle, energy, 0);
      children[i] = new Branch(dir, en);
    }
  }

  void draw() {

       pushMatrix();
      translate(end.x, end.y, end.z);
      sphere(1);
       popMatrix();
    line(start.x, start.y, start.z, end.x, end.y, end.z);
    if (children == null) {
      point(end.x, end.y, end.z);
    }
    else {
      for (int i = 0; i<children.length; i++) {
        children[i].draw();
      }
    }
  }

}

Viewing all articles
Browse latest Browse all 2896

Trending Articles