[solved] 2d circle to circle collision response
Posted: Wed Apr 14, 2010 7:45 am
So I'm trying to set up a simple 2d physics system at the moment and for some reason I can't seem to get my circle to circle collision responses working correctly. I'm sure it's a typo or similar but it's not getting anywhere so I felt I should probably post it up online and see if I can get a hand sussing out the problem.
NOTE: the collision detection works, I am having trouble with the response.
NOTE: the collision detection works, I am having trouble with the response.
Code: Select all
void circleToCircleCollision(Entity* circleA, Entity* circleB)
{
//Determines the strength of reflection, this will be expanded on later.
float bounce=1.0f;
//Note: i store the deltaX and deltaY in a vector for convenience.
vector2<float> delta(circleA->x-circleB->x,circleA->y-circleB->y);
float distance=delta.magnitude();
//entities have a width and a height, from this we can create a radius by using the one that is larger (this is a temporary way of getting the combined radius of each entity)
float totalRadius=0.0f;
circleA->sizeX>circleA->sizeY?totalRadius+=circleA->sizeX:totalRadius+=circleA->sizeY;
circleB->sizeX>circleB->sizeY?totalRadius+=circleB->sizeX:totalRadius+=circleB->sizeY;
//simple circle to circle collision detection
if(distance <= totalRadius)
{
delta.normalise();
float velocityA = (circleA->motion.x*delta.x) + (circleA->motion.y*delta.y);
float velocityB = (circleB->motion.x*delta.x) + (circleB->motion.y*delta.y);
if((velocityA-velocityB)!=0.0f)
{
float deltatime = (totalRadius - distance)/(velocityA - velocityB);
//Move the circles so they are in the position where they had just touched.
circleA->x-=circleA->motion.x*deltatime;
circleA->y-=circleA->motion.y*deltatime;
circleB->x-=circleB->motion.x* deltatime;
circleB->y-=circleB->motion.y* deltatime;
//
float projectionA=(circleA->motion.x*delta.x) + (circleA->motion.y*delta.y);
float _projectionA=(circleA->motion.y*delta.x) - (circleA->motion.x*delta.y);
float projectionB=(circleB->motion.x*delta.x) + (circleB->motion.y*delta.y);
float _projectionB=(circleB->motion.y*delta.x) - (circleB->motion.x*delta.y);
//new velocity
float vA=(projectionA+bounce*(projectionB - projectionA))/(1.0f+(circleA->mass/circleB->mass));
float vB=(projectionB+bounce*(projectionA - projectionB))/(1.0f+(circleA->mass/circleB->mass));
//Use the attained data to assign the new motion vector
circleA->motion.x =((vA*delta.x) - (_projectionA*delta.y));
circleA->motion.y =((vA*delta.y) + (_projectionA*delta.x));
circleB->motion.x =((vB*delta.x) - (_projectionB*delta.y));
circleB->motion.y =((vB*delta.y) + (_projectionB*delta.x));
//The balls position was shifted 'back in time' so we shift it once more to account for this.
circleA->x+=circleA->motion.x* deltatime;
circleA->y+=circleA->motion.y* deltatime;
circleB->x+=circleB->motion.x* deltatime;
circleB->y+=circleB->motion.y* deltatime;
}
}