是否有一种方法在Libgdx验证多边形和圆之间的碰撞?
我看到了Intersector
类,但只发现了圆形和矩形的碰撞测试。其他多边形呢?
如果我需要手动操作,使用Libgdx的最佳方法是什么?
遗憾的是,我没有足够的声誉来评论,所以我添加了这个作为另一个答案…
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);
}
所以,我设法创建了一个圆形和多边形之间的碰撞测试方法。至少,它对我有用。
代码如下:
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;
}
…并遵循菲尔·安德森的优秀答案,这是我的版本,它只是避免每次检查都创建新的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);
}
}