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 & HelpSyntax Questions › Connecting random circles to a ring
Page Index Toggle Pages: 1
Connecting random circles to a ring (Read 877 times)
Connecting random circles to a ring
Jul 21st, 2009, 12:33pm
 
Hey forum,

I am getting mad about my skript and I need some hints about what I am doing wrong.
Here is what my sketch should do:
1. I have 10 random points on stage and I like to connect them to 10 points on a circle.
2. Every random point should look up the shortest distance to a point on the circle.
3. Every point on the circle should be connected only to one random point. So before a line is drawn, the random point has to check if the point on the circle is occupied. If so, the random point looks uo the next longer connection and so on.

This is my script.
Part 1 and 2 are ok, but I getting mad about point 3.
Please can anyone give me some support on this?

Thank you!


Code:
float ar_x[] ={                                    
};
float ar_y[] ={                                  
};
float ring_x[] ={                                    
};
float ring_y[] ={                                  
};
float distances[] ={                                    
};
int amount=10;
float[][][]waytopoint = new float[amount][amount][2];


void setup(){
 size(500, 500);
 smooth();
 noLoop();
}

void draw(){
 translate(width/2, height/2);
 f_randompoints();
 f_ringpoints();
 f_distances();
 f_sort();
 f_drawcircles();
 f_drawlines();
}

void f_randompoints(){
 for(int i=0;i<amount;i++){
   ar_x=append(ar_x, random(-50,50));
   ar_y=append(ar_y, random(-50,50));  
 }
}
void f_ringpoints(){
 for(int i=0;i<amount;i++){
   float degree = radians((360.0/amount)*i);  
   ring_x= append(ring_x,cos(degree));
   ring_y= append(ring_y,sin(degree));
 }
}
void f_distances(){
 for(int i=0;i<amount;i++){
   for(int j=0;j<amount;j++){
     waytopoint[i][j][0]=dist(ar_x[i],ar_y[i],ring_x[j]*200,ring_y[j]*200);
     waytopoint[i][j][1]=j;
   }
 }
}

void f_sort(){
 for(int i=0;i<amount;i++){
   for(int j=0;j<amount;j++){
     waytopoint[i][j] = sort((waytopoint[i][j]));
   }        
 }
}

void f_drawcircles(){
 noStroke();
 ellipseMode(CENTER);
 for(int i=0;i<amount;i++){
   fill(0);
   ellipse(ar_x[i],ar_y[i],5,5);
   fill(255,0,0);  
   ellipse(ring_x[i]*200,ring_y[i]*200,7,7);
 }
}

void f_drawlines(){
 stroke(0);
 noFill();
 float temp=1000.0;
 float temp2=0.0;
 for(int i=0;i<amount-1;i++){
   for(int j=0;j<amount-1;j++){
     if(temp<int(waytopoint[i][j][1])){
       temp=int(waytopoint[i][j][1]);
       temp2=int(waytopoint[i][j][0]);
     }
     else{
       line(ar_x[int(waytopoint[i][int(temp2)][0])]  ,  ar_y[int(waytopoint[i][int(temp2)][0])]  ,  ring_x[int(waytopoint[i][int(temp2)][0])]*200  ,  ring_y[int(waytopoint[i][int(temp2)][0])]*200);  
     }
   }
 }
}
Re: Connecting random circles to a ring
Reply #1 - Jul 21st, 2009, 8:37pm
 
I notice you never actually use your distances[] array. When you call your f_distances() function, just measure the distance of the current outer ring point from each of the center random points, and store the value in your distances array. Then just throw in a for() loop to find the smallest distance recorded of all those points, and have the line draw from your outer point, to the point that yielded the closest recorded distance.
Re: Connecting random circles to a ring
Reply #2 - Jul 22nd, 2009, 2:07pm
 
Hi NoChinDeluxe,
Thanks for your suggestions! I think you showed me the right way, but I was not able to bring this to life.

What I've tried is this:
I cut out the sort function and modified the f_drawlines() function.
Code:
void f_drawlines(){
 stroke(0);
 noFill();
 int temp2=0;
 for(int i=0;i<amount;i++){
   float temp=waytopoint[i][0][0];
   for(int j=0;j<amount;j++){
     if(temp>int(waytopoint[i][j][0])){
       temp=int(waytopoint[i][j][0]);
       temp2=int(waytopoint[i][j][1]);
     }
      line(ar_x[int(waytopoint[i][int(temp2)][1])]  ,  ar_y[int(waytopoint[i][int(temp2)][1])]  ,  ring_x[int(waytopoint[i][int(temp2)][1])]*200  ,  ring_y[int(waytopoint[i][int(temp2)][1])]*200);        
   }
 }
}


Now there are all points connected to the points to the ring - but not in the shortest way  Embarrassed.
Re: Connecting random circles to a ring
Reply #3 - Jul 23rd, 2009, 7:48am
 
OK I had a go at writing up what you need, but honestly, working with all these multidimensional arrays is killing me. It's really confusing and is not the most efficient way to do this. You really just need a class that stores a circle point's location, as well as the coordinates of the closest random point. Then just let it draw it's own line to those coordinates. Doing this will clean up your code a ton and it'll be way easier to keep track of everything. Let me come up with something and I'll get back to you.
Re: Connecting random circles to a ring
Reply #4 - Jul 23rd, 2009, 11:32am
 
