蜂窝网格的坐标以及寻路
Posted 蝶之羽风暂留此
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蜂窝网格的坐标以及寻路相关的知识,希望对你有一定的参考价值。
蜂窝网格就是这样的六边形格子
仔细观察的话,可以发现,蜂窝网格和四边形网格的区别就在于,蜂窝网格把偶数行的格子都错开了。
假设一个格子在四边形网格中的坐标是(x,y),那么它在蜂窝网格的坐标应该是:
(sqrt3 * (x + (y % 2) / 2) , y * 3 / 2)
这样就能把蜂窝网格用一个二维数组保存起来了。
接下去是一个寻路算法,我们需要找出以一个格子为起点,一定移动力下所有可以到达的格子,就像上面那张图里展示的那样:
public class hextile{ public static float sqrt3=1.7320508075689f; public int x, y,m;//格子的坐标,以及移动到这个格子上的剩余行动力 public hextile pre;//表示是从哪个格子移动到这个格子上的,为Null的话表示没有 int max=20;//二维数组的上界,暂时定为了20*20的矩形蜂窝方阵 ///构造函数 public hextile(int x,int y,hextile pre,int m){ this.x = x; this.y = y; this.pre = pre; this.m = m; } //返回蜂窝一周的六个蜂窝,理论上要另写一个函数判断是否越界了的,这里直接在方法里判断了 public List around(int i){ List list = new List (); if (this.x > 0) list.Add (new hextile (this.x - 1, this.y, this,this.m-i)); if (this.x < max-1) list.Add (new hextile (this.x + 1, this.y, this,this.m-i)); if ((this.y < max-1) && (this.x - 1 + this.y % 2 >= 0)) list.Add (new hextile (this.x - 1 + this.y % 2, this.y + 1, this,this.m-i)); if ((this.y < max-1) && (this.x + this.y % 2 < max)) list.Add (new hextile (this.x + this.y % 2, this.y + 1, this,this.m-i)); if ((this.y > 0) && (this.x - 1 + this.y % 2 >= 0)) list.Add (new hextile (this.x - 1 + this.y % 2, this.y - 1, this,this.m-i)); if ((this.y > 0) && (this.x + this.y % 2 < max)) list.Add (new hextile (this.x + this.y % 2, this.y - 1, this,this.m-i)); return(list); } //返回以此对象为起点,移动力为m的蜂窝,arr为移动力阻碍数组 public List findarea(int[,] arr){ List list = new List ();//输出用的链表 List a = new List ();//a记录每个需要寻路的节点 a.Add(this); list.Add (this); //枚举移动力,一定要倒过来枚举,因为涉及到了链表元素的删除 for (int i = this.m; i > 0; i--) { //对移动力等于当前枚举数的格子进行操作 for (int j = a.Count - 1; j >= 0; j--) //对应移动力才能进行操作 if (a[j].m==i) //有多余移动力则获取该格子周围一圈的格子 if (a[j].m>=arr[a[j].x,a[j].y]){ //获取该格子周围一圈的格子 List l = a [j].around(arr[a[j].x,a[j].y]); for (int u = 0; u < l.Count; u++) { bool bo = true; //判断该格子是否能加入输出list for (int o = 0; o < list.Count; o++) { if ((list[o].x==l[u].x)&&(list[o].y==l[u].y)){ bo = false; //如果是更优路线 if (list [o].m < l [u].m) { list.RemoveAt (o); list.Add (l [u]); a.Add (l [u]); break; } } } if (bo) { list.Add (l [u]); a.Add (l[u]); } } //操作完毕,将该格子从待操作列表中删除 a.RemoveAt (j); } } return(list); } }
以上是关于蜂窝网格的坐标以及寻路的主要内容,如果未能解决你的问题,请参考以下文章