【发布时间】:2010-08-03 15:17:44
【问题描述】:
问题
我想将网格(二维数组)划分为随机形状的部分(想想earth's tectonic plates)。
标准是:
- 用户输入网格大小(程序应该缩放,因为这可能非常大)。
- 用户输入网格划分系数(多少部分)。
- 网格是一个矩形六角网格,顶部和底部都加盖,左右环绕。
- 部件没有碎片。
- 其他部件中没有部件。
- 没有微小或超大的部件。
- 形状随机的零件,不是完美的圆形,也不是串成的蛇形。
我的解决方案:
- 创建一个可以访问/操作相邻单元格的方法。
- 随机确定每个部分的大小(所有部分的总和等于整个二维数组的大小)。
- 用最后一部分的 id 号填充整个二维数组。
- 对于除最后一个以外的每个部分:
- 在二维数组的随机单元格中播种当前零件 ID 号。
- 遍历整个数组并存储每个单元格的地址,这些单元格与已使用当前部件 ID 号播种的任何单元格相邻。
- 提取其中一个存储的地址并用当前的车牌 ID 号填充该单元格(因此该部分开始形成)。
- 重复直到达到零件尺寸。
请注意,为了避免零件内部带有长“臂”或大孔,我创建了两个存储阵列:一个用于相邻的单元格 到只有一个具有当前零件 ID 号的单元格,另一个用于与多个相邻的单元格,然后我在前者之前耗尽后者。
运行我的解决方案会得到以下结果:
网格大小:200
宽度:20
身高:10
零件:7
66633333111114444466
00033331111114444466
00003331111114444466
00003331111144444660
00000333111164444660
00000336111664422600
00000336615522222200
00006655555522222200
00006655555552222220
00066655555552222220
部件号:0
零件尺寸:47
部件号:1
零件尺寸:30
部件号:2
零件尺寸:26
部件号:3
零件尺寸:22
部件号:4
零件尺寸:26
部件号:5
零件尺寸:22
部件号:6
零件尺寸:27
我的解决方案存在问题:
- 最后一部分总是零散的——在上面的例子中,有三个不同的六组。
- 当零件在死胡同中形成并且没有空间增长到完整尺寸时,该算法将停止(该算法不允许在其他零件上形成零件,除非它是最后一个零件,已放下在开始时覆盖整个二维数组)。
- 如果我在形成 2d 数组之前没有指定零件尺寸,而只是指定零件数量并动态随机生成零件尺寸,这就留下了形成微小零件的可能性,即还不如根本不存在,尤其是当二维数组非常大时。我当前的零件尺寸方法将零件尺寸限制在二维数组总尺寸的 10% 到 40% 之间。如果有一些超级优雅的方法可以做到这一点,我可以不指定零件尺寸 - 用户将拥有的唯一控制是二维数组大小和零件数量。
其他想法:
- 将零件形成完美对齐的正方形,然后在 2D 阵列上运行并随机让每个零件侵占其他零件,将它们扭曲成随机形状。
- 在网格上绘制蛇形线并填充创建的空间,可能使用如下数学运算:http://mathworld.wolfram.com/PlaneDivisionbyLines.html
结论:
所以问题来了:我是一个初学者程序员,不确定我是否以正确的方式解决了这个问题。我可以创建一些更多的“修补”方法,将零散的部分转移到一起,并允许成型部分在卡在死胡同的情况下“跳出”,但感觉很混乱。
您将如何解决这个问题?有没有一些我可以用来简化事情的性感数学?
谢谢
【问题讨论】:
-
为什么不从
axb大小为1的部分开始,随机加入相邻的部分呢?是否有一些标准零件必须满足? -
我没有想到这一点,最近几天一直在试验你的方法。它自然避免了零件的碎片化,但不会像我的那样在其他零件内部形成零件。你的方法最简单的形式总是会产生一个超大的部分,其余的会很小。按摩以获得你想要的东西似乎并不比我的解决方案更容易。我在我的问题帖子中添加了对我的标准的更清晰的解释。
标签: algorithm language-agnostic grid computational-geometry multidimensional-array