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 › beginner: collision of multiple balls
Page Index Toggle Pages: 1
beginner: collision of multiple balls (Read 630 times)
beginner: collision of multiple balls
Sep 25th, 2008, 8:57pm
 
hi all

i'm attending a course of Processing, and i have an exercise that i'm having a big trouble with understanding array issues.

we have to develop a multiple collision detection system. the objective of the exercise is to make the balls invert their speed when colliding with the borders of the canvas, and also with another one of the balls.

i'm posting the code of what i did below. object collision is commented.

Quote:
//aula6 exemplo2
//eduardo fernandes. 25/09/08

int x[];//x position
int y[];//y position
int raio[];//radius
int vx[];//x speed
int vy[];//y speed

int n;//number of objects


void setup(){
  size(512,512);
  background(0);
  fill(255);
  smooth();
  noStroke();
  ellipseMode(CENTER);

  n=4;

  x=new int[n];
  y=new int[n];
  raio=new int[n];
  vx=new int[n];
  vy=new int[n];

  for(int i=0; i<n; i++){  
    x[i]=int(random(512));
    y[i]=int(random(512));
    raio[i]=int(random(10,30));
    vx[i]=int(random(2,6));
    vy[i]=int(random(2,6));

  }
}
void draw(){
  background(0);

  for(int i=0; i<n; i++){
    //distance between balls
    float d[]=new float[i];
    d[i]=sqrt(sq(x[i+1]-x[i])+sq(y[i+1]-y[i]));

    //actualizes ball speed
    x[i]=x[i]+vx[i];
    y[i]=y[i]+vy[i];

    //wall collision      
    if(x[i]<0 || x[i]>512){
      vx[i]=-vx[i];
      x[i]=x[i]+vx[i];
    }
    if (y[i]<0 || y[i]>512){
      vy[i]=-vy[i];
      y[i]=y[i]+vy[i];
    }

    //object collision
    /*if (d[i]>raio[i]){

    }
    else{
      vx[i]=-vx[i];
      vy[i]=-vy[i];
      x[i]=x[i]+vx[i];
      y[i]=y[i]+vy[i];  
    }*/
  }
  for(int i=0; i<n; i++){
    ellipse(x[i],y[i],raio[i]*2,raio[i]*2);
  }
}



sofar i had sucess in making the objects bounce on the walls, but i had trouble in making balls recognize other balls.

we have been teached that a good way to measure distance between points is using good old pythagorean theorem a=sqr(sq(a)+sq(b)), so i used

Quote:
    float d[]=new float[i];
    d[i]=sqrt(sq(x[i+1]-x[i])+sq(y[i+1]-y[i]));



i've tried a lot of different ways to measure the distance and i always get different responses, all but what i need to do.

i think the the error i'm making is that i'm not being able to differentiate one ball from the others, and estabilish that differentiation on the calculation of distances, for a different number of "particles". the usual error is to make the calculation equals zero, so it won't move. other issue is that i'm not interacting with array correctly.

can anybody assist me? i have seen a lot of examples of this over the web, but they are all OOP, and i haven't learned that already, so anything that goes in that direction won't be of use(in this phase of the course, at least).

thanks
Re: beginner: collision of multiple balls
Reply #1 - Sep 25th, 2008, 9:23pm
 
Hey,

There's a function built in to measure distance between two points

float d = dist(x1,y1,x2,y2);

And to figure out if two balls are touching:
if ball1's radius + ball2's radius >= the distance between centers, they are touching or overlapping

Since you don't want an OO solution (which would be much more elegant), then here's how you might aproach it:

-In your main loop, you go through each ball.
-For each ball, you have to compare it to every other ball, except itself
You will need another loop inside the main one to perform this check, and in that loop you have to perform the check that you're not comparing ball-1 to itself.

So with your main loop in mind:
Code:

for(int i=0; i<n; i++){
for (int c=0; c<n; c++){
if (n!=c){ //Do not compare ball to itself
float d = dist(blah,blah,blah,blah)
if (raio[n]+raio[c] >= d){
//Balls are touching. Do whatever

}
}
}



}

Re: beginner: collision of multiple balls
Reply #2 - Sep 25th, 2008, 11:49pm
 
in a way to try to make it more understandable, i made the code more modular, and split it rewrote the code to the following. and you know what? IT WORKS!!!!

gracias man.

Quote:
//aula6 exemplo2
//eduardo fernandes. 25/09/08

int x[];//x position
int y[];//y position
int raio[];//radius
int vx[];//x speed
int vy[];//y speed

int n;//number of objects


