轴对齐空间划分:将空间划分为随机矩形吗?


11

我需要一种将3d空间划分为随机轴对齐的盒子形状的方法。目前,我目前正在划分2d空间用于测试目的。我想到的最直接的方法是定义一个大小为(1,1)的矩形,然后将所有现有矩形递归地分成两个在X轴和Y轴之间交替的不平坦矩形。

在此处输入图片说明

这里的问题很明显。这种方法会导致拉伸线变长(以红色标记)

在此处输入图片说明

我想要的是更自然的外观(我提供了一个示例)

看,从上到下或从左到右没有长的直线。

在此处输入图片说明

唯一的限制是我可能希望限制矩形的最小大小,而不影响大小的粒度。也就是说,如果最小的rect是1平方厘米,而不是秒,则最小的房间不应是2平方单位。

因此,理想情况下,算法应满足以下三个约束:

  1. 矩形不是无限小。
  2. 矩形尺寸不是最小矩形尺寸的离散乘积。也就是说,如果最小的rect是3平方单位,则不将较大的rect约束为6、9、12等正方形单位,因此可以是3.2或4.7。
  3. 该算法以多项式时间运行(需要快速计算)。

Answers:


12

您概述的方法既简单又有用,但是会遇到如图所示的可怕缺陷。躲开它。您需要并行增长算法;对于单线程模型,遵循循环方法:

  1. 在地图空间中随机放置各个点。根据Voronoi图的Lloyd弛豫法,使用高斯分布或通过应用迭代弛豫算法将随机放置的点彼此远离,对它们的分布进行规范化(避免丑陋的聚类)。这些点代表您将要居住的房间的质心。
  2. (对所有房间并行/重复循环)从每个点开始,向外增长4个顶点(一个矩形房间),每次全局迭代从中心点开始移动(您可以在每个轴上以不同的速率生长不同的房间,而不是对于所有内容,然后看看结果如何-可能会带来更自然/更多样化的结果)。在某些时候,您的某些矩形将开始相互挤压。在那一点上,限制该轴的增长,确保两个房间的相邻边缘完全接触,然后继续前进。
  3. 重复步骤2,逐步增加每个房间,直到所有增长都受到相邻房间或地图边界的限制。
  4. 这仍然会留下一些空白。现在的问题变成了在无人居住的空间中定位和放置房间之一。实际上,如果您的基础空间是一个(整数索引)网格(并且每个增长迭代都捕捉到该网格),那么这将更容易处理,因为您可以维护已占用和未占用的网格单元的列表:已放置并扩大了所有房间,在空置列表中搜索由相邻单元格组成的离散空间。由于许多未使用的空间将具有非矩形的形状,因此您需要从该非矩形空间中随机选择一个像元,并将其增大到最大大小,就像在步骤2中对房间所做的那样。 -矩形空间,直到完全填满。
  5. 重复步骤4,直到地图被100%占用为止。

这是个好建议。缺点是,它可能无济于事,无法保护我免受无穷无尽的小骚扰。我需要某种方式来限制矩形的大小。目前,我正在研究另一种方法。我将比较结果并进行更新。
AturSams 2014年

@ArthurWulfWhite然后您的问题未指定,应该更新。您的最小房间大小取决于地图单元的分辨率;因此,如果您将粗粒度设置为足以容纳最小房间大小,则此后可以基于浮点调整轴,从而返回更自然的外观。
工程师

你是对的!我以为我写了那部分。但是我没有。对于这个错误,我深表歉意。是的,我知道网格的大小。房间只能小到网格允许的大小。
AturSams 2014年

好-希望您找到合适的解决方案。顺便说一句,我的意思是“调整网格线”,而不是“调整轴”。
工程师

1
实际上,根据您认为我的概念,我正在松散地执行完全一样的操作。我也将结果发布在这里。
AturSams 2014年

2

如您所见,我设法摆脱了这些工件。这个想法非常相似。

  1. 将2d空间划分为非均匀网格。如果两行距离太近,请移开其中一根。
  2. 随机选择一个矩形,检查是否已沿y轴(在高度上)修改了矩形,以及它的直接邻居是否已沿y轴进行了修改。我俩都没有被修改,让他们重新协商他们之间的细分(一个人会向另一个人捐赠一些空间)。
  3. 这次仅在另一根轴上执行与步骤2相同的操作。
  4. 重复该过程,直到您进行了尽可能多的修改。

非均匀网格(1):

在此处输入图片说明

在轴x(2)上协商:

在此处输入图片说明

协商y轴(3):

在此处输入图片说明

结果(4):

在此处输入图片说明

在此处输入图片说明


这是从@Nick Wiggill的见识中得到的宽松启发
AturSams 2014年

2
通过首先将n * m个相邻单元的组随机合并到单个矩形中,可以对此进行进一步改进。这将掩盖在上面的输出中仍然可见的基础网格。现在,必须使用这些较大的矩形进行协商,以处理其边缘之一上的所有单元。
DMGregory

好。仍然有很多共线边界,我会进一步研究,但是很高兴您找到了解决方案!很高兴为您提供帮助。
工程师

@DMGregory我考虑了这一点,但我希望小矩形和大矩形之间的比率一定程度上保持一致。如果这是一个纹理或一个关卡,我一定会做(实际上有一个以前的例子可以做到)。
AturSams 2014年

@NickWiggill我可以完全消除共线。只需调整算法即可。必须有一种进一步改进它的方法(使用最新的变体进行更新)
AturSams 2014年
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.