程序…带房间发生器的房子


74

我一直在看一些有关程序化生成地牢的算法和文章。问题是,我正在尝试建造一间带房间的房子,而这些房间似乎不符合我的要求。

首先,地牢有走廊,房屋有大厅。虽然最初看起来似乎一样,但大厅不过是不是房间的区域,而走廊是专门设计用来将一个区域连接到另一个区域的。

房屋的另一个重要区别是,您必须具有特定的宽度和高度,并且必须用房间和大厅填充整个物件,而使用地牢则要有空白空间。

我认为房子的大厅介于地牢走廊(可带您进入其他房间)和地牢中的空白空间(未在代码中明确定义)之间。

更具体地说,要求是:

  • 有一组预定义的房间,
    我无法即时创建墙壁和门。
  • 房间可以旋转但不能调整大小
    ,因为我有一组预定义的房间,所以我只能旋转它们,不能调整它们的大小。
  • 房屋尺寸已设定,必须完全填充房间(或大厅),
    即我想用可用的房间填充14x20的房屋,以确保没有可用空间。

以下是一些图片,可以使它更加清晰:

典型的地牢生成器 没有走廊的地牢 房屋发电机结果

如您所见,在房子里,“空空间”仍然是可步行的,它将您从一个房间转移到另一个房间。

因此,说了这么多之后,也许一所房子只是一个真正非常紧凑且带有走廊的地牢。还是比地牢更简单。也许那里有东西,但我还没有找到,因为我真的不知道要搜索什么。

这就是我希望得到您帮助的地方:您能否给我一些有关如何设计此算法的指导?关于将采取什么步骤有什么想法?如果您创建了地下城生成器,您将如何修改它以满足我的要求?您可以根据需要特定或通用。确实,我正在寻找您的大脑。


2
一个奇怪的建议:我强烈建议阅读克里斯托弗·亚历山大(Christopher Alexander)的著作《永恒的建筑模式语言》,这些建筑书籍为(软件)模式的概念奠定了基础。它们本质上描述了一种用于建筑物和居住空间的显式语言,可以转换为自上而下的程序构建方法。
史蒂文·斯塔德尼克