void setup(){
  size(512,512);
  background(0);
  fill(255);
  smooth();
  noStroke();
  ellipseMode(CENTER);
  frameRate(20);

  n=12;

  x=new int[n];
  y=new int[n];
  raio=new int[n];
  vx=new int[n];
  vy=new int[n];

  for(int i=0; i<n; i++){  
    x[i]=int(random(512));
    y[i]=int(random(512));
    raio[i]=int(random(10,30));
    vx[i]=int(random(-2,2));
    if(vx[i]==0){
      vx[i]=1;
    }
    vy[i]=int(random(-2,2));

    if(vy[i]==0){
      vy[i]=-1;
    }
  }
}

void draw(){
  background(0);

  for(int i=0; i<n; i++){

    //actualizes ball speed
    speed();
    //wall collision      
    colisao1();

    //particle collision
    colisao2();
  }
  display();
}

void colisao1(){
  for(int i=0;i<n;i++){
    if(x[i]<0 || x[i]>512){
      vx[i]=-vx[i];
      x[i]=x[i]+vx[i];
    }
    if (y[i]<0 || y[i]>512){
      vy[i]=-vy[i];
      y[i]=y[i]+vy[i];
    }
  }
}

void colisao2(){
  for(int i=0; i<n; i++){
    for(int c=0; c<n; c++){
      if (i!=c){
        float d=sqrt(sq(x[i]-x[c]))+(sq(y[i]-y[c]));
        if(raio[c]+raio[i] >= d){
          vx[i]=vx[i]*-1;
          x[i]=x[i]+vx[i];
          vy[i]=vy[i]*-1;
          y[i]=y[i]+vy[i];
          vx[c]=vx[c]*-1;
          x[c]=x[c]+vx[c];
          vy[c]=vy[c]*-1;
          y[c]=y[c]+vy[c];
        }
      }
    }
  }
}

void speed(){
  for(int i=0; i<n; i++){
    x[i]=x[i]+vx[i];
    y[i]=y[i]+vy[i];
  }
}

void display(){
  for(int i=0; i<n; i++){
    fill(255);
    ellipse(x[i],y[i],raio[i]*2,raio[i]*2);
  }
}

Re: beginner: collision of multiple balls
Reply #3 - Sep 26th, 2008, 11:47am
 
two things that might help speed it up

for(int i=0; i<n; i++){
   for(int c=0; c<n; c++){

you are doing twice as many compares as you need to - you compare ball 1 with ball 2 and then later you compare ball 2 with ball 1 etc. i *think* making c go from i + 1 to n in the inner loop (or from 0 to i - 1) will fix this (and remove the need for the if (i!=c)...)

also sqrt is expensive and can be avoided by squaring both sides

sqrt(a * a + b * b) < c

is the same as

(a * a + b * b) < (c * c)

and the latter is faster
Re: beginner: collision of multiple balls
Reply #4 - Sep 26th, 2008, 11:53pm
 
hi koogs

thanks for your help. i didn't understand what you meant about comparing as much as i needed. actually i don't understand much the way of creating nested loops for setting checkpoints, or as a base for comparisons.

all i knew was that in the beginning i was comparing the same ball within itself, so it wouldn't work(better, it would contiualy keep changing speed, that in the long run, it would remain stuck). and that i needed to set another ball to compare. it seems that the nested loop works for that, but i still can't figure out how it does assign a ball with[c] and other with [i].

just scratching the surfaces of it.
Re: beginner: collision of multiple balls
Reply #5 - Sep 27th, 2008, 2:32pm
 
eduzal wrote on Sep 26th, 2008, 11:53pm:
i still can't figure out how it does assign a ball with[c] and other with [i].


think of it as a matrix and i refers to the row (the first ball) and c refers to the column (the second ball). for each row you have to go through every column, so you need the c loop within the i loop.

float d=sqrt(sq(x[i]-x[c]))+(sq(y[i]-y[c]));

this bit is working out the distnace between pairs of balls, x[i] is x position of first ball, x[c] is x pos of second ball. this is just pythagorean distance where x[i] - x[c] is x distance and y[i] - y[c] is y distance.

as for the compares you just have to realise that the comparison matrix is symmetrical. the diagonal is where a ball is being compared to itself so you don't need that but also that the upper triangle is just a reflection of the lower triangle and you don't need both.

Code:

AA AB AC AD
BA BB BC BD
CA CB CC CD
DA DB DC DD


AA BB CC DD will all be 0 (comparing a ball with itself) and BA (distance from B to A) is the same as AB (distance from A to B)

so really all you need to do is to calculate BA CA CB DA DB DC which is 6 things rather than 16
Re: beginner: collision of multiple balls
Reply #6 - Oct 3rd, 2008, 8:39pm
 
hi koogs

thank you. i'm getting to understand things further now. taking the lessons and following some books.

thanks for your time.
Page Index Toggle Pages: 1