随机图生成-散布/聚类随机节点的策略


10

我正在太空中做一个简单的4X策略游戏,其中每个节点都是一个兴趣点(行星,小行星等)。

要随机生成地图,请按照以下步骤操作

  1. 确定地图每个节点的类型(例如,可能有5个类似地球的行星,10个贫瘠的行星等)

  2. 将每种类型的节点放置在地图上。

对于第2步,我希望每种节点类型的分布均匀。因此,例如,我将从放置所有类似地球的行星开始。如果我简单地做一个rand(map.width,map.height)来确定位置,我可能最终会把所有类地球的行星聚在一起,这将使从该区域开始的玩家受益。

是否有任何方法(例如使用不同的图形函数或噪声函数)可以生成彼此分散的(x,y)坐标序列。同样,有什么方法可以生成彼此接近的坐标?


1
不论是我的还是别人的,都请标记为已接受。谢谢。
工程师

Answers:


8

您面临的问题是随机选择不能区分,这可能意味着它不适合您的需要。但是,至少有一种简单的方法可以解决此问题:

  1. 将您的空间分成多个扇区(例如,如果您有一个100乘100的区域,并且您需要生成100个此类太阳系,然后将您的区域分成一个10乘10的扇区网格)

  2. 遍历每个扇区并重复步骤3(依次重复执行步骤4)

  3. 随机确定当前扇区中当前太阳系的行星数(例如,对于3到7个行星,仅获取0到4的随机数,然后加3)(如果您有多个太阳系)部门中的系统,这是您设置另一个循环的地方)

  4. 在回路确定的当前太阳系内随机分配行星(您也可以使用随机数来增加行星之间的最小距离);在这里,您可以决定行星的类型,也可以使用各种权重或您喜欢使用的任何方法来随机确定行星的类型。

您可能还希望在每个扇形的边缘周围定义一个“边界”区域,以防止相邻扇形的行星彼此直接接触(以防万一,它们实际上有效地并排放置)。 ..

另一个解决方案可能是确定每个太阳系和/或每个行星的位置,以便对相邻扇区进行快速接近检查并相应地进行调整(例如,从边缘移开最小距离加随机距离) )。


别客气!+1以发布有关解决您的问题的后续信息。=)
兰道夫·理查森

8

确保均匀分布的最佳方法是将每个节点视为一种物理粒子。首先在连续(浮点)xy平面上随机分布。通过在平面上每对不同的单独粒子对之间施加排斥力,您会发现它们逐渐散开。从某种意义上说,这就像是解决冲突,只有没有实际的联系可以说。然后,将平面转换(栅格化)为整数索引的网格就很简单了。您可以从整数索引的网格开始就可以简单地做到这一点,但是让事情变得“好”可能会有点困难-这取决于网格的分辨率有多高...越高越好, 在这种情况下。

显然,您可能还希望从正方形平面的边缘施加某种力,否则,您可能会发现很多粒子“在岸上冲刷”。另外,您可以创建一个比您需要的字段大得多的字段,然后对该字段的一小部分进行快照-这样可以避免上述问题。

当您想确定相反的情况(即确实发生聚类)时,请查看“标准”或“高斯”分布。这就是为什么随机生成的星空通常看起来是假的。他们使用纯随机分布而不是更自然的分布模型。


1
您还可以从“物理”模型中获得聚类行为,您只需要使用其他规则集,就可以使用吸引和排斥的组合。选项是无止境的,所有要做的就是找到正确的模型。
aaaaaaaaaaaaaa

6

您可以使用简单的泊松磁盘分布算法来获得“蓝噪声”分布。这导致平面中的点彼此之间大致相等地间隔开。这不仅适用于您的2D实例,而且也适用于3D以及非欧几里得空间,但计算很快就会变得笨拙。

这些算法的基本思想是,您从第一个“种子”点开始,然后向外进行工作,在您希望从该点开始的最大和最小距离之间的环空中添加随机或伪随机点,然后消除彼此靠近的人。然后,您的算法将以这种方式向外工作,直到添加了所需的点数(这将为您提供大致的圆形点云)或填充了可用空间为止。

大学的Daniel Dunbar和Greg Humphreys 在“ 快速泊松磁盘样本生成的空间数据结构 ”中可以找到用于生成2D这样的噪声的快速而优雅的替代算法,以及对其性质的简短讨论。弗吉尼亚州。


2
从未听说过泊松磁盘分布-很好的链接!
tenpn 2011年
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.