Home > front end >  OpenGL 2D Circle - Rotated AABB Collision
OpenGL 2D Circle - Rotated AABB Collision

Time:11-14

I have trouble figuring out a way to detect collision between a circle and a rotated rectangle. My approach was to first rotate the circle and the rectangle by -angle, where angle is the amount of radians the rectangle is rotated. Therefore, the rectangle and the circle are aligned with the axes, so I can perform the basic circle - AABB collision detection.

bool CheckCollision(float circleX, float circleY, float radius, float left, float bottom, float width, float height, float angle){

        // Rotating the circle and the rectangle with -angle
            circleX = circleX * cos(-angle) - circleY * sin(-angle);
            circleY = circleX * sin(-angle)   circleY * cos(-angle);

            left = left * cos(-angle) - bottom* sin(-angle);
            bottom = left * sin(-angle)   bottom * cos(-angle);

       }

glm::vec2 center(circleX, circleY);
        // calculate AABB info (center, half-extents)
        glm::vec2 aabb_half_extents(width / 2.0f, height / 2.0f);
        glm::vec2 aabb_center(
            left   aabb_half_extents.x,
            bottom   aabb_half_extents.y
        );
        // get difference vector between both centers
        glm::vec2 difference = center - aabb_center;
        glm::vec2 clamped = glm::clamp(difference, -aabb_half_extents, aabb_half_extents);
        // add clamped value to AABB_center and we get the value of box closest to circle
        glm::vec2 closest = aabb_center   clamped;
        // retrieve vector between center circle and closest point AABB and check if length <= radius
        difference = closest - center;

        return glm::length(difference) < radius;

CodePudding user response:

Let rectangle center is rcx, rcy. Set coordinate origin in this point and rotate circle center about this point (cx, cy are coordinates relative to rectangle center):

cx = (circleX - rcx) * cos(-angle) - (circleY - rcy) * sin(-angle);
cy = (circleX - rcx) * sin(-angle)   (circleY - rcy) * cos(-angle);

Now get squared distance from circle center to rectangle's closest point(zero denotes circle center is inside rectangle):

dx = max(Abs(cx) - rect_width / 2, 0)
dy = max(Abs(cy) - rect_height / 2, 0)
SquaredDistance = dx * dx   dy * dy

Then compare it with squared radius

  • Related