【问题标题】:Random Tile layout随机平铺布局
【发布时间】:2011-03-08 03:18:40
【问题描述】:

我需要将瓷砖放置在一个从中心点向外辐射的大网格上,以一种看起来有机且随机的方式。新瓷砖需要在网格上找到至少接触 1 个其他瓷砖的开放空间。

谁能指出我正确的方向,以帮助解决此问题? 或者我可以阅读的一些基本概念与此有关?

例如,在这张图片中,已经创建了一个形状(黄色),我可能正在接收一个新的瓷砖,它可能是 1x1、2x2 或 3x3。试图找到一种好方法来确定我可以放置新图块的位置,以便它接触到最大数量的当前图块。

图片: alt text http://osomer.com/grid.JPG

【问题讨论】:

  • 这些都是相同的图块,您希望它们创建的形状是有机的和随机的,还是您有一堆可以连接的图块并希望生成的正方形看起来有机和随机?
  • 你能提供任何图像或草图来说明你的意思吗?目前尚不清楚您正在考虑的网格是笛卡尔还是极坐标。或者它应该是多么有机和随机。您是否尝试过按照您描述的方式放置图块,怎么会失败?
  • 添加了图片和更多描述。我的图块通常是图像中的一个正方形,但将来可能是 2x2 或 3x3 或更大。
  • 对不起,你说你从一个已经创建的黄色形状开始。但是整套瓷砖看起来是黄色的。你能以某种方式指出原始形状和随后的瓷砖吗?
  • 理论上,黄色物体表示随机平铺放置的结果。它从中间的一个瓦片开始,一次连接一个瓦片创建。黄色对象周围的空白区域是新瓷砖的空间。我正在尝试找出找到这些空间的最佳方法。

标签: algorithm math layout grid tiles


【解决方案1】:

或者,您可以解决这个问题,因为黄色瓷砖“侵蚀”在蓝色/背景上。要做到这一点,在每一步,让黄色瓷砖在基本方向上与其相邻的所有背景瓷砖的“侵蚀总和”E上添加一个固定数字(也许是其中的一小部分)到对角线相邻的背景图块)。

然后,当需要放置新图块时,您可以为每个背景图块选择一个从 0 到 E 的随机数;最伟大的被“侵蚀”掉了。或者,您可以做一个简单的加权随机选择,E 是它们的权重。

对于 2x2 或 3x3 瓷砖,您只能从适合“适合”其中的 2x2 或 3x3 正方形的瓷砖中挑选(即,2x2 或 3x3 边缘的侵蚀瓷砖,以免造成重叠与已经放置的瓷砖)。但实际上,您永远不会得到像逐个侵蚀/瓷砖放置那样自然的东西。

您可以通过让它们在每次迭代中持续存在来节省重新计算侵蚀总和的时间,只有当您添加一个新图块时,才会将其周围的侵蚀总和向上计算(简单的+=)。在这一点上,它与建议的另一个答案基本相同,尽管具有不同的观点/哲学。

侵蚀和E的样本网格,直接基数邻居为+4,对角邻居为+1:

Erosion Sums http://img199.imageshack.us/img199/4766/erosion.png

E较高的最有可能被“侵蚀”掉;例如,在这一个中,西面和南面的两个小入口最有可能被黄色侵蚀掉,其次是北面和东面的较小海湾。最不可能的是那些几乎没有碰到黄色的角落。您可以通过为每个图块分配一个从 0 到 E 的随机数并侵蚀具有最高随机数的一个,或者进行简单的加权随机选择,或者通过您的任何决定方法来决定哪一个选择。

