使用Libgdx实现圆形和多边形碰撞

10

在Libgdx中有没有一种方法来验证一个多边形和一个圆形之间的碰撞?

我看到了Intersector类,但只发现了圆形和矩形之间的碰撞测试。那其他多边形呢?

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

3个回答

14

很遗憾我没有足够的声望来发表评论,所以我只能将这个答案作为另一个答案添加...

Cristiano的出色答案适用于检查圆形是否与多边形的线段之一重叠,但它不检查更为罕见的情况,即圆形完全包含在多边形内部,这可能会发生如果小而快速移动的圆形与大多边形碰撞。

我已经复制了Cristiano的代码,并进行了小的更改以解决这个问题...

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);
}

好的,当时我只需要检查外部碰撞,所以我不知道这个。感谢更新 ;) - Cristiano Santos
这需要放入libgdx中。 - Denys Kniazhev-Support Ukraine
请确保不要在方法内创建新的向量,否则使用的内存将会快速膨胀。可以使用类似于 tmpVector2.set(x, y) 的方式来代替 new Vector2(x, y)(其中 tmpVector2 是一个字段)。 - Denys Kniazhev-Support Ukraine

13

所以,我成功地创建了一个在圆形和多边形之间进行碰撞测试的方法。至少对我来说是有效的。

这是代码:

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;
}

这段代码能否适用于 PolyLine 而不是 Polygon? - Vetalll
抱歉,我不知道,因为我是在两年前提出这个问题/回答的 =/ - Cristiano Santos
我检查了这段代码。是的,这是适用于多边形和折线的工作代码。 - Vetalll

0

......并且跟进Phil Anderson的出色回答,这是我的版本,它简单地避免了在每次检查时创建新的Vector2,并改为重复使用Vector2的静态实例。

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);
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接