让我们有一个二维网格,其中X是要检查的单元格,T是满足给定单元格X的检查标准的单元格。
+---+---+---+---+---+
| T | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | X | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
现在,我想通过以下方式搜索找到最接近X的,满足条件(在此示例中为T)的单元格,其中数字表示要检查的单元格按升序排列:
+---+---+---+---+---+
| 11| | | | |
+---+---+---+---+---+
| 10| 1 | 2 | 3 | |
+---+---+---+---+---+
| 9 | 0 | X | 4 | |
+---+---+---+---+---+
| 8 | 7 | 6 | 5 | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
对X单元的偏移量进行硬编码的简单方法不起作用,因为T和X之间的距离是任意的。那么,如果没有前一种方法,我该如何归档呢?
答案 0 :(得分:1)
如果您想结识邻居,可以使用下面显示的简单算法。半径将指定您将获得多少个邻居,并且可以非常简单地增加它。它将从上到下从左到右。有了数据,循环就可以把每个邻居扔掉,并让相邻的小区相距-1。
List<Node> neighbours = new List<Node>();
iint currentRadius = 1;
for(int x = -currentRadius; x <= concurrent; x++)
{
for(int y = -currentRadius; y <= concurrent; y++)
{
if(x == 0 && y == 0)
continue; //Dont check itself
int checkX = pos.x + x;
int checkY = pos.y + y;
if(checkX >= 0 && checkX < gridSizeX && checkY >= 0 checkY < gridSizeY) //Check if current pos is not out of bounds
{
neighbours.Add(nodes(checkX, checkY));
}
}
}
答案 1 :(得分:1)
尚未指定半径测试,在循环上方没有标记任何内容,仅填充了一个正方形。 “半径”一词仅适用于圆形区域。
如果要枚举圆内或圆附近的点,请使用欧氏距离:
在浮点域中:以currentRadius * currentRadius为条件,并相应地将X * X + Y * Y乘以
在整数域中:一个布雷森汉姆圆,参考文献https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/连接水平进行填充
第二个选项是最快的-我在过去的美好时光中使用了-您会更快地找到点。.但是它给您带来象限和边界问题,并且如果您要存储点,则在运行时从整数获得的收益比较将无关紧要。
现在,我将使用第一个选项。对于相对较小的网格,请使用循环,添加R * R> V的测试,其中V是X和T之间的平方欧几里得距离,即V =(TX-X)*(TX-X)+(TY-Y )*(TY-Y)。