Hey guys!
I have a question about collision response.
In my program I check if some circles collide, and if they do, the collision is being resolved and the new velocities are being set.
That works fine if the circles have the same radii, but when the radii are different, the circles stick together sometimes.
Here's (http://vimeo.com/89234201) a video showing the problem. ( I recommend you to watch it in fullscreen mode. The password is 'sfml')
Here's my resolve circle to circle collusion function:
void resCtcCollision(elasticCircle &circleA, elasticCircle &circleB) //Resolve Circle to Circle Collision
{
sf::Vector2<long double> v1(circleA.getVel());
sf::Vector2<long double> v2(circleB.getVel());
sf::Vector2<long double> ap(circleA.getPosition());
sf::Vector2<long double> bp(circleB.getPosition());
sf::Vector2<long double> n = ap - bp;
n = Normalize(n);
long double a1 = dotProduct(v1, n);
long double a2 = dotProduct(v2, n);
long double optimizedP = (2.0 * (a1 - a2)) / (circleA.getMass() + circleB.getMass());
v1 = v1 - optimizedP * circleB.getMass() * n;
v2 = v2 + optimizedP * circleA.getMass() * n;
circleA.setVel(v1);
circleB.setVel(v2);
}
My timestep is correct.
Has anyone an Idea what I've could done wrong?
Well, how's your collision function? In the response function you only change the velocity, that might be enough if the circles each have a large enough radius, but what happens if the center of a circle fully enters the other circle before the collision gets detected? Besides changing the velocity you might want to ensure that the circles' center are outside of the other circle.
Yes, I think that's ensured already.
Here's my collision function:
bool altCtcCollision(sf::Vector2f a, sf::Vector2f b, float radA, float radB) // Alternative Circle to Circle Collision (I have two different Collision-detection methods)
{
float dx = b.x - a.x;
float dy = b.y - a.y;
float radii = radA + radB;
return ( dx * dx ) + ( dy * dy ) < radii * radii;
}
The collusion will be resolved if this boolean is true. I also added a if-statement in the resolve-collision function to ensure that the center of circle A is outside of the circle B:
void resCtcCollision(elasticCircle &circleA, elasticCircle &circleB) //Resolve Circle to Circle Collision
{
if(Distance(circleA.getPosition(), circleB.getPosition()) > circleB.getRadius())
{
// Calculate and set new Velocities
}
}
But it still doesn't work. :(
To detect collision between two circles, do following:
if (sqrt(pow(circle1.getPosition().x - circle2.getPosition().x, 2) + pow(circle1.getPosition().y - circle2.getPosition().y, 2)) <= circle1.getRadius() + circle2.getRadius()) { }
P.S. I'm writing this from my mobile so code might be wrong.