【讨论】:

  • 很好的解决方案,虽然这句话:“从 0 到 E 中选择一个随机数;最大的一个被“侵蚀”掉”似乎没有任何意义。 “E”值不必是唯一的或连续的,所以我看不出这种选择方法是如何工作的。
  • @Nick -- 来自前面的子句:for each background tile -- 也就是说,如果你有四个 E 值 [1,5,3,2] 的图块,rand() 是一个函数返回一个从 0 到 1 的随机、均匀分布的有理数,你会找到 [rand()*1,rand()*5,rand()*3,rand()*2],然后从中选出最大值。
  • 啊。不过,这基本上就是您继续描述的加权随机选择,只是每个选择需要更多的随机数。
  • 我确实相信这两种方法之间存在细微差别,但如果您要进行优化,那么是的,加权随机选择绝对是最好的。我可以看到前一种方法很有用,或者例如,如果您希望随着黄色瓷砖的增加而增加侵蚀率 - 而不是只选择顶部进行侵蚀,当且仅当随机数达到时才会发生所有侵蚀一定的门槛。
【解决方案2】:

对于纯随机,您从一个空网格和一个“候选”列表(也是空的)开始。

将第一个图块放在网格的中心,然后将每个相邻的图块添加到您刚刚放入“候选”列表的图块中。然后,每回合,在“候选”列表中选择一个随机条目并在那里放置一个图块。查看您刚刚放置瓷砖的位置旁边的每个相邻网格位置,对于每个也是空的网格位置,下次将其放在“候选”列表中(如果还没有的话)。

为避免在您的图块网格中创建孔洞,请根据已填充的相邻图块的数量增加选择网格位置的概率(因此,如果只有一个相邻图块已填充,则可能性较低。如果它们'都填满了,概率很大)。

在伪代码中:

grid = new array[width,height];
candidates = new list();

function place_tile(x,y) {
   // place the tile at the given location
   grid[x,y] = 1;

   // loop through all the adjacent grid locations around the one
   // we just placed
   for(y1 = y - 1; y1 < y + 1; y1++) {
       for(x1 = x - 1; x1 < x + 1; x1++) {
           // if this location doesn't have a tile and isn't already in
           // the candidate list, add it
           if (grid[x,y] != 1 && !candidates.contains(x1,y1)) {
               candidates.add(x1,y1);
           }
       }
   }
}

// place the first tile in the centre
place_tile(width/2, height/2);

while (!finished) {
   // choose a random tile from the candidate list
   int index = rand(0, candidates.length - 1);

   // place a tile at that location (remove the entry from
   // the candidate list)
   x, y = candidates[index];
   candidates.remove(index);
   place_tile(x, y);
}

【讨论】:

  • 哇,这看起来很棒。我要试试这个,看看我能不能让它工作。逻辑似乎是合理的。
  • 我在看到您对 2x2 和 3x3 瓷砖的编辑之前写了这篇文章,但我相信这可以重新考虑到这一点。您可能需要稍微扩展“候选”结构以考虑瓷砖的额外尺寸......
【解决方案3】:

您的问题的问题是“有机和随机”可以是许多不同的东西。 让我显示两个链接

  • 生成random fractal terrain(查看“多云天空”部分并想象您将其转换为黑白,或者在您的情况下为黄色/背景)。
  • 模拟erosion(看'erode'下的图片)

上述两个样本对我来说是“有机的和随机的”,但您可能对这些样本不满意。所以,我认为你必须更好地定义什么是“有机和随机”。

现在,我将采用您对添加新图块的指导规则的定义(但不要认为这一定是同一个问题),我将其解读为:

给定两个形状(假设是位图) 找到相对位置 形状使得数量 接触边是最大的

我也会假设

  • 不允许重叠
  • 您可以在生成的合并形状内留下孔
  • 您可以不旋转形状

在这种情况下,您需要测试的解决方案少于 xy 个解决方案,并且在每个解决方案中您都需要 - 如果有重叠则丢弃它 - 如果他们不接触就丢弃它 - 如果他们接触,那么计算共同的边数 上述所有三个测试都可以通过扫描所有黄色瓷砖(数量为konstx*y)在恒定时间内完成

那么,以上可以在 O(n^4) 内轻松完成,对你来说足够了吗?

【讨论】:

    【解决方案4】:

    计算对偶图的随机生成树,即以单元格中心为顶点的网格。为此,从网格的中心开始并进行随机深度优先搜索。然后绘制单元格以增加树距中心的距离。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-16
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多