collision of basic shapes?
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?
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.
--------------------------------------------------------------------------------
Good Links: C++ Reference, Java API
SDL Home Page, Lua Scripting Language, Python Scripting Language
Chris Taylor's Design Document (Downloadabe MS-Word Only), Blitz Basic Homepage
[edited by - Onemind on May 26, 2004 11:50:18 PM]
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
SDL Home Page, Lua Scripting Language, Python Scripting Language
Chris Taylor's Design Document (Downloadabe MS-Word Only), Blitz Basic Homepage
[edited by - Onemind on May 26, 2004 11:50:18 PM]
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement