Reputation: 9146
I have a bouncing ball application and I have to extend it to prevent overlapping of the balls.
When ball overlaps another, they should move away as in real life.
I have to extend the given MoveBall
method:
private void MoveBall()
{
prevX = x;
prevY = y;
x += xVelocity;
y += yVelocity;
// Is there too closed ball?
foreach (Ball ball in parentForm.balls)
{
distance = Math.Sqrt(Math.Pow((double)(ball.prevX - prevX), 2) +
Math.Pow((double)(ball.prevY- prevY), 2));
overlap = ((radius + ball.radius) - distance);// +ball.radius;
if (ball.id != this.id &&
ball.id != lastID &&
overlap > 0)
{
lastID = this.id;
if (xVelocity > 0) // roading right
{
xVelocity = -xVelocity;
x -= xVelocity - ball.xVelocity;
}
else if (xVelocity <= 0) // roading left
{
xVelocity = -xVelocity;
x += xVelocity + ball.xVelocity;
}
if (yVelocity > 0)
{ // going up
yVelocity = -yVelocity;
y -= yVelocity - ball.yVelocity;
}
else if (yVelocity <= 0) // down
{
yVelocity = -yVelocity;
y += yVelocity + ball.yVelocity;
}
}
}
// ***********************************************
// ***************** END MY CODE *****************
if (x > parentForm.Width - 10 - (radius) || x < 0)
{
if (x < 0) x = 0;
if (x > parentForm.Width - 10) x = parentForm.Width - 10 - radius;
xVelocity = -xVelocity;
}
if (y > parentForm.Height - 40 - (radius) || y < 0)
{
if (y < 0) y = 0;
if (y > parentForm.Height - 40) y = parentForm.Height - 40 - (radius);
yVelocity = -yVelocity;
}
}
x,y, xVelocity, yVelocity, radius, prevX, prevY declared as int.
overlap, distance as double.
When 2 overlap, they are getting stuck. Why?
Unfortunately, I can't upload all source code because there are lot of modules. I'm using Visual C# Express 2010.
Upvotes: 2
Views: 3637
Reputation: 6060
As no Question is asked explicitly, I will assume the question "Why are the balls sticking together?"
You have only shown one loop in source code, that's not enough ;-) To check all possible collisions, you need to check n*(n-1)/2 possible collisions. That is normally done with two loops. You have to put in careful measures to avoid handling the same collision twice.
The reason that your balls get stuck is that you handle the same collision multiple times. For example two balls colliding exactly horizontal: The left one has velocity 5 and x-position of 100. The other one shall have a position of 110 and velocity of -6. When the collision happens:
The balls were at 100 and 110 resp. and have been moved to 104 and 105. While the velocities are now pointing away from each other, the collision handling in the following step will invert them again. So the positions are close together and the velocities are changing sign every frame. The balls seem "stuck to each other".
I hope the answer helps you to understand your problem. For a better implementation of an elastic collision (that handles each collision exactly once) look here: Ball to Ball Collision - Detection and Handling
Upvotes: 2
Reputation: 29213
Having stumbled upon similar issues when I made my first attempts at collision detection algorithms, I'll try to describe what I think is the problem here.
Maybe the balls move fast enough so that, before collision is even detected by your code, they are already partially "inside" each other. When collision detection comes and notices that, it does what it's supposed to do: change the planned trajectories of the objects according to the details of the collision that just happened. The problem is that, because these objects got sort-of "merged" before collision detection caught them, they can't get unstuck because collision detection is fired again, trapping them with each other.
If this is the source of the problem, then maybe the above code would work with a small enough velocity vector. Of course, that's not a real solution, but if it does work for very small velocities, it probably confirms my hypothesis and you have some idea regarding how to proceed.
Upvotes: 0