在Java中,我试图为游戏中的城镇管理员创建一个Grid系统。我希望它从中心点开始填充,并以圆形图案(甚至菱形图案)将其伸出。我是否可以使用公式来简化这一过程?

例如,我希望能够输入一个数字,并获取网格的X和Y坐标。例如

If i input 0, it will give me (0,0)
If i input 1, it will give me (0,1)
2 -> (1,0)
3 -> (0,-1)
4 -> (-1,0)
5 -> (0,2)
6 -> (1,1)
7 -> (2,0)
8 -> (1,-1)
9 -> (0,-2)
10 -> (-1,-1)
11 -> (-2,0)
12 -> (-1,1)
13 -> (0,3)
etc


我只是不知道从哪里开始。

提前致谢,

最佳答案

为什么要从0一直迭代到n只是为了计算坐标when you could use ... math

这是您的螺旋线访问的正方形序列:

         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个环的大小为4r,并包含从2(r-1)r +1到2r(r +1)(含)的数字。

那么哪个环包含数字n?好吧,它是最小的r,使得2r(r + 1)≥n,可以使用二次公式找到:


  2r(r + 1)≥n
  ∴2r2 + 2r − n≥0
  ∴r≥(−2 +√(4 + 8n))/ 4
  ∴r≥½(−1 +√(1 + 2n))


所以我们想要的是

 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);
    }
}

09-11 19:36