OK, here's the solution I came up with. I built two classes. The first is the RandomPoint class. This class not only creates the random points and draws them in the center, but it also utilizes the findTarget() function, which calculates which point on the circle is the closest to its location.

The second class is called the CirclePoint class. The only thing this class does is calculate the locations of each point on the circle. It then draws each point at that location.

I find this code to be much more readable than using a bunch of multidimensional arrays. For one, we can now just use one for() loop to access the class members. Before we had to use two or three just to access all the dimensions of the array. We can now also name our members things like "x" and "y" and we can attach them to specific points. So each CirclePoint has its own x and y, instead of having to store them all in one 3D array.

There is one problem you are going to run into. Which CirclePoints the RandomPoints connect to all depends on which RandomPoint you start with when calculating distances. As you iterate through the RandomPoints, they will start eliminating available CirclePoints, which means that one of the last RandomPoints may have to connect to a CirclePoint across the screen, simply because it was last and didn't get a chance to even have a shot at getting assigned a closer CirclePoint. I'm not sure if that will be a problem for your particular project. Anyway, here is the code. Let me know if you have any questions. I didn't really comment anything, so feel free to question anything that's in there.

Code:

ArrayList circle_points;
ArrayList random_points;
int AMOUNT = 10;

void setup(){
 size(500, 500);
 smooth();
 ellipseMode(CENTER);
 noLoop();
 
 //initialize our CirclePoints
 circle_points = new ArrayList(AMOUNT);
 for(int i=0; i<AMOUNT; i++){
   float degree = radians((360/AMOUNT)*i);
   circle_points.add(new CirclePoint(degree));
 }
 
 //initialize our RandomPoints
 random_points = new ArrayList(AMOUNT);
 for(int i=0; i<AMOUNT; i++){
   random_points.add(new RandomPoint());
 }
}

void draw(){
 background(255);
 translate(width/2, height/2);
 for(int i=0; i<AMOUNT; i++){

   //Access a RandomPoint and find the closest CirclePoint
   RandomPoint rp = (RandomPoint)random_points.get(i);
   rp.findTarget(circle_points);
   rp.drawPoint();
 
   //simply draw the CirclePoints
   CirclePoint cp = (CirclePoint)circle_points.get(i);
   cp.drawCircle();
 }
}


/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////


class CirclePoint{
 float x, y;
 float target_x, target_y;
 float degree;
 boolean is_not_occupied;
 
 CirclePoint(float _degree){
   degree = _degree;
   x = cos(degree)*200;
   y = sin(degree)*200;
   target_x = 0;
   target_y = 0;
   is_not_occupied = true; //is this point available?
 }
 
 void drawCircle(){
   noStroke();
   fill(255,0,0);
   ellipse(x, y, 7, 7);
 }
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

class RandomPoint{
 float x, y;
 float target_x, target_y;

 RandomPoint(){
   x = random(-50, 50);
   y = random(-50, 50);
 }
 
 void drawPoint(){
   noStroke();
   fill(0);
   ellipse(x, y, 5, 5);
   stroke(0);
   line(x, y, target_x, target_y);
 }
 
 void findTarget(ArrayList _cps){
   ArrayList cps = _cps;
   float shortest_distance = 1000;
   int index_of_shortest = 0;
   for(int i=0; i<cps.size(); i++){
     CirclePoint cp = (CirclePoint)cps.get(i);
     if(cp.is_not_occupied){
       if(i == 0){
         shortest_distance = dist(x, y, cp.x, cp.y);
         index_of_shortest = i;
       }
       float current_distance = dist(x, y, cp.x, cp.y);
       if(current_distance < shortest_distance){
         shortest_distance = current_distance;
           index_of_shortest = i;
       }
     }
   }
   CirclePoint shortest_point = (CirclePoint)cps.get(index_of_shortest);
   target_x = shortest_point.x;
   target_y = shortest_point.y;
   shortest_point.is_not_occupied = false;
 }
}
Re: Connecting random circles to a ring
Reply #5 - Jul 24th, 2009, 8:35am
 
Hey NoChinDeluxe,

It works perfect to me!!
I never used classes before, so I will have a deeper look to some lines  of your fantastic code. This will also be a good lesson for me to understand the use of classes.


Man thank you so much!  Cheesy
Re: Connecting random circles to a ring
Reply #6 - Jul 25th, 2009, 1:44pm
 
No problem. Glad I could help. You'll find classes will make your life much easier. If you're unfamiliar with them, take a look at the excellent reference pages on object-oriented programming. The way you were doing it before was fine, but like I said, much easier using classes. It's kind of part of the journey of learning. It's kind of like how most people start out and realize quickly they need to start using arrays. Usually when code starts getting too complex for arrays (such as your original code), it's time to start talking classes.

Anyway. Start learning this stuff and feel free to ask questions about object-oriented programming in general or about the specifics of the code I posted. Good luck!
Page Index Toggle Pages: 1