Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circle and Polygon Collision with Libgdx

Is there a way in Libgdx to verify a collision between a Polygon and a Circle?

I saw the Intersector class but only found collision test for Circle and Rectangle. What about any other Polygon?

If I need to do it manually, what's the best way to do that using Libgdx?

like image 558
Cristiano Santos Avatar asked Mar 10 '13 15:03

Cristiano Santos


Video Answer


2 Answers

Sadly I don't have enough reputation to comment so I'm adding this as another answer instead...

Cristiano's excellent answer works for checking that the circle overlaps one of the line segments of the polygon, however it doesn't check for the more unusual case of the circle being fully contained inside the polygon, which could happen if a small fast moving circle collided with a large polygon.

I've repasted Cristiano's code below with a small change to fix the issue...

public static boolean overlaps(Polygon polygon, Circle circle) {
    float []vertices=polygon.getTransformedVertices();
    Vector2 center=new Vector2(circle.x, circle.y);
    float squareRadius=circle.radius*circle.radius;
    for (int i=0;i<vertices.length;i+=2){
        if (i==0){
            if (Intersector.intersectSegmentCircle(new Vector2(vertices[vertices.length - 2], vertices[vertices.length - 1]), new Vector2(vertices[i], vertices[i + 1]), center, squareRadius))
                return true;
        } else {
            if (Intersector.intersectSegmentCircle(new Vector2(vertices[i-2], vertices[i-1]), new Vector2(vertices[i], vertices[i+1]), center, squareRadius))
                return true;
        }
    }
    return polygon.contains(circle.x, circle.y);
}
like image 77
Phil Anderson Avatar answered Oct 05 '22 08:10

Phil Anderson


So, I managed to create a collision test method between a Circle and a Polygon. At least, it works for me.

Here's the code:

public boolean overlaps(Polygon polygon, Circle circle) {
    float []vertices=polygon.getTransformedVertices();
    Vector2 center=new Vector2(circle.x, circle.y);
    float squareRadius=circle.radius*circle.radius;
    for (int i=0;i<vertices.length;i+=2){
        if (i==0){
            if (Intersector.intersectSegmentCircle(new Vector2(vertices[vertices.length-2], vertices[vertices.length-1]), new Vector2(vertices[i], vertices[i+1]), center, squareRadius))
                return true;
        } else {
            if (Intersector.intersectSegmentCircle(new Vector2(vertices[i-2], vertices[i-1]), new Vector2(vertices[i], vertices[i+1]), center, squareRadius))
                return true;
        }
    }
    return false;
}
like image 31
Cristiano Santos Avatar answered Oct 05 '22 07:10

Cristiano Santos