Collision Between Objects

Member
Posts: 64
Joined: 2005.06
Post: #1
Taking a hint from the O'Reilly tutorial, I've created a simple little program that has a ball that bounces around. I wasn't content with that, so I decided to add gravity, wind and friction and such. I got that to work (yet not quite perfect), but I decided to press on and make multiple balls that also collide with each other.

My question is, how do I do this? I know how to detect the collision (simply comparing points and locations), but I can't get the locations of the other balls. All the balls are kept in an array, and to test the collision of each ball I need to run a for loop. My problem here is, how do I go out and grab all the locations of all the other balls that are in the same array inside the if argument for the collision?

I don't know if that's clear at all, but hopefully someone can help.

Note: A for loop is already running, which grabs the current ball in the loop to be tested to all the other balls.
Quote this message in a reply
Member
Posts: 64
Joined: 2005.06
Post: #2
P.S. How do you do 'and' in an if statement? I believe 'or' is ||, correct me if I'm wrong though.
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #3
logical and is &&
very simple collision between 2 balls or spheres can be done using our good friend the distance formula(related to pythagorous)
Code:
x=ball1.x-ball2.x
y=ball1.y-ball2.y
r=ball1.radius+ball2.radius
if(x*x+y*y>r*r)
   sucessful collision

there is some problems with this code, it does not take into account fast moving objects. So, if you have balls that move faster than the diameter of the ball, this simple solution doesn't work. It also doesn't take moving balls at all, as in a few cases it might show they do not collide, when in fact they did collide between giving time period. BUT! despite these fallacies, if you have all the balls in their position, it will tell you if any are touching any others.
Quote this message in a reply
Member
Posts: 64
Joined: 2005.06
Post: #4
As stated above, the problem isn't how to detect the collision, but how to grab all the other ball positions out of the same array as the ball that's going to test collisions, so a collision can even be tested.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
I'm not sure I understand what you're asking, but I think maybe what you want is a double for loop:

Code:
int i;
for (i = 0; i < NUMBER_OF_BALLS; ++i)
{
    int j;
    for (j = 0; j < NUMBER_OF_BALLS; ++j)
    {
        float xDistance = balls[i].x - balls[j].x;
        float yDistance = balls[i].y - balls[j].y;
        float collisionDistance = balls[i].radius + balls[j].radius;

        if (((xDistance * xDistance) + (yDistance * yDistance)) < (collisionDistance * collisionDistance))
        {
            /* a collision occurred */
        }
    }
}

Notice that this checks more pairs than are necessary (each pair is checked twice, bar each ball with itself which is only checked once).

You can fix this by changing the condition on the inner for loop from j < NUMBER_OF_BALLS to j < i.
Quote this message in a reply
Member
Posts: 469
Joined: 2002.10
Post: #6
what kind of array?

---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Quote this message in a reply
Member
Posts: 304
Joined: 2002.04
Post: #7
Quote:Originally posted by jbrimm
My question is, how do I do this? I know how to detect the collision (simply comparing points and locations), but I can't get the locations of the other balls.


managing collisions (not the actual math involved in detecting collisions) is quite an interesting problem. How do you create classes that are general enough to reuse - but specific enough to understand what to do in each of the many permutations that are possible with collisions.

Here is what I do. Im assuming you are using a object-oriented language.

I create a class called 'Group'. Group has an array of objects of type 'Sprite'. The *Group* class has the code to handle collisions. So I might have:

Group * badGuysGroup, * bulletsGroup, * goodGuyGroup;
...

so I have methods which allow me to:

//collide all sprites in this group w/ each other
badGuysGroup->collideGroup();

//collide all the sprites from one group with all the sprites of another
badGuysGroup->collideWithGroup(bulletsGroup);

//I can avoid doing collisions that wouldnt matter - like I would *not* do this:
bulletsGroup->collideGroup();
//because I dont need to test bullet-bullet collisions

//also if I have a specific sprite I want to collide with all bullets I can:
Sprite * goodGuySprite;
...
bulletsGroup->collideWithSprite(goodGuySprite);

hth,
Codemattic
Quote this message in a reply
Moderator
Posts: 608
Joined: 2002.04
Post: #8
Quote:Originally posted by jbrimm
P.S. How do you do 'and' in an if statement? I believe 'or' is ||, correct me if I'm wrong though.
"And" is && and you are correct, || is "or."
Quote this message in a reply
Member
Posts: 156
Joined: 2002.11
Post: #9
There is a fairly recent and comprehensive article on sphere collision test for a billiard game that can be found on http://www.gamasutra.com (registration required, but it's free).

Time is running out!
Quote this message in a reply
Member
Posts: 157
Joined: 2002.12
Post: #10
Anyone have any info abount bounding boxes collision detection?
Quote this message in a reply
Member
Posts: 156
Joined: 2002.11
Post: #11
I feel bad redirecting people from this forum to another, but http://www.flipcode.com is filled with posting and references about axis-aligned bounding boxes and collision detection. It's worth a peek.

Time is running out!
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #12
we should add how to do circle/sphere and bounding box collision detection to our FAQ.
Quote this message in a reply
ededed
Unregistered
 
Post: #13
Code:
int i;
for (i = 0; i < NUMBER_OF_BALLS; ++i)
{
    int j;
    for (j = 0; j < NUMBER_OF_BALLS; ++j)
    {

// Make sure that balls dont collide with themselves
        if(i != j) {
        
        float xDistance = balls[i].x - balls[j].x;
        float yDistance = balls[i].y - balls[j].y;
        float collisionDistance = balls[i].radius + balls[j].radius;

        if (((xDistance * xDistance) + (yDistance * yDistance)) < (collisionDistance * collisionDistance))
        {
            /* a collision occurred */
        }
        }
    }
}
Quote this message in a reply
Member
Posts: 157
Joined: 2002.12
Post: #14
Sphere collisions are the easiest, once you try to get collision with other primitives it gets very tricky.
For most games spheres will work fine, except if you use physics with non spherical objects.
Quote this message in a reply
Member
Posts: 304
Joined: 2002.04
Post: #15
(this is off the top of my head - I havent tested it)

If you do your loops like this you avoid testing collisions twice.

Code:
int i;
for (i = 0; i < NUMBER_OF_BALLS - 1; ++i)
{
    int j;
    for (j = i+1; j < NUMBER_OF_BALLS; ++j)
    {
     ... do testing here
    }
}

-Codemattic
Quote this message in a reply
Post Reply