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 › understanding boncybubbles example
Page Index Toggle Pages: 1
understanding boncybubbles example (Read 1282 times)
understanding boncybubbles example
Oct 28th, 2009, 11:51pm
 
Hello, im trying to understand how the bouncybubbles code from the processing examples works .... but i do not understand what happens when 2 balls collide, can anybody explain me how the collide function works?

why does it calculate the angle? and what is targetX, targetY, etc?
Can anybody explain this piece of code?

thanks


 void collide() {
   for (int i = id + 1; i < numBalls; i++) {
     float dx = others[i].x - x;
     float dy = others[i].y - y;
     float distance = sqrt(dx*dx + dy*dy);
     float minDist = others[i].diameter/2 + diameter/2;
     if (distance < minDist) {
       float angle = atan2(dy, dx);
       float targetX = x + cos(angle) * minDist;
       float targetY = y + sin(angle) * minDist;
       float ax = (targetX - others[i].x) * spring;
       float ay = (targetY - others[i].y) * spring;
       vx -= ax;
       vy -= ay;
       others[i].vx += ax;
       others[i].vy += ay;
     }
   }  
 }
Re: understanding boncybubbles example
Reply #1 - Oct 29th, 2009, 12:23am
 
Quote:
void collide() {
  for (int i = id + 1; i < numBalls; i++) {
    // for each ball, cycle through all the balls above
    // it in the array.  This prevents dual <--> collisions
    float dx = others[i].x - x;
    float dy = others[i].y - y;
    // d for distance/delta --  x and y dist
    float distance = sqrt(dx*dx + dy*dy);
    // use the pythagorean theorem to get the diagonal distance
    float minDist = others[i].diameter/2 + diameter/2;
    // the minimum distance for two circles to collide
    // is the sum of their radii.
    if (distance < minDist) {
      // distance is less than collision dist...so, collide!
      float angle = atan2(dy, dx);
      // angle between the two circles
      float targetX = x + cos(angle) * minDist;
      float targetY = y + sin(angle) * minDist;
      // minDist is the total collision distance,
      // so targetX and targetY *should* be the center
      // of the colliding circle.  (The trig is just saying:
      // find a point at angle [angle] and distance [minDist].)
      float ax = (targetX - others[i].x) * spring;
      float ay = (targetY - others[i].y) * spring;
      // and yet they obviously differ by a small amount...
      // my best guess is that this collision test is running
      // before the balls actually move, and that the difference
      // between target and actual locations represents the speed
      // of the impending collision.
      vx -= ax;
      vy -= ay;
      others[i].vx += ax;
      others[i].vy += ay;
      //ax and ay modify bounce velocity at the set angle.
    }
  }  
}

Re: understanding boncybubbles example
Reply #2 - Oct 29th, 2009, 1:54am
 
Looks like it's based on a collision detection example in Keith Peter's Actionscript Animation (a great reference book BTW).  In that there's a single, large central ball that the other smaller balls bounce off of.  Here's some text that might help:

"If there is a collision, you find the angle between the two, and use that plus the minimum distance to calculate a target x and y.  This target will be right on the outer edge of the centerBall.

From there, you just apply basic spring code to spring to that point...  once it reaches that point, it's no longer colliding and will fly off in whatever direction it's heading."

BenHem - since (distance < minDist) targetX/Y can't represent a point at the centre of the collision; to get that you would presumably use 'distance' rather than 'minDist' in the calculation.  In fact using minDist in the calculation ensures that targetX/Y will never be the centre of the collision and presumably ensure the balls don't get 'stuck' together...
Re: understanding boncybubbles example
Reply #3 - Oct 29th, 2009, 8:15am
 
thanks for the reply, but what about if i want to implement polygon collision with the ball . I want to add some polygons that can collide with the balls creating a similar effect as balls colliding between each other..... Do you think this approach is well suited for this? I ask this because calculating the collision between point and polygon doenst allow me to get the angle, it just give me back a true or falso.

Do you know which is the best way for adding some polygons that can collide with the balls in the same way?

thanks

Seb.
Re: understanding boncybubbles example
Reply #4 - Oct 29th, 2009, 9:00am
 
