Billie
Billie

Reputation: 9146

Implement bouncing balls collision detection

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.

enter image description here

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

Answers (2)

DasKr&#252;melmonster
DasKr&#252;melmonster

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:

  1. x is set to 105.
  2. Collision detected: x is set to 104 and velocity to -5.
  3. The other Ball handles the same collision:
  4. He moves according to his velocity to position 104.
  5. Collision handling: His velocity becomes 6 and position becomes 105.

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

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

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

Related Questions