我确信有一种干净的方法可以做到这一点,但我可能没有使用正确的关键字来找到它。
所以让我说我有一个网格。从网格上的位置开始,返回落在给定距离内的所有网格坐标。所以我称之为:
getCoordinates( currentPosition, distance )
对于每个坐标,从初始位置开始,添加所有基本方向,然后在它们周围添加空格,依此类推,直到达到距离。我想在网格上看起来像钻石。该函数将返回该坐标数组。有人能指出我能够有效地完成这项工作的例程吗(我在AS3工作,这是值得的)?
在所需的输出中,迭代1将是:
.x.
xxx
.x.
迭代2将是:
..x..
.xxx.
xxxxx
.xxx.
..x..
迭代3:
...x...
..xxx..
.xxxxx.
xxxxxxx
.xxxxx.
..xxx..
...x...
依旧......
答案 0 :(得分:7)
编辑:更新了算法以反映OP想要的内容。
迭代1:
.x.
xxx
.x.
迭代2:
..x..
.xxx.
xxxxx
.xxx.
..x..
... 迭代4:
....x....
...xxx...
..xxxxx..
.xxxxxxx.
xxxxxxxxx
.xxxxxxx.
..xxxxx..
...xxx...
....x....
显然,您可以在不迭代的情况下确定坐标。
如果起点是(X,Y),则迭代是n
for(int i = x - n; i <= x + n; i++)
{
for(int j = y - n; j <= y + n; j++)
{
int dx = abs(i - x);
int dy = abs(j - y);
if(dx + dy <= n) //Produces a diamond, n+1 would produce a diamond with cut corners
{
//The point at (i, j) is within the marked area.
}
}
}
答案 1 :(得分:2)
这取决于您使用哪种数据结构来表示网格,但通常breadth-first search应该为您处理此问题。
答案 2 :(得分:0)
BFS + FIFO队列:
P = U = 0;
Q[P] = currentPosition;
D[ Q[P] ] = 0; D[~all the rest~] = infinity (or really any flag, such as -1)
while ( P <= U )
{
current = Q[P];
++P;
for ( each neighbor N = (X', Y') of (current.X, current.Y) )
if ( D[N] == inf && D[current] + 1 <= distance )
{
D[N] = D[current] + 1;
++U;
Q[U] = N;
}
}
答案 3 :(得分:0)
两种可能性,取决于你想要的距离以及你愿意做多少编程:
(1)Dijkstra的algorithm。如果您想象网格上的每两个相邻点都已连接(只有垂直和水平连接,因此每个点有4个邻居),您将获得您的钻石。您不必为图形实现任何数据结构 - 您只需要为当前顶点生成邻居列表。
(2)Fast marching。这将在数值误差范围内为您提供真正的欧几里德距离,因此您将得到一个近似的圆,而不是钻石。
答案 4 :(得分:0)
对于迭代N,你想要所有的点P',使得从P到P'的距离<= N,其中距离是| X' - X | + | Y' - Y |。
for (int i = -N; i <= N; i++)
for (int j = abs(i) - N; j <= N - abs(i); j++)
{
results.Add(new Point(X+i, Y+j));
}
}
return results;
答案 5 :(得分:0)
我意识到这个问题已有9年历史了,但是实际上是从中心(菱形)径向地迭代的算法看起来像这样:
for (int mag = 0; mag <= range; ++mag)
for (int xm = 0; xm <= mag; ++xm)
{
int ym = mag - xm;
int xms = (xm == 0) ? -1 : 1;
int yms = (ym == 0) ? -1 : 1;
for (int xs = -1; xs <= xms; xs += 2)
for (int ys = -1; ys <= yms; ys += 2)
{
int x = x_centre + xm * xs;
int y = y_centre + ym * ys;
// Do whatever with x, y here
}
}