gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Collision and response: Circles and boxes

#112833 - sirpoonga - Wed Dec 20, 2006 7:13 pm

I've been trying to find resources on collision detection and response for circles and boxes. Doing a circle and a plane is pretty easy. But a circle and a point I am having trouble finding info on.

What I am finding involves floating point math. I know I will need to convert that to fixed point so that is another task I have to look up after figuring this out. Right now I don't care how slow it runs, I just want to get the concepts down.

I am working on a labyrinth game for the DS and the DS Motion detector.
http://img.photobucket.com/albums/v472/SirPoonga/gamedev/maze2.jpg

I would like the physics to be realistic, but will take shortcuts where necessary.

I do plan on implementing friction and elasticity (can choose from different types of balls - rubber bouncy ball, metal bearing, etc...).

Since the walls are at horizontal and verticle angles that simplifies things. Testing if the ball will collide with a wall edge is easy. Actually, detecting if it will collide with a corner is easy.

What I am finding trouble with is determining the response, the new velocity vector after hitting a corner. And edge is easy, you just flop sign bit for the one axis. Then take that vector and multiply by elasticity.

From what I understand about circles and corners you need to calculate the exact moment the circle collided. And then there is some calculations with the normalized vector that is created from the corner point to the circle center. That's about all I have gathered, I've only found generalizations and nothing specific.

Some of my conclusions so far:
The vector direction created between the corner and the circle center is the direction of the force the corner is going to apply. The amount of force, as Newton put it, would be the same amount as what the ball puts int he opposite direction, right? So the question now is how do I determine how much force was applied in that direction? I suppose mass would make a difference here. To simplify things maybe I will make mass a constant of 1.

High school physics is vaguely coming back...

#112834 - Miked0801 - Wed Dec 20, 2006 7:23 pm

Ok, got a milestone today, but I can give you a few quick pointers.

Circle/Point collision is very simple. Take the distance between the center of the circle and the point you are checking. Compare vs. the radius. If less than radius, collision. For speed an accuracy, use a radius squared check against the distance squared (no icky sqrt() functions and 100% accurate.)

Collision with a corner can be assumed to be collision with a "wall" that is perpendicular to the center of the circle and the point of the collision. Hmm. Not easy to understand that - ok. For corner collision, take the point of the corner and the center of the circle and form a vector. Now reflect your velocity on this vector. It's the same principle as colliding with a "wall" where the wall collide point will always be perpendicular to X or Y in your code - and as such makes the resulting collision an X/Y velocity reflection.

The good news is that all the above calcs are very fast and can easily be done with fixed point/integer math.

Good luck.

#112835 - sirpoonga - Wed Dec 20, 2006 7:33 pm

You repeated everything I said :(

I know it is like colliding with a wall at the tangent. It's calculating the amount of force the ball exerts in that direction which I am having trouble with. Let's say a ball hits a top right corner with a velecoity vector of 185 degrees and the collision point is at 200 degrees. I need to know how much force is applied in that 200 degree direction.


also about collision detection. Yes, if the point is less than the radius it collided. But you don't want to use the circle's position at that time. Let's take two consecutive frames, one before the circle collided and one after the circle collided. At the second frame the circle will have passed it's collsion point. If you base your calcs off the current circle's position it will be inaccurate. The collision took place in between the two frames. I've seen ways to calculate this so I won't deal with this right now. It's just a matter of appropriately adjusting the balls location.

#112837 - Miked0801 - Wed Dec 20, 2006 7:41 pm

Lol. Just using the previous frame's position will probably be good enough for a game - it has worked fine for me in a number of past projects. But, you could always solve for the exact point of collision if you really felt the need.

And on the force - ok, if you don't want to just assume instant rebound and no energy lost (most games do), you could treat the ball as a "spring" and apply force as per it's spring constant as the wall intrudes further into the circle's area. Basically, the further the circle is compressed towards the center, the harder (linearly) the wall press back.

#112855 - sirpoonga - Wed Dec 20, 2006 9:23 pm

Ok, I thought about it and I realize what I need to do. I need to find the reflecting vector, duh. If my high school geometry memory serves me correct that has something to do with dot products. Doing a quick search is this right?
R = V - 2*N*(V dot N) Where V is object vector and N is normal vector. So, just a matter of implementing this with fixed point math.

I shouldn't have to calculate any forces. Friction is a constant force will create a constant vector that gets added onto the ball's velocity vector. No trig should be involved.

Edit: Could I just use the t16 data type for this, then I don't have to worry about making my own fixed point conversions?