Stop Recursion When Out of Boundary

Hi all,

I created a simple recursive tree using a proto-L-System and I'd like for the recursion to stop if it goes out of the box I've drawn. However, because of all the translations, I'm confused as to how this can be achieved.

I'd be very grateful if someone can point me in the right direction.

Many Thanks, Charles

// A simple recursive tree using a proto-L-System

import processing.opengl.*;
Branch axiom;
PVector cameraPos = new PVector(600, -100, 600);

void setup()
{
  size(800, 800, OPENGL);
  axiom = new Branch();
}
void draw()
{

  background(0);
  stroke(192);
  fill(255);
  translate(width/2, height);
  rotateY(frameCount*0.01);
  axiom.draw();
  if (frameCount % 50 == 0) {
    axiom.replace(0);
  }
  translate(0, height*-0.5);
  noFill();
  box(400, 600, 400);

  camera(cameraPos.x, cameraPos.y, cameraPos.z, width/2, height*0.5, 0, 0, 1, 0);
}
void mousePressed()
{
  axiom = new Branch();
}

class Branch
{
  PMatrix3D joint;
  Branch child_a;
  Branch child_b;
  Branch()
  {
    joint = new PMatrix3D();
    child_a = null;
    child_b = null;
  }
  void replace(int depth)
  {
    // still need to prevent infinite recursion:
    if (depth > 16) {
      return;
    }
    // note: grow children before yourself
    if (child_a != null) {
      child_a.replace(depth+1);
    }
    if (child_b != null) {
      child_b.replace(depth+1);
    }
    // now I grow myself
    rule();
  }
  void rule()
  {
    // rule: grow offshoot branches
    // B -> B (+B) (-B)
    if (child_a == null) {
      // main stem -- almost straight
      child_a = new Branch();
      child_a.joint.rotateY(random(0, PI));
      child_a.joint.rotateX(random(-PI/16, PI/16));
    }
    if (child_b == null) {
      // branching off
      child_b = new Branch();
      child_b.joint.rotateY(random(0, PI));
      child_b.joint.rotateX(random(-PI/4, PI/4));
    }
  }
  void draw()
  {
    applyMatrix(joint);
    pushMatrix();
    {
      translate(0, -height/8, 0);
      box(10, height/4, 10);
    }
    popMatrix();
    pushMatrix();
    {
      translate(0, -height/4, 0);
      scale(0.7);
      if (child_a != null) {
        child_a.draw();
      }
    }
    popMatrix();
    pushMatrix();
    {
      translate(0, -height/4, 0);
      scale(0.7);
      if (child_b != null) {
        child_b.draw();
      }
    }
    popMatrix();
  }
}

Answers

  • Have a look at the functions modelX(), modelY() and modelZ().

    They return the coordinates for a point after applying transformations.

  • Thanks for your suggestion, it seems the function is what I'm after unfortunately I can't get it to work.

  • edited January 2016

    When I save the X, Y, Z coordinates just after having drawn the branches and use them in void draw to create a sphere they appear in a different position. :s

    Could anyone point out why this is happening?

    // A simple recursive tree using a proto-L-System
    
    import processing.opengl.*;
    Branch axiom;
    PVector cameraPos = new PVector(600, -100, 600);
    
    float x;
    float y;
    float z;
    float originX;
    float originY;
    float originZ;
    int boxSXZ = 400;
    int boxSY = 600;
    
    
    void setup()
    {
      size(700, 700, P3D);
      axiom = new Branch();
      sphereDetail(4);
    }
    void draw()
    {
    
      background(0);
      stroke(192);
      fill(255);
      translate(width/2, height);
      rotateY(frameCount*0.01);
    
    
      axiom.draw();
      if (frameCount % 50 == 0) {
        axiom.replace(0);
      }
      translate(0, height*-0.43);
      noFill();
      stroke(255);
      box(boxSXZ, boxSY, boxSXZ);
    
      translate(0, height*0.43);
      fill(255, 0, 0);
      sphere(10);
      originX = modelX(0, 0, 0);
      originY = modelY(0, 0, 0);
      originZ = modelZ(0, 0, 0);
    
    
    // draw a sphere based on the coordinates of each branch
    // as recorded in class Branch
    
      translate(x,y,z);
      sphere(10);
    
      //println(x + " " +  y + " " + z);
      println(originX + " " +  originY + " " + originZ);
    
      camera(cameraPos.x, mouseY, cameraPos.z, width/2, height*0.5, 0, 0, 1, 0);
    }
    void mousePressed()
    {
      axiom = new Branch();
    }
    
    
    class Branch
    {
      PMatrix3D joint;
      Branch child_a;
      Branch child_b;
      Branch()
      {
        joint = new PMatrix3D();
        child_a = null;
        child_b = null;
      }
      void replace(int depth)
      {
        // still need to prevent infinite recursion:
        if (depth > 8) {
          return;
        }
        // note: grow children before yourself
        if (child_a != null) {
          child_a.replace(depth+1);
        }
        if (child_b != null) {
          child_b.replace(depth+1);
        }
        // now I grow myself
        rule();
      }
      void rule()
      {
        // rule: grow offshoot branches
        // B -> B (+B) (-B)
        if (child_a == null) {
          // main stem -- almost straight
          child_a = new Branch();
          child_a.joint.rotateY(random(0, PI));
          child_a.joint.rotateX(random(-PI/16, PI/16));
        }
        if (child_b == null) {
          // branching off
          child_b = new Branch();
          child_b.joint.rotateY(random(0, PI));
          child_b.joint.rotateX(random(-PI/4, PI/4));
    
        }
      }
      void draw()
      {
        applyMatrix(joint);
        pushMatrix();
        {
          translate(0, -height/8, 0);
          box(10, height/4, 10);
    
          // record the location of the branches as they are drawn
          x = modelX(0, 0, 0);
          y = modelY(0, 0, 0);
          z = modelZ(0, 0, 0);
    
          //sphere(10);
        }
        popMatrix();
        pushMatrix();
        {
          translate(0, -height/4, 0);
          scale(0.7);
          if (child_a != null) {
            child_a.draw();
          }
        }
        popMatrix();
        pushMatrix();
        {
          translate(0, -height/4, 0);
          scale(0.7);
          if (child_b != null) {
            child_b.draw();
          }
        }
        popMatrix();
      }
    }
    
  • you're saving transformed coordinates (lines 45-47) and then drawing them after applying the transformations again (lines 29, 30, 37, 42)

Sign In or Register to comment.