Bouncing off polygons is a whole different ball-game (no pun intended - honest!)...  Basically it's a lot more complicated and I must admit not something I've experimented with much.  Depending on what you intend you might want to settle on a kludge, look into available libraries, or go the painful route of writing your own collision methods.  Still I'm sure there are people here with the experience who can make more helpful suggestions Wink
Re: understanding boncybubbles example
Reply #5 - Oct 29th, 2009, 9:02am
 
Or use something like JBox2D (BoxWrap2D) which already did most of the hard job!
Only with convex polygons...
Re: understanding boncybubbles example
Reply #6 - Oct 29th, 2009, 11:36am
 
blindfish, I'm sticking to my guns on this one -- if they're at the point where they're colliding, minDist represents the sum of their radii and therefore the *maximum* distance between the two circles' midpoints...distance, on the other hand, may be slightly less, and I'm guessing the difference represents the speed (depth) of impact..if you have the sketch draw a line between the actual midpoint and targetX/Y, it will be a very short one if it appears at all.

Re: polygons, I would suggest starting with a line.
Re: understanding boncybubbles example
Reply #7 - Nov 1st, 2009, 9:09am
 
Well this had me scratching my head so I did as you suggested and drew a line between the two points and also drew targetX/Y.  Here's how I think it's working:  As you say minDist represents the sum of the radii and therefore the distance that needs to be between them in order for the balls to be separated (i.e. no longer colliding).  When a collision occurs targetX/Y isn't a point that the ball springs towards - which was my first assumption - but a point the ball springs away from; hence:

Code:
vx -= ax;
vy -= ay;


By definition, if there is a collision, 'distance' must always be less than minDist since that's how a collision is defined [if (distance < minDist)]; so as you say the difference between the two represents the force of the impact.  Also the greater the difference between them, the greater the force of the spring action.  TargetX/Y represents a point beyond the centre point of the colliding ball...

Here's a demo.

Re: understanding boncybubbles example
Reply #8 - Nov 2nd, 2009, 3:01am
 
Gonna steal the thread a bit..
I have a similar question...
I can't seem to get my collisions to work, i have either no collision at all, or when the collision occurs the pictures go bananas. I have stared at the code for several hours without any results at all :/
Code:

private void move(){

//xv = hastigheten på x
//sänker hasigheten på xv med xGravity
xv+= xGravity;
//ger hastigheten till xv genom att plussa ihop x med x (hur många steg x ska ta)
x += xv;

// kollar ifall "bollen studsar mot en vägg"
if (x>width || x<0)
{

//xv*=-1;
if(x<0){
x=0+sprite.width/2;
xv*=-0.6;
}
else{
x=width - sprite.width/2;
xv*=-0.6;
}
}
yv += potGravity;
y +=yv;

// if the ball hits the ground, bounce it back up
if(y +sprite.height/2 > ground){
y = ground - sprite.height/2;
yv*=bounce;
}

if(yv<0){
alive=false;
onTheFloor = true;
}
}


Code:

void collide(){
//loopar igenom ballArray och
for (int i = 0; i <ballArray.size(); i++){
//skapar en temp objekt av typen boll för att hålla datan på plats i
Ball temp = (Ball)ballArray.get(i);
//ser till att den hoppar över sig själv
// if the other object is on the ground, you are gonna stick on top
// this means you have to change your ground to the other's top
//if (!temp.onTheFloor && temp.alive)
// ground = int(temp.y);
// if you are on the ground, dont care about collisions
if (!onTheFloor)
if ( temp.getID() != id) {
float dx = temp.getX() - x;
float dy = temp.getY() - y;
float distance = sqrt(dx*dx + dy*dy);
float minDist = temp.getW()/2 + w/2;

if (distance < minDist) {
//println("gayfish: " +distance);
float angle = atan2(dy, dx);
float targetX = x + cos(angle) * minDist;
float targetY = y + sin(angle) * minDist;
float ax = (targetX - temp.getX()) * spring;
float ay = (targetY - temp.getY()) * spring;
//xv *= -1;//-= ax;
//yv *= -1;//-= ay;

//
y = temp.getY() - temp.getH()/2 - h/2;
//y = temp.getH - temp.getY()/2 - y/2;
float tempXV = temp.getXv();
temp.setXv(-tempXV*potGravity/2);
float tempYV = temp.getYv();
temp.setYv(-tempYV*potGravity/2);
}
}
}
}


Help is hugely appreciated!
Page Index Toggle Pages: 1