最近在学习Gh的循环插件,无意中看到有关迷宫算法的内容,就想尝试着用Anemone插件实现。不过因为根本不懂编程,磕磕绊绊还是做出来了,不过最终性能实现状况不是特别好。因为涉及到每次循环需要遍历整个点集,随着需要计算的格数增加,每次循环计算量就会相应增加,之后试试能不能直接通过点之间数据结构的关系重新实现一下。参考的这篇文章
CSDN-专业IT技术社区-登录blog.csdn.net(一)深度优先
人话就是不撞南墙不回头:随机从一个点开始随机“钻洞”,如果碰墙无路可走,就往回走直到周围有可以选择的路径,然后再 次随机“钻洞”,重复这个过程,直到迷宫所有的部分都被走过。GIF演示:
可能比较麻烦的地方就是把这个思路转换成电池,这里说一下我在Grasshopper中实现的思路:
1.square运算器生成点阵,将生成的对应方格中心点点集作为“陆地”,初始状态下每个点四周都被“墙”包围
2.随机选择一个“陆地”点作为初始点(以下简称“头”),然后将这个点从“陆地”之中除去,这是循环的初始条件。
3.利用布尔值与0和1的关系判定运算点周围点的个数:
计算运算点与每个剩余点的距离,判断它们是否等于方格的边长,将得到的这些布尔值(1=True,0=False)累加,结果大于0则四周有可选择的点,反之没有。
4.利用stream filter运算器实现不同情况下的分流
“有路可走”时,随机选取“头”周围的点,并将其从剩余点中剔除,可以把这个点与起始点连线作为路径记录;
“无路可走”时,剩余点不变并且参与下一次循环。
5.定义一个列表存储已经走过的点(insert item运算器)用于“无路可走”时运算点的选取
“有路可走”时,将选择的点插入到列表的第一项
“无路可走”时,将该列表第一项作为运算点,并将其剔除列表
6.最后定义一下循环结束的条件,如果剩余点的列表个数等于0则循环终止
调整电池图,这个时候就可以执行一个完整的循环了。不过目前只有点参与运算,可以在循环中增加“有路可走”时起始点与末尾点的连线,这个时候可以看到每次循环两点的连线,不过需要右键选择Collect Data才能保留所有连线,或者利用Data Recorder运算器保留每次发生变化的值。
但是这样就会有一些问题:
如果循环CollectData就会有很多无效的数据冗余,比如剩余点集以及回退点集每循环一次都会存储所有的数据;
如果使用DataRecorder,每次更改生成条件需要重新设置,而且我不仅需要路的数据,更需要墙的数据。
7.这样的话就需要稍微修改一下生成逻辑了。“墙”与“路”是有关系的,每形成一条路径就摧毁一堵墙,也就是他们之间是一一对应的(他们的中点是重合的)。那么可以预先生成全部的墙与路径,之后每次循环保留或者剔除相应的数据即可。甚至不需要这些点参与循环,只需要拿到他们的序号就好(利用member index运算器)。这样可以大大减小运算量。
最后根据循环得到的索引值数据提取保留的端点数据,并将每个分支下的两个点相连,这样就大功告成了;
之后要做的就是点击button,等待循环了,也可以在输出的“头”位置连一个circle观察一下这个迷宫的生成过程;
8.最后join一下offset一下loft一下Union一下extrude一下就可以拿到一个迷宫了。
迷宫电池图:
百度网盘地址:
链接:https://pan.baidu.com/s/1PBBTozTboIev7HoAUWLjIQ
提取码:vmy0
需要Grasshopper插件Anemone
下载地址:
https://www.food4rhino.com/app/anemonewww.food4rhino.com