# My Simple Circle-AABB Collision Resolution Algorithm Isn't Working

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

## Recommended Posts

I have very basic collision detection requirements, so, instead of a full library, I just tried to write up the most bare-bones algorithm I could. It *almost* works, and I've been staring at it for a while with no progress. Any help is appreciated.

Here's the resolution method:

void PhysicsSystem::resolve_collision(DynamicEntity& entity, int x, int y)
{
Vector2f tile_pos(x, y);
Vector2f nearest(entity.pos);
Vector2f min(x, y), max(x + 1, y + 1);

if (nearest.x() < min.x()) nearest.x() = min.x();
else if (nearest.x() > max.x()) nearest.x() = max.x();

if (nearest.y() < min.y()) nearest.y() = min.y();
else if (nearest.y() > max.y()) nearest.y() = max.y();

Vector2f ray(entity.pos - nearest);
auto length = ray.norm();
auto depth = entity.size - length;

if (length != 0 && depth > 0)
{
ray.normalize();
entity.pos += depth * ray;
}
}

This produces a good response when colliding with a tile below and one to the right, but it collides one tile too soon coming from the other two directions.

Edited by kabbotta

##### Share on other sites

Just take the movement vector into account, so that you prefer a closest point in the direction you are walking.

Something like this (not tested and can be better written):

void PhysicsSystem::resolve_collision(DynamicEntity& entity, int x, int y)
{
Vector2f tile_pos(x, y);
Vector2f nearest(entity.pos);
Vector2f min(x, y), max(x, y);
if (entity.vel.x() < 0) {
min.x = x - 1;
} else {
max.x = x + 1;
}
if (entity.vel.y() < 1) {
min.y = y - 1;
} else {
max.x = y + 1;
}
...
}

Edited by Finalspace

##### Share on other sites

Thanks, I added your suggestion and it does seem to be working a little better, but it still does something funny around the corners.

Here is the method now:

void PhysicsSystem::resolve_collision(DynamicEntity& entity, int x, int y)
{
Vector2f tile_pos(x, y);
Vector2f nearest(entity.pos);
Vector2f min(x, y), max(x, y);

if (entity.vel.x() < 0)
min.x() = x - 1;
else
max.x() = x + 1;

if (entity.vel.y() < 0)
min.y() = y - 1;
else
max.y() = y + 1;

if (nearest.x() < min.x()) nearest.x() = min.x();
else if (nearest.x() > max.x()) nearest.x() = max.x();

if (nearest.y() < min.y()) nearest.y() = min.y();
else if (nearest.y() > max.y()) nearest.y() = max.y();

Vector2f ray(entity.pos - nearest);
auto length = ray.norm();
auto depth = entity.size - length;

if (length != 0 && depth > 0)
{
ray.normalize();
entity.pos += depth * ray;
}
}


Around the corners the collision goes out a little too far sometimes. I think I need to think about the math a little more, because I'm not even sure why your suggestion helped ; )

Edited by kabbotta

1. 1
2. 2
3. 3
Rutin
22
4. 4
5. 5

• 12
• 19
• 14
• 9
• 9
• ### Forum Statistics

• Total Topics
632929
• Total Posts
3009284
• ### Who's Online (See full list)

There are no registered users currently online

×