Sphere - Bounding box collision

Started by
6 comments, last by OrenGL 19 years, 8 months ago
Hi, like my topic says I whant to know how to make an collision between and sphere and an Box and make the sphere move away from the box. If someome knows about an tutorial or if you can explain how this workd I will be glad. thx.
-[ thx ]-
Advertisement
Here's how I would do it:

A cube is made up of six squares. Each square represents it's own infinite plane. There are three 'pairs' of planes: top+bottom, front+back, left+right. Two planes in a pair are parallel.

A point can be either between the two planes in a pair or outside the two planes.

If a point is between the two planes in a pair and this is true for all three pairs that means it's inside the cube.

The point we're interested in is the center of the sphere.

If the point is between the two planes in a pair and this is true for exactly two pairs then the sphere can only collide with one of the planes. To be more precise, it is the the nearest of the two planes that the point is not between that the sphere will collide with if they do collide. Do a sphere-plane collision test.

If the point is between the two planes in only one of the pairs then the sphere can only collide with one of the edges (ie. a line). To be more precise, it can only collide with the nearest of the four edges that do not belong to the planes that the point is between. Do a line-spere collision test.

If the point is not between two planes in any of the pairs that the sphere can only collide with the corners of the cube.
To illustrate what I meant by the previous post, here's how it would work in 2D:

squareMMMMMMMM   O  <-circleMMMM

As long as the center of the circle is between the "top" and the "bottom" lines of the square, the circle can only collide with the side of the square. In this particular case, the right side.
     O (outside)MMMM-----MMMM (between the sides)MMMM-----     (outside)

As long as the center of the circle is "outside ", the circle can only collide with the corners of the square.
Fluffe:

Hi, and thanks for your tutorial ;) I got an picture of what you saying.

thx.
-[ thx ]-
I'm not sure what you mean by 'moving away from the box'. If you want the sphere to bounce of the cube like a ball would in real life, then here's a way to do it:

You're trying to move the sphere with the movement vector v0. The sphere collides with the cube before moving all the way. The movement vector to the point of collision is v1. v2 is the movement that remains, but which is not possible because of the collision. v_bounce is actually just v2 mirrored in the plane you're bouncing off...
d is the distance to the plane.
'normal' is the plane's normal.
we only use normal vectors with a length of 1.


Bouncing off a plane:

Let the sphere collide with the plane (ie. move it as close to the plane as you can). This is done by using the following formula:

v1 = v0 * (d/l0)

movement_vector = original_movement_vector * (distance_to_plane / length_of_projection)

'l0' is the length of the projection of 'v0' unto the plane's normal. Now we will bounce off the plane. v2 = v0 - v1
v_bounce = v2 + 2 * normal * l2

'l2' is the length of the projection of 'v0' unto the plane's normal. We assume that the normal is pointing out of the cube (otherwise it should be v2 - 2 * normal * l2)

The movement vector for the complete movement towards the plane and back is simply v1 + v_bounce


Bouncing off an edge:

Find the exact point where the sphere intersects with the line. Find the plane that contains that point and which has a normal which is parallel to and has the same direction (but probably not the same length) as the vector from the point of intersection to the center of the sphere when the sphere and the line intersect!. Ie. calculate where the center of the sphere will be when they intersect, find the vector from the point where they intersect to the center of the sphere and set its length to 1. Construct a plane from the point where they intersect and this vector (this is the easiest part).

Now you just bounce of this new plane the same way you did before.


Bouncing off a corner:

This time you don't have to find a point where the sphere intersects with anything. Just use the corner as the point. Ie. calculate where the center of the sphere will be when it intersects with the corner, find the vector from the corner to the center of the sphere and set its length to 1. Construct a plane from the point where they intersect and this vector and bounce off this plane.



I'm probably not very good at explaining this and I'm very tired so I probably made some mistakes. I'm willing to help you further if you need it, but you should read up on basic things like vector math (eg. projections) and intersections between spheres, planes and lines is you don't master this already.
Quote:Original post by X5-Programmer
Fluffe:

Hi, and thanks for your tutorial ;) I got an picture of what you saying.

thx.



No problem. Well, actually I should have gone to bed long time ago, but that's not your fault ;). The last post took a long time to write so I didn't see your answer until after I posted it.

Feel free to ask any other questions you might have, although I won't be able to answer in the next few hours due to sleeping.


BTW. I think usually (ie. in most games) you'd just do collision with the planes and ignore the edges/corners. Doing so can work well in many cases. The approach I have described is the "realistic" or "correct" way of doing it, but neither the simplest nor the most efficient.
Fluffe:

Thanks alot dude for your help and willingness to explain this all for me =).

Edit : you can take your beauty sleep now if you want hehe =).
-[ thx ]-
If you had two spheres the solution would seem obvious; is the sum of their radiuses smaller/larger than the distance between their centers?

Ok but how do you find a radius of a box? Well the solution is to use the "Effective Radius", which is kind of like saying the closet point to the sphere on the box.

Let 'D' be the line connecting the two centers and 'N'=normalize(D). Lets call the box axis vectors R1, R2 and R3 these should NOT be normalized.

Now the hard part is to understand that
abs(dot(Rn,N))
is the distance in direction N on the Rn axis. You need to use abs since you don't know what direction R is pointing and we really only need the size.

So the effective distance in direction N is
effective_raduis_size = (abs(dot(R1,N)) + abs(dot(R2,N)) + abs(dot(R3,N)) )

This is now like the two spheres problem; two radius with two centers (actually you already have the distance between them from above).
Don't shoot! I'm with the science team.....

This topic is closed to new replies.

Advertisement