就个人而言,我会尝试制定类似于egarcias的答案的算法。首先生成房间占位符(可以填充不同数量房间的大区域。每个房间占位符之间必须有一个特定的(或带有下界的随机)大小间隙。“空白”空间就是考虑走廊即空间是在家里而不是在一个房间里,房间的地方持有人通过类似的“地下城与无走廊”例如随机大小的房间充满。
本杰明·约翰逊的危险

@pek请为您的解决方案创建一个答案,不要放在问题中。
MichaelHouse

@ Byte56完成。明确地说,我这样做是因为我不想得到别人的认可,因为我只做了别人建议的事情。我知道为什么这对网站的格式不理想,所以我添加了答案。
pek

谢谢@pek。不用担心获得信誉,这是当之无愧的,它对于来站点查看解决方案的人很有用(并在期望的最佳位置看到它)。
MichaelHouse

Answers:


50

我认为这对于使用二进制或三进制空间分区都是很好的情况。

初次使用时,请将房屋空间分为大厅和{房间块}。获取下一个大块,将其分成{hall and chunk}或{2个大块和它们之间的Hall}。在每个步骤中,将切片方向旋转90度。当{没有剩余的大块}或{大厅总面积达到限制}时停止。

在第二遍,将剩余的块分割成多个房间。获取下一个大块并将其拆分。跳过随机拆分一些不太大的块,以获得一些大房间。

如果任何大厅都面对更旧的大厅,请将墙壁(或带门的墙壁)放在那里。

将房间与大厅直接相连,或通过其他已经相连的房间相连。

例如,您可以看到我手工制作的结果或类似C ++的部分完成的伪代码。最终镜头:

最后一枪


那就是我的研究结果的结果,即空间划分。您的代码示例给了我一个非常非常好的开始。我目前正在阅读算法。但是有一个问题:我的要求之一是房间是预定义的(即有2x2个房间带一扇门,1x1有两个门,但没有2x2带三个门),所以我无法开始分区,然后决定将门放置在何处。我想在分区时必须牢记我的限制。您对我的建议有什么建议吗?无论如何,非常感谢您的回答和努力!
pek

@pek我不确定凡人能否找到解决这个问题的学术方法。您可以尝试为块拆分器和框拆分器设置其他条件,然后生成和删除级别,直到找到可以满足所有条件的级别。
雨中的阴影2013年

是的,我希望自己缺少一些东西。我的第一种方法是使用A *找出如何在给定的空间中布置房间,但是大厅缺乏逻辑。现在,我正在考虑可以使用BSP放置大厅,然后将A *应用于街区。我最担心的是,它可能太昂贵了,而且并不总能产生结果。但我必须先对此进行测试。也许不会那么糟糕?
pek

2
@pek如果您仍然感兴趣,我发现了一些有用的东西。看看这个,还有谷歌L-system
雨中的阴影2013年

24

您可以充分利用您期望的设计将房间集中在被走廊环绕的矩形房间中的事实。考虑到这一点,我会这样做:

  1. 设计房间的走廊和“大空间”
  2. 在房间中填充每个“大空间”

2步

如果从边界处的房间开始,则可以很容易地用房间填充较大的空间-它们有特定的限制,例如,面向走廊的房间可以在该墙上有门,但是面向“外墙”的房间不能(他们可能有窗户)。大房间“内部”的房间至少需要一个入口。


15

因此,这就是我解决此问题的方法。但是首先,我要感谢@Shadows In Rain和@egarcia的回答。他们给了我一个很好的指导,帮助我取得了一些成果。

我使用了Shadows In Rain的空间划分来生成基本的房屋,然后按照egarcia的建议在房间中填充房间。

空间划分非常简单,因为90%的代码是由Shadows完成的。“填充房间”部分更具挑战性。我决定使用伪人工智能计划系统,该系统使用A *适当地放置房间。使用计划而不是仅使用A *的好处是,前提条件有助于大大减少搜索空间。

以下是一些结果截图:

平面图生成阶段 平面图生成阶段

房间布置阶段 房间布置阶段

现在有了连接门!
现在有了连接门!


11

达尔和林德(Dahl&Rinde)撰写了一篇有关“室内环境的程序生成”的论文,该论文使用骨架和区域方法在建筑物内部填充房间和走廊。本文包括其原型的类图。他们的书目中也有一些很好的参考,包括前面提到的A Pattern Language

他们的工作是围绕以下简化的假设进行设计的:

  • 只处理公寓楼
  • 没有拆分级别
  • 限制建筑物的形状(信封)必须为多边形
  • 信封上没有孔
  • 信封厚度相似或线性变化(即没有沙漏形状)
  • 只处理需要走廊的建筑物

以下是他们的流程的简要概述:

  • 找到信封的骨架。然后根据与信封之间的距离,与门或楼梯的距离以及与先前放置的走廊的距离,沿着骨骼放置走廊。
  • 接下来,将剩余的非走廊空间划分为最大的连接区域,每个区域具有单个连续边界。在某些情况下,这需要插入墙壁。
  • 然后将这些区域划分为多个公寓,尝试为每个公寓分配至少一个窗口。在某些情况下,较小的部门将合并以避免过多的小公寓。没有窗口的区域将被忽略。
  • 最后,使用加权Voronoi类图作为基础将公寓划分为多个房间,如下所示:

    • 种子重量用于影响房间的大小。种子被添加在门窗上。添加额外的种子,通常每个所需房间添加一个;虽然没有明确说明,但似乎种子是沿着公寓的外墙放置的。
    • 从最远的点开始,计算给定种子与所有其他点之间的一条线,然后将其相对于端点的权重一分为二(如果A和B的权重为1和4,则为EG,等分点为从A到B的1/4)。等分线的集合与外壁一起形成种子的细胞。
    • 接下来,通过用垂直于相邻对外墙特征(窗户或门)之间的中点的直线划分区域来创建S空间墙骨架(根据Peponis等人,1997年)。
    • 最后,从“尽可能与Voronoi细胞壁对应”的S空间骨架中选择壁。

3
可以包括图片吗?那很好啊。我对纸张进行了略读,并且从建筑POV看它们生成的房间看起来不错。
2013年

这是一种非常有趣的方法,我将不得不自己仔细研究一下它可能会摆脱的任何想法。
Draco18s 2015年

我来这里是为了放松工作……令我惊讶的是研究课题出来了。我懒得根据自己的研究来写答案(我还只是设计了算法的基本知识,所以还是不值得的)或描述Danil Nagy解决该问题的方法,所以我就在这里autodeskresearch.com/publications/...
费利佩·古铁雷斯
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.