We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Recursively generating trees using linkedlists
Page Index Toggle Pages: 1
Recursively generating trees using linkedlists (Read 1361 times)
Recursively generating trees using linkedlists
May 9th, 2005, 7:49am
 
Just wondering if anyone else out there has encountered a similar problem to this and had any light to shed on it:

In trying to write a program that creates a simple random tree using LinkedLists of Branch objects. That is, each branch has a list of branchs which stem from it and each of those has its own list of branches and so on.

The only problem is that when I try to 'grow' the tree, the function which populates the list is recursive and goes off in one direction only creating branches on just one of the objects in the list.

I understand this isnt the best explaination so here is the code:

Branch root;

int num_of_branches, tree_size;

void setup()
{
 size(500,500);
 background(0);
 stroke(255);
 strokeWeight(1);
 
 translate(250,450);
 tree_size = 0;
 
 num_of_branches = 10;
 
 root = new Branch(0,0,0,-60);
 
}


class Branch
{
 int s_x, s_y, e_x, e_y; //start and end point coordinates
 
 LinkedList branches;
 
 Branch(int start_x, int start_y, int end_x, int end_y)
 {
   branches = new LinkedList();
   
   //create end points based on start point
   this.s_x = start_x;
   this.s_y = start_y;
   
   this.e_x = end_x;
   this.e_y = end_y;
   
   this._draw();
   this.grow();
 }
 
 Branch(int start_x, int start_y)
 {
   branches = new LinkedList();
   
   //create end points based on start point
   this.s_x = start_x;
   this.s_y = start_y;
   
   this.e_x = s_x - int(random(-50, 50));
   this.e_y = s_y - int(random(50));
   
   this._draw();
 
 }
 
 void grow()
 {
   tree_size++;
   
   int num = int(random(num_of_branches));
   println(num);
   
   //create branches
   for(int i=0;i<num;i++)
   {
     branches.add(new Branch(this.e_x, this.e_y));
   }
   
   //for each branch in list, grow until some tree size is reached
   int s = branches.size();
   for(int i=0;i<s;i++)
   {
     Branch temp = (Branch) branches.get(i);
     if(tree_size<20)
     {
       temp.grow();
     }
   }
 }
 
 void _draw()
 {
   
   line(this.s_x, this.s_y, this.e_x, this.e_y);
 }
}


If anyone else out there has had a go with anything similar to this, id be really interested to know what would be a good angle to go about populating all the branches in one recursive function to create a more realistic tree.

cheers for your time anyway,
paul.
Re: Recursively generating trees using linkedlists
Reply #1 - May 9th, 2005, 10:58am
 
The problem is simply the recursive nature of your code, in your case it's caused because the child branches that you create have no idea in which level of the tree they are.

What happen in your case is that the first branch starts a loop to grow new sub-branches. But as in the constructor of your branch class there is already a grow() call the first subbranch already grows another branch whose first subbranch also grows another ... and so on. You tried to solve this with tree_size but that will not work because it gets increased in every branch so after 20 branches it's already 20, whereas you really want 20 levels.


What is missing is a counter that you pass on in the constructor which gets decreased each time you generate a new subbranch. If the counter is 0 the branch will not generate a new subbranch and return.

Branch(int level, int start_x, int start_y, int end_x, int end_y)
 {
   branches = new LinkedList();
   
   //create end points based on start point
   this.s_x = start_x;
   this.s_y = start_y;
   
   this.e_x = end_x;
   this.e_y = end_y;
   
   this._draw();
   this.grow(level);
 }

[...]

void grow(int level)
 {

if (level<0) return;

      int num = int(random(num_of_branches));
   println(num);
   
   //create branches
   for(int i=0;i<num;i++)
   {
branches.add(new Branch(this.e_x, this.e_y));
   }
   
   //for each branch in list, grow until some tree size is reached
   int s = branches.size();
   for(int i=0;i<s;i++)
   {
Branch temp = (Branch) branches.get(i);
temp.grow(level-1);  
    }
 }

Re: Recursively generating trees using linkedlists
Reply #2 - May 9th, 2005, 11:16am
 
I would try to keep track of the level of each branch instead of the total tree size (if not the tree will only grow one branch at a time until it reaches the max tree size).

Another solution would be to not do it recursive, but that's a bit more work.

Here's the modified code:
Code:

Branch root;

int num_of_branches, num_of_levels;

void setup()
{
size(500,500);
background(0);
stroke(255);
strokeWeight(1);

translate(250,450);

num_of_branches = 6;
num_of_levels = 6;

root = new Branch(0,0,0,-60,0);

}


class Branch
{
int s_x, s_y, e_x, e_y; //start and end point coordinates

LinkedList branches;

int level;

Branch(int start_x, int start_y, int end_x, int end_y, int lvl)
{
branches = new LinkedList();

//create end points based on start point
this.s_x = start_x;
this.s_y = start_y;

this.e_x = end_x;
this.e_y = end_y;

this.level = lvl;

this._draw();
this.grow();
}

Branch(int start_x, int start_y, int lvl)
{
branches = new LinkedList();

//create end points based on start point
this.s_x = start_x;
this.s_y = start_y;

this.e_x = s_x - int(random(-50, 50));
this.e_y = s_y - int(random(50));

this.level = lvl;

this._draw();

}

void grow()
{

int num = int(random(num_of_branches));
num=constrain(num, 1, num_of_branches);
println(num);

//create branches
for(int i=0;i<num;i++)
{
this.branches.add(new Branch(this.e_x, this.e_y, this.level+1));
}

//for each branch in list, grow until some tree size is reached
int s = this.branches.size();
for(int i=0;i<s;i++)
{
Branch temp = (Branch) this.branches.get(i);
if(temp.level<num_of_levels)
{
temp.grow();
}
}
}

void _draw()
{

line(this.s_x, this.s_y, this.e_x, this.e_y);
}
}
Re: Recursively generating trees using linkedlists
Reply #3 - May 9th, 2005, 11:18am
 
Oh well, Quasimodo was faster and much more elegant.

I think a tree class would be something nice for a library.  I will give it a thought and it's possible API.
Re: Recursively generating trees using linkedlists
Reply #4 - May 10th, 2005, 5:05am
 
Quasimodo and Ricard.. thanks so much for your help. Thats exactly what I needed to do.

Paul.
Re: Recursively generating trees using linkedlists
Reply #5 - May 10th, 2005, 3:40pm
 
Hey all,

There's an example here that uses an ArrayList to hold onto recursively generated branches (it could use some improvement, but may help you with what you're doing. . )

http://stage.itp.nyu.edu/nature/week07/

Best,
Dan
Page Index Toggle Pages: 1