我正在搜索有关碰撞检测优化的信息。
有一个物体(圆圈)从点 a 移动到点 b 。该对象具有半径 r ,并且场中也存在许多障碍物(圆圈)。
我有一个算法(函数)来检查圆圈和胶囊之间的碰撞,我现在称这个函数为每个障碍物:
for-each (o : obstacles)
if collide(o, Capsule(a,b,r))
return true;
return false;
许多障碍物距离移动物体很远,可以通过碰撞检测功能进行检查。
我的问题是:
是否有解决方案忽略使用碰撞检测功能检查所有障碍物?像最近邻搜索或 KD树之类的东西?
编辑:所有障碍都有相同的半径。
答案 0 :(得分:4)
作为第一步,您可以忽略某些框架/框中没有出现的所有障碍。
E.g。所有具有y坐标的障碍物(障碍物形状的y-最低点)大于a和b的最大y坐标+可以忽略移动物体半径的相同距离。类似于较低的y边界和x边界。 而不是一个盒子,你可以进一步分支成两个(更多)盒子。例如,购买将a-b的距离分成两个距离并对(a,(b-a)/ 2),/(b-a)/ 2,b)中的每一个进行上述过程。
但这一切都取决于与碰撞程序相比,这些值的比较效率。
答案 1 :(得分:2)
您可以简单地使用网格,其中每个单元格容纳触及该单元格的所有障碍物。现在只检查胶囊接触的碰撞细胞。 此外,您也可以使用四叉树,但根据我的经验,网格通常足够,并且还具有在障碍物移动时可以轻松快速更新的优势。
答案 2 :(得分:2)
评论马丁的回答:
我创建了一个类似Box(a.x-R, a.y-R, b.x+R, b.y+R)
的框,其中R
为ObjectRadius + ObstacleRadius
,然后删除不在此框内的每个障碍。在图中,只会检查带有黄点的障碍物:
答案 3 :(得分:1)
我可以推荐怪物曲线,例如希尔伯特曲线。它是像数据结构一样的四叉树或kd树,它将2d复杂度降低到1d问题。在每个帧中,您可以从开始构建怪物曲线,这样可以删除或插入四叉树或kd树。它还有一些更好的2d平铺属性,但在您的情况下可能不需要。
答案 4 :(得分:0)
答案 5 :(得分:0)
您可以尝试在代码中实现空间分区。通过将每个对象/障碍物划分为覆盖整个空间或地图的每个框。通过这样做,您可以将障碍分为几个部分。因此,只需检查一小部分内的碰撞,就可以大量减少碰撞检查。如果您的障碍物没有移动,您只需要为每个障碍物进行一次此分区。如果它们正在移动,则必须每次更新每个障碍物的分区[重新组合]。
空间分区技术已经有很长一段时间了,这里有一个链接可以帮助你实现。