D4Ly
asked on
Colliding Balls help!
I am working on something in which balls fall from the top of the stage and then bounce around, off the walls and one another. Each balls has a random size and mass defined at runtime, and all animation is scripted. My problem is on the collisions.
On the stage a clip runs a loop every frame going through each ball checking to see if a collision has been made with another ball. It seems that a collision is detected, processed, and the resultant velocities are applied to each ball properly, but because there is the possibility of overlapping at the time of the collision detection, the balls may be seen as colliding on the next frame as they try and move apart, resulting in another calculation. This causes the balls to just bunch up.
I seem to need some way to either
a) separate the balls properly when a collision is detected
b) make sure another collision calculation isn't processed until the distance between balls is greater than radius + radius2
How to go about this has me confused. Any thoughts?
I'll be more than happy to post my flash file for download if neccessary!!
-D4
On the stage a clip runs a loop every frame going through each ball checking to see if a collision has been made with another ball. It seems that a collision is detected, processed, and the resultant velocities are applied to each ball properly, but because there is the possibility of overlapping at the time of the collision detection, the balls may be seen as colliding on the next frame as they try and move apart, resulting in another calculation. This causes the balls to just bunch up.
I seem to need some way to either
a) separate the balls properly when a collision is detected
b) make sure another collision calculation isn't processed until the distance between balls is greater than radius + radius2
How to go about this has me confused. Any thoughts?
I'll be more than happy to post my flash file for download if neccessary!!
-D4
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Iammontoya-
I'm not sure how that is supposed to help. My direction change calculations are a little more complex, but the basic idea is exactly the same as the link you've provided, but does not address my issue of balls against the wall or floor (since there is in fact no wall or floor in that example). I know how to 'fish', and have done my research...that's why I am here :) Perhaps a solution is out there, but I have yet to find it.
for(var i=0; i<maxBalls; i++){ //check collisions
bi = _root["ball"+i];
if(!bi) continue;
for(var j=i+1; j<maxBalls;j++){
bj = _root["ball"+j];
if(!bj) continue;
var xd = bi._x - bj._x; var yd = bi._y - bj._y;
var dr = Math.sqrt(Math.pow(xd,2) + Math.pow(yd,2)); //distance between balls
var rads = ((bi._width / 2) + (bj._width / 2)); //total distance between center points
var tm = (bi.code.mass + bj.code.mass)/2; //half of total system mass
if(bi.hitTest(bj)){ //check if balls are colliding
var nx = xd/dr; var ny = yd/dr; //normal vectors
var v0 = ( bi.code.vx * nx + bi.code.vy * ny );
var v1 = ( bj.code.vx * nx + bj.code.vy * ny );
var relv = v0 - v1; //relative velocity calculation
var vec0 = -bounce * relv; var vec1 = bounce * relv; //new vectors
bi.code.vx = (bi.code.vx) + nx * vec0 * bj.code.mass / tm; //set the resultant velocities
bi.code.vy = (bi.code.vy) + ny * vec0 * bj.code.mass / tm;
bj.code.vx = (bj.code.vx) + nx * vec1 * bi.code.mass / tm;
bj.code.vy = (bj.code.vy) + ny * vec1 * bi.code.mass / tm;
}
}
}
The math here works beautifully when the balls are both in the air. Its when one of the balls collides off of a wall or the floor that I run into some issues.
I've been thinking. I never have an issue with the ball getting caught up in the wall or floor itself. I believe this is because when the ball collides with a wall or floor it's position is reset to be completely inside the container, and then the new velocities are applied. Perhaps a solution would be to move the balls apart in the direction they will be traveling and _then_ apply the resultant velocities. How to do this is a bit unclear at this point, as well as how to deal with the walls and floor when moving a ball that is say, stationary on the ground.
Another thought would be to set a timer of some sort up, which would not allow for another collision calculation on the same 2 balls for a certain period of time, allowing them to move apart.
-D4
I'm not sure how that is supposed to help. My direction change calculations are a little more complex, but the basic idea is exactly the same as the link you've provided, but does not address my issue of balls against the wall or floor (since there is in fact no wall or floor in that example). I know how to 'fish', and have done my research...that's why I am here :) Perhaps a solution is out there, but I have yet to find it.
for(var i=0; i<maxBalls; i++){ //check collisions
bi = _root["ball"+i];
if(!bi) continue;
for(var j=i+1; j<maxBalls;j++){
bj = _root["ball"+j];
if(!bj) continue;
var xd = bi._x - bj._x; var yd = bi._y - bj._y;
var dr = Math.sqrt(Math.pow(xd,2) + Math.pow(yd,2)); //distance between balls
var rads = ((bi._width / 2) + (bj._width / 2)); //total distance between center points
var tm = (bi.code.mass + bj.code.mass)/2; //half of total system mass
if(bi.hitTest(bj)){ //check if balls are colliding
var nx = xd/dr; var ny = yd/dr; //normal vectors
var v0 = ( bi.code.vx * nx + bi.code.vy * ny );
var v1 = ( bj.code.vx * nx + bj.code.vy * ny );
var relv = v0 - v1; //relative velocity calculation
var vec0 = -bounce * relv; var vec1 = bounce * relv; //new vectors
bi.code.vx = (bi.code.vx) + nx * vec0 * bj.code.mass / tm; //set the resultant velocities
bi.code.vy = (bi.code.vy) + ny * vec0 * bj.code.mass / tm;
bj.code.vx = (bj.code.vx) + nx * vec1 * bi.code.mass / tm;
bj.code.vy = (bj.code.vy) + ny * vec1 * bi.code.mass / tm;
}
}
}
The math here works beautifully when the balls are both in the air. Its when one of the balls collides off of a wall or the floor that I run into some issues.
I've been thinking. I never have an issue with the ball getting caught up in the wall or floor itself. I believe this is because when the ball collides with a wall or floor it's position is reset to be completely inside the container, and then the new velocities are applied. Perhaps a solution would be to move the balls apart in the direction they will be traveling and _then_ apply the resultant velocities. How to do this is a bit unclear at this point, as well as how to deal with the walls and floor when moving a ball that is say, stationary on the ground.
Another thought would be to set a timer of some sort up, which would not allow for another collision calculation on the same 2 balls for a certain period of time, allowing them to move apart.
-D4
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I tried your suggestion, but the result unfortunately is that the balls grab each other more smoothly.
Check it out.
http://www.d4ly.com/ee/anim_03_b.swf
this is with setInterval at 1ms.