当您可以使用...数学时,为什么要从 0 一直迭代到n来计算坐标!
这是您的螺旋访问的正方形序列:
13
14 5 24
15 6 1 12 23
16 7 2 0 4 11 22
17 8 3 10 21
18 9 20
19
这可以分为“环”。首先是数字 0。然后是一个大小为 4 的环:
1
2 4
3
然后是第二个 8 号环:
5
6 12
7 11
8 10
9
然后是第三个 12 号的环:
13
14 24
15 23
16 22
17 21
18 20
19
等等。第r环的大小为 4 r,包含从 2( r − 1) r + 1 到 2 r ( r + 1) 的数字。
那么哪个环包含数字n?嗯,它是最小的r使得 2 r ( r + 1) ≥ n,可以使用二次公式找到:
2 r ( r + 1) ≥ n
∴ 2 r 2 + 2 r − n ≥ 0
∴ r ≥ (−2 + √(4 + 8 n )) / 4
∴ r ≥ ½(−1 + √(1 + 2 n ))
所以我们想要的r是
r = ceil(0.5 * (−1.0 + sqrt(1.0 + 2.0 * n)))
这足以计算您想要的坐标:
public spiral_coords(int n) {
if (n == 0) {
return Coords(0, 0);
}
// r = ring number.
int r = (int)(ceil(0.5 * (-1.0 + sqrt(1.0 + 2.0 * n))));
// n is the k-th number in ring r.
int k = n - 2 * (r - 1) * r - 1;
// n is the j-th number on its side of the ring.
int j = k % r;
if (k < r) {
return Coords(-j, r - j);
} else if (k < 2 * r) {
return Coords(-r - j, -j);
} else if (k < 3 * r) {
return Coords(j, -r - j);
} else {
return Coords(r - j, j);
}
}