问题
我想将一个网格(2D数组)分成随机形状的部分(类似于地球的构造板块)。
标准如下:
- 用户输入网格大小(程序应该进行缩放,因为这可能非常大)。
- 用户输入网格划分系数(有多少部分)。
- 网格是一个矩形六边形网格,并且在顶部和底部被封口,在左右两侧包裹。
- 不能分裂零件。
- 没有零件在其他零件内部。
- 没有小型或超大型零件。
- 随机形状的部分,不是完美的圆形或细长的蛇形。
我的解决方案:
- 创建一个可以访问/操作相邻单元格的方法。
- 随机确定每个部分的大小(所有部分的总和等于整个二维数组的大小)。
- 用最后一个部分的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数组)。
- 如果我在形成2D数组之前不指定部件大小,而只是指定部件数量并在生成部件大小时随机生成,那么这会留下形成微小部件的可能性,这些部件可能根本不存在,特别是当2D数组非常大时。 我目前的部件大小方法将部件大小限制在2D数组总大小的10%至40%之间。 如果有一种超级优雅的方法可以做到这一点,我也许可以不指定部件大小 - 用户唯一的控制是2D数组大小和部件数量。
其他想法:
- 将零件组成完美对齐的正方形,然后在2D数组上运行,并随机允许每个零件侵入其他零件,将它们扭曲成随机形状。
- 在网格上绘制蛇形线条,并填充所创建的空间,可能使用一些数学方法,例如:http://mathworld.wolfram.com/PlaneDivisionbyLines.html
结论:
所以问题来了:我是一个初学者程序员,不确定我是否以正确的方式解决了这个问题。我可以创建一些更多的“修补”方法,将分散的部分移动到一起,并允许正在形成的部分“跳出”死胡同,如果它们被困在其中,但感觉很混乱。
你会如何解决这个问题?也许有一些性感的数学方法可以简化事情吗?
谢谢
axb
部分开始随机连接相邻部分?这些部分是否有满足的某些标准? - Mladen Jablanović