关于 java:Circle and Polygon Collision with Libgdx

Circle and Polygon Collision with Libgdx

Libgdx 中有没有办法验证多边形和圆之间的碰撞?

我看到了 Intersector 类,但只找到了 Circle 和 Rectangle 的碰撞测试。其他多边形呢?

如果我需要手动完成,使用 Libgdx 的最佳方法是什么?


遗憾的是,我没有足够的声誉来发表评论,所以我将其添加为另一个答案...

克里斯蒂亚诺的出色答案适用于检查圆是否与多边形的线段之一重叠,但它不会检查圆完全包含在多边形内的更不寻常的情况,这种情况可能会发生如果一个快速移动的小圆与一个大多边形相撞。

我已经在下面重新粘贴了 Cristiano 的代码,并进行了一些小改动以解决问题...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
}


所以,我设法在 Circle 和 Polygon 之间创建了一个碰撞测试方法。至少,它对我有用。

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}


...为了跟进 Phil Anderson 的出色回答,这是我的版本,它只是避免每次检查都创建新的 Vector2,而是重新使用 Vector2 的静态实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class PolygonUtil {

static final Vector2 center = new Vector2();
static final Vector2 vec1 = new Vector2();
static final Vector2 vec2 = new Vector2();

public static boolean overlaps(Polygon polygon, Circle circle) {
    float []vertices=polygon.getTransformedVertices();
    center.set(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(vec1.set(vertices[vertices.length - 2], vertices[vertices.length - 1]),
                    vec2.set(vertices[i], vertices[i + 1]), center, squareRadius))
                return true;
        } else {
            if (Intersector.intersectSegmentCircle(vec1.set(vertices[i-2], vertices[i-1]), vec2.set(vertices[i], vertices[i+1]), center, squareRadius))
                return true;
        }
    }
    return polygon.contains(circle.x, circle.y);
}

}