查看两个体素是否互连的算法


11

我正在寻找以下问题的良好算法:给定3D体素网格(可能为空或填充),如果我选择两个不相邻的体素,我想知道它们是否通过以下方式相互连接其他体素。

例如(为了说明2D的情况),其中#是实心正方形:

  1 2 3
a # # #
b # #
c # # #

如果我选择a3和c3,我想尽快确定它们是否已连接;如果在a3和c3之间存在通过填充像素的路径。(当然,实际情况是在3D体素网格中。)

我已经研究了泛洪算法和路径查找算法,但不确定如何选择。两者都执行不必要的工作:洪水填充会尝试填充所有体素,但这不是必需的。寻路算法通常与寻找最短路径有关,这也是不必要的。我只需要知道,如果有一个路径。

我应该使用什么算法?

编辑:根据评论,我认为应该添加以下内容:体素的内容事先未知,并且还需要算法来检测是否删除(清空)体素是否会导致该组体素破裂分成两个或更多个较小的组。


在您的例子是从A3到C3的有效路径如下所示:c3->c2->b2->a2->a3

这是正确的
布拉姆Vaessen

Answers:


12

A *可以正常工作。查找路径是您想要的,查找最短路径与查找任何路径一样快(或更快)。在这种情况下,考虑到起点和终点,A *可能是最合适的。这意味着您具有增加的试探性以加快搜索速度。

使用A *通常,您找到的第一个路径是最短的,因此在找到路径之后,它不会做额外的工作。

在此处输入图片说明

对于某些优化,请在此处查看我的答案


看起来好像真的向前射击,直到撞到那堵墙然后有点爬行
GameDev-er

1
@ GameDev-er是的,这是因为启发式。如果没有障碍,搜索将非常快,几乎是一条直线。
MichaelHouse

通过对节点进行更好的排序,这将首先扩展最接近最终节点的路径。如果您具有用于排序节点的快速数据结构,请按照最直接路径到目标的距离对它们进行排序。
MichaelHouse

9

如果您准备进行一些预处理并降低了存储成本,那么在构建时将体素划分为关联的组,就可以很明显地回答“是否有路径”。如果两个体素属于同一组,则它们之间存在一条路径。显然,问题在于您必须将组信息存储在某个地方,这取决于您的数据布局。如果要存储一个简单列表,则可以将其分为多个列表,每个与空间相关的组一个。如果您正在组织某种BVH,那么您可以说“此节点及以下节点中的所有体素都属于组X”,则可能会获得相当不错的效率。

或者,您可以进行一些空间预分割,并为每个连接的组存储一些较小的“集线器”体素集。然后,您可以从源体素和目标体素到其最近的中心体素进行路径查找,这对于计算路径而言应该更短/更便宜。如果找到从体素到中心体素的路径,则该体素是中心体素组的一部分。通过明智地选择这些集线器体素,可以最大程度地减少路径遍历的次数。例如,一个球体的中心可能只有一个中心体素,但是一个细长的组可能会沿着其长度每X个体素都有一个中心体素。如果您的源体素和目标体素位于长度的两端,那么它们最多只需要走X个体素即可找到中心,即使长度的起点和末端之间可能有大量的体素,

这完全取决于体素组的病理状况:如果您期望数量众多的小型断开连接的组,则存储成本的增长将大大超过仅寻路的性能影响。如果您希望连接的组相对较少,但是拓扑结构比较奇怪,那么幼稚的寻路可能会非常昂贵,而存储成本和最小化的寻路则是便宜得多的选择。


1
这是正确的答案,但是为了有效地实现它,不应将其存储为列表。向指向其“代表性体素”的每个体素添加一个指针,您可以使用联合查找算法设置该指针。这是每个体素的恒定存储成本,并且对于计算成本而言,边缘数量基本上是线性的。
Neil G

有趣的想法,但有两件事可能会使情况复杂化。首先是体素网格的内容是未知的,因此,要制作中心体素,我还需要一种算法,该算法可以确定哪些体素应该是中心体。
Bram Vaessen

1
第二个问题是,在删除一个体素后立即需要该算法,以确定由于该体素的删除而将其所属的组是否分成较小的组。
Bram Vaessen 2013年

@BramVaessen如果您正在寻找所有成对的互连关系-尤其是各个组是否“分手”-那么这与简单的可达性有所不同(尽管可达性是最简单的方法);我鼓励您添加更多有关您对原始问题的追求的详细信息,因为这可能会为“问题背后的问题”提供更好的答案。
Steven Stadnicki

要保持干净,我也问过我最初的问题,在不同的问题在这里gamedev.stackexchange.com/questions/50953/...
布拉姆Vaessen

4

我对体素不是很熟悉,但是我可以想象,通过使用诸如A *之类的最佳优先搜索算法,您可以获得相当不错的性能。在这种情况下使用A *的问题在于,通常会使用的启发式设计旨在优先考虑最短路径,而不仅仅是尽快找到“任何路径”。

使用备用启发式方法可能会有些运气,它会扩展较少的节点,例如

f(p)= g(p)+ w(p)* h(p)

其中w> = 1.越接近目标,则减小'w'的值,从而越接近目标像素,路径成本'g'的优先级越高。

我希望这有帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.