#### Archived

This topic is now archived and is closed to further replies.

# collision of basic shapes?

This topic is 4986 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

does anyone know how to detect collisions between shapes like spheres boxes domes and cylinders and the how to move one object out of the other?

##### Share on other sites
I've cut-and-pasted some code from my 2D graphics engine. HasCollided is called first, and it determines if any collision occured (NOTE: I took out some error checking for readablity). Basicly, I take the distance between the upper left hand corners of each bounding box, and check if the upper left hand corner is too close to the other box.

In CorrectForPush, I push the first object away from the second one. I calculate how much I would have to move the sprite in each direction, and choose the shortest distance.

bool BoundingBox::HasCollided(BoundedObject *obj){// gets a handy pointerBoundingBox *b = (BoundingBox *)obj;int distX = abs(b->X - X);    // check for horz collision    if(distX < b->width || distX < width)    {    int distY = abs(b->Y - Y);        // check for vertical collision        if(distY < b->height || distY < height)        {        CorrectForPush(b);        velX = velY = 0;        return true;        }    }}// corrects positionvoid BoundingBox::CorrectForPush(BoundingBox *b){    // if this is immovable, don't bother checking    if(isImmovable == true)return;// calculates moves of the object to avoid collisionint  leftX = b->X - width;int  rightX = b->X + b->width + 1;int  leftY = b->Y - height;int  rightY = b->Y + b->height + 1;        // left X is the shortest move to no collision    if(leftX < rightX && leftX < leftY && leftX < rightY)X = leftX;    // right X shortest    else if(leftY < leftX && leftY < rightX && leftY < rightY)X = rightX;                    // right Y shortest    else if(rightX < leftX && rightX < leftY && rightX < rightY)Y = rightY;     else Y = leftX;}

--------------------------------------------------------------------------------
Good Links: C++ Reference, Java API

[edited by - Onemind on May 26, 2004 11:50:18 PM]

##### Share on other sites
Do you mean in 3D? That''s a pretty huge topic :-)

Spheres are pretty easy. Two spheres intersect if the distance between them is less than the sum of their radii. To avoid the square root, we usually compare the squared distance between them to the sum of their squared radii.

The ''move away'' vector is simply the normalized vector between the centers of the spheres. Ideally you would move them along this vector (+ly and -ly, respectively) until they are just touching. You should be able to figure out the appropriate amounts algebraically.

Axis-aligned bounding boxes (AABBs) are also pretty easy. The intersection test consists of checking three potential separating axes (look up ''separating axis test''), which in this case are simply the three orthogonal world axes. Based on the results of these tests you can figure out how much they are intersecting and presumably what direction and how far to push them so that they are just touching.

Oriented bounding boxes (OBBs) are a little trickier. The separating axis test requires a maximum of 15 axes tested rather than three.

I should mention at this point that rather than pushing away two objects that intersect, you can do dynamic ''swept volume'' tests that give you the first time of intersection. Then you simply move the objects to the first time of intersection, and they will be just touching.

Cylinder/ray intersection is pretty easy, but other intersection tests involving cylinders can get pretty involved. I''d stay away from them unless you really need them.

Collision (or intersection) testing is a huge topic that generally requires a lot of study. But if you just limit yourself to spheres or AABBs for the time being, you should be able to get up and running fairly quickly.