我正在制作一个需要检测2个非轴对齐框之间碰撞的程序。我的程序只需要指示2个非轴对齐框是否发生碰撞。我希望有最简单有效的算法。
因为你可以看到正方形1,2和3会返回true,因为它们与绿色方块相撞。 4会因为没有碰撞而返回false。
我确实在单独的数组列表中包含了这两种颜色的所有框。
有人知道这个问题的库或算法吗?提前谢谢。
答案 0 :(得分:1)
查看java.awt.geom包中的Area类。
http://docs.oracle.com/javase/6/docs/api/java/awt/geom/Area.html
答案 1 :(得分:0)
常用方法涉及quadtrees。这是一篇很好的写作和教程here,它解释了如何使用四叉树在2D空间中执行碰撞检测。
一般的想法是,您的游戏区域将继续被四个分区作为您的添加对象。每个分区称为一个节点,每个节点将维护对相应分区中存在的对象的引用。根据对象在2D空间中的位置将对象放入节点中。如果节点不完全适合分区,则将其插入父节点。使用此方法,您不必对2D空间中的每个其他对象执行昂贵的检查,因为您可以确定不同节点(在同一级别,即兄弟节点)中的对象不会发生冲突。因此,您只需对一小部分对象执行碰撞检测。
请注意,这只是告诉您哪些对象占据某个区域;它是一种更有效的方法来磨练可能碰撞的对象。之后,您必须检查对象是否实际发生碰撞。还有另一篇文章here可以通过各种技术来实现这一目标。
答案 2 :(得分:0)
我不知道"容易"你的游戏确实是,你需要检查多少形状(我在这里思考效率),但是如果你在不同的列表中有不同的颜色形状,那么一种强力迭代可能适合你。如果它对您来说足够有效,那不是一个线索。我使用box2D来告诉我碰撞,但听起来这可能对你来说太过分了。
我想到的强力方法是利用libgdx的Intersector类(查看API,它有很多方法)。与其他矩形相比,迭代矩形。如果两个矩形重叠(即:碰撞),像IntersectRectangles()这样的东西会给你一个布尔值。
这可能效率太低/太黑,物理库可能太多了。所以提供的其他答案之一可能是最佳点。
答案 3 :(得分:0)
此问题需要考虑两种算法/数据结构:
用于存储旋转四边形的空间数据结构,以有效地确定需要相互测试哪些四边形对。其他答案已经解决了这个问题。如果四边形的数量足够小,那么你可以测试所有绿色四边形的所有红色四边形,即O(m * n)。
执行一个旋转四边形与另一个旋转四边形的实际测试的算法。其中最简单的是Separating Axis Theorem。
SAT背后的基本思想是,如果你能找到至少一条线,其中一个凸面物体的所有点位于其一侧,而另一侧的所有点位于另一侧,那么这两个没有碰撞。您需要测试的潜在线条只是两个对象的边缘。
要实现它,您需要实施一个点线测试,以告诉您一个点的边缘哪一侧。这是通过计算边缘的法线,然后计算边缘法线的点积和从边缘上的点到您正在测试的点的矢量来完成的。点积的符号告诉您该点在哪一侧(正面表示边缘外侧,表示向外指向法线)。无论你在外部还是在内部计算零(在线)取决于你是否想要只是接触但不能穿透的物体算作碰撞,如果你这样做,那么点积必须大于零才能算作外部。 / p>
例如,如果对象上的点是顺时针顺序,并且edgeA和edgeB是一个对象上的边的两个点,而pointC是另一个对象上的一个点,则测试就像这样(不使用函数)电话,显示数学):
boolean isOutsideEdge(PointF edgeA, PointF edgeB, PointF pointC)
{
float normalX = edgeA.Y - edgeB.y;
float normalY = edgeB.X - edgeA.x;
float vectorX = pointC.x - edgeA.x;
float vectorY = pointC.y - edgeA.y;
return (normalX * vectorX) + (normalY * vectorY) > 0.0f;
}
然后算法是:
SAT可以推广到任意凸多边形。
答案 4 :(得分:0)
所以我决定最后选择box2d。这是最好的解决方案,因为不同的掩模限定符,物体没有碰撞,但是它们很容易被碰撞检查。
我必须创建自己的contactlistener来覆盖默认的contactlistener。如果任何2个物体相撞,我可以做任何事情。
感谢大家的帮助。