简体   繁体   English

用于碰撞检测的O(n ^ log n)算法

[英]O(n^log n) algorithm for collision detection

I'm building a game engine and I was wondering: are there any algorithms out there for Collision Detection that have time complexity of O(N^log N)? 我正在构建一个游戏引擎,我想知道:是否有任何算法用于碰撞检测,其时间复杂度为O(N ^ log N)?

I haven't written any coding yet, but I can only think of a O(N^2) algorithm (ie: 2 for-loops looping through a list of object to see if there's collision). 我还没有编写任何编码,但我只能想到一个O(N ^ 2)算法(即:2个for循环遍历对象列表以查看是否存在冲突)。

Any advice and help will be appreciated. 任何建议和帮助将不胜感激。

Thanks 谢谢

Spatial partitioning can create O(n log(n)) solutions. 空间分区可以创建O(n log(n))解决方案。 Depending on the exact structure and nature of your objects, you'll want a different spatial partitioning algorithm, but the most common are octrees and BSP. 根据对象的确切结构和性质,您需要不同的空间分区算法,但最常见的是八叉树和BSP。

Basically, the idea of spatial partitioning is to group objects by the space they occupy. 基本上,空间分区的想法是通过它们占据的空间对对象进行分组。 An object in node Y can never collide with an object in node X (unless X is a subnode of Y or vice versa). 节点Y中的对象永远不会与节点X中的对象发生碰撞(除非X是Y的子节点,反之亦然)。 Then you partition the objects by which go in which nodes. 然后,您可以对通过哪些节点的对象进行分区。 I implemented an octree myself. 我自己实现了一个八叉树。

You can minimize the number of checks by sorting the objects into areas of space. 您可以通过将对象排序到空间区域来最小化检查次数。 ( There is no point in checking for a collision between an object near 0,0 and one near 1000,1000 ) (检查0,0附近的物体与1000,1000附近的物体之间的碰撞没有意义)

The obvious solution would be to succesively divide your space in half and use a tree ( BSP ) structure. 显而易见的解决方案是将您的空间成功地分成两半并使用树( BSP )结构。 Although this works best for sparse clouds of objects, otherwise you spend all the time checking if an object near a boundary hits an object just on the other side of the boundary 虽然这最适合稀疏的物体云,否则你会花费所有时间来检查边界附近的物体是否碰到了边界另一侧的物体

I assume you have a restricted interaction length, ie when two objects are a certain distance, there is no more interaction. 我假设你有一个受限制的交互长度,即当两个对象是一定距离时,没有更多的交互。 If that is so, you normally would divide your space into domains of appropriate size (eg interaction length in each direction). 如果是这样,您通常会将您的空间划分为适当大小的域(例如,每个方向的交互长度)。 Now, for applying the interaction to a particle, all you need to do is go through its own domain and the nearest neighbor domains, because all other particles are guaranteed further away than the interaction length is. 现在,为了将交互应用于粒子,您需要做的就是通过自己的域和最近的相邻域,因为所有其他粒子都保证比交互长度更远。 Of course, you must check at particle updates whether any domain boundary is crossed, and adjust the domain membership accordingly. 当然,您必须检查粒子更新是否跨越任何域边界,并相应地调整域成员身份。 This extra bookkeeping is no problem, considering the enormous performance improvement due to the lowered interacting pair count. 考虑到由于交互对数减少导致的巨大性能提升,这种额外的簿记是没有问题的。 For more tricks I suggest a scientific book about numerical N-Body-Simulation. 对于更多技巧,我建议一本关于数值N-Body-Simulation的科学书籍。

Of course each domain has its own list of particles that are in that domain. 当然,每个域都有自己的域中的粒子列表。 There's no use having a central list of particles in the simulation and going through all entries to check on each one whether it's in the current or the neighboring domains. 在模拟中有一个中心的粒子列表是没有用的,并且通过所有条目来检查每个粒子是在当前域还是相邻域中。

I'm using oct-tree for positions in 3D, which can be quite in-homogeneously distributed. 我正在将oct-tree用于3D中的位置,这可能是非常均匀分布的。 The tree (re-)build is usually quite fast, bot O(N log(N)). 树(重新)构建通常非常快,机器人O(N log(N))。 Then finding all collisions for a given particle can be done in O(K) with K the number of collisions per particle, in particular there is no factor log(N). 然后找到给定粒子的所有碰撞可以在O(K)中完成,其中K是每个粒子的碰撞次数,特别是没有因子log(N)。 So, to find all collisions then need O(K*N), after the tree build. 因此,要在树构建之后找到所有碰撞,则需要O(K * N)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM