每个扇区可以表示为(x,y,r,a,d),其中x,y是位置,r是半径,d是方向,a是角度。给定两个圆形扇区的这些信息,如何确定它们是否相互重叠?有没有什么高效的算法来解决它?谢谢!
因为我们有圆形扇区,所以角度和方向不重要,如果你实时这样做。以下内容仅适用于整圈扇区,或者如果两个扇区相互指向。
您可以按照以下步骤操作:
1)求出每个扇区之间的距离,2)将两个半径减去该距离,3)如果结果为负数,则两个扇区之间发生了碰撞。否则,它是碰撞的距离。
例如,我们有两个扇区,半径均为 50 个单位。它们的中心点之间的距离为 80。减去 80-50-50 = -20,所以你知道发生了 20 个单位的碰撞。
否则,如果距离为 500,则 500-50-50 = 400,这是一个正值,现在您知道这两个扇区相距 400 个单位。
现在,如果圆太近,比如说,相隔1个单位,1-50-50=-99,这意味着它们几乎完全重叠。
对于您在注释中指定的真正分段圆形扇区,您应该使用paxdiablos或Macs答案。
有两个步骤。首先是计算出两个中心是否足够接近以允许碰撞,这可以通过比较它们之间的距离和它们的半径之和来完成:
if (((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) > ((r1 + r2) * (r1 + r2)))
// No collision.
然后,您需要检查中心之间的线是否落在由您的各种角度定义的弧线内:
float angle1to2 = Math.atan2(y2 - y1, x2 - x1);
if (angle1to2 < (d1 - a1/2) || angle1to2 > (d1 + a1/2))
// No collision
float angle2to1 = angle1to2 + Math.PI;
if (angle2to1 < (d2 - a2/2) || angle2to1 > (d2 + a2/2))
// No collision
如果您通过了这些检查而没有排除碰撞的可能性,那么您就成功地检测到了碰撞。
警告:这段代码根本没有经过测试。特别是,< code>atan2调用可能需要一些调整,具体取决于您的坐标系。
编辑:刚刚意识到这错过了一个重要的拐角案例,其中弧不是“指向”彼此,而是仍然重叠。将对此深思并返回。。。
我知道一种非常快速的方法来打折这种可能性,因为我以前曾将其用于圆圈碰撞。
计算出两个中心之间的距离,如果大于半径之和,就不会发生碰撞。为了提高效率,不要使用平方根,只需直接计算平方值:
if (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) > (r1 + r2) * (r1 + r2):
# No chance of collision.
圆段的计算会有点困难。
您选择的方法取决于您需要它有多精确。如果你在做实际的数学计算,你可能需要高精度。但是,举例来说,如果你是为了像电脑游戏这样的东西,足够近可能就足够好了。
如果是这样的话,我会考虑将弧线转换为一系列直线(其数量可能取决于弧线的“扩散” - 你可能会用几条线来扩展一度弧度,但这对于 180 度不太有效)。
直线冲突检测是一种更广为人知的方法,尽管您必须处理比较数量可能会迅速增加的事实。
如果你不想使用线段,那么下面是要遵循的过程。它使用一种圆碰撞算法来找出完整圆的零点、一点或两点碰撞,然后检查这些点以查看它们是否在两个圆弧内。
首先,运行上面的检查以检测不可能发生碰撞的情况。如果圆之间不可能发生碰撞,那么圆弧也不会发生碰撞。
其次,检查圆是否有单个碰撞点。如果:
(x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) == (r1 + r2) * (r1 + r2)
当然在合适的误差范围内。我们现在都应该知道,比较浮点数是否相等应该使用某种增量比较。
如果是这种情况,您有一个点要检查,您可以很容易地找到该点。它是沿着从(x1, y1)
到(x2, y2)
的直线上的点r1
单位,或者,将其视为沿着该线移动一些分数:
(x1 + (x2-x1) * (r1+r2) / r1, y1 + (y2-y1) * (r1+r2) / r1)
否则,有两点需要检查,你可以用这个问题的答案来确定这两点是什么。
一旦你有了一些碰撞点,这是一个更简单的方法来确定这些点是否在一条弧上,记住候选点需要在两条弧上才能碰撞,而不仅仅是在一条上。
假设您有两个相同的对象(意味着它们分别具有相同的属性和相同的值)。 你如何测试平等性? 例
本文向大家介绍请问如何判断两个链表是否相交?相关面试题,主要包含被问及请问如何判断两个链表是否相交?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 从头遍历两个链表。创建两个栈,第一个栈存储第一个链表的节点,第二个栈存储第二个链表的节点。每遍历到一个节点时,就将该节点入栈。两个链表都入栈结束后。则通过top判断栈顶的节点是否相等即可判断两个单链表是否相交。因为我们知道,若两个链表相交,则从
我正在尝试解决简单的任务,但我没有找到任何优雅的解决方案。 我基本上解决了两个圆形扇区的交集。每个扇区由(-pi, pi]范围内的2个角度(从atan2 func)给出。每个选择器占用的最大角度为179.999。所以每两个角度就可以知道圆形扇区的位置。 返回值应根据以下内容描述互交:
本文向大家介绍如何判断一个对象是否为空?相关面试题,主要包含被问及如何判断一个对象是否为空?时的应答技巧和注意事项,需要的朋友参考一下 可以使用 JSON.stringify() 方法判断 还有就是使用for in 遍历该对象 3.ES6 新增的方法 Object.keys(): Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组。 如果我们的对象为空,他会返回一个
本文向大家介绍如何判断对象是否死亡(两种方法)?相关面试题,主要包含被问及如何判断对象是否死亡(两种方法)?时的应答技巧和注意事项,需要的朋友参考一下 堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断那些对象已经死亡(即不能再被任何途径使用的对象)。 2.1 引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0
我试图找出两个矩形是否相互重叠。我将下面的矩形表示为< code>[x1,x2] x [y1,y2] 我只需要一个伪代码,我可以实现它来查找矩形是否彼此重叠。