1

Java で、ゲーム内のタウン マネージャー用のグリッド システムを作成しようとしています。中心点から塗りつぶし、円形のパターン (またはダイヤモンドのパターン) で外に出ていきたいです。これを簡単にするために使用できる数式はありますか?

たとえば、数値を入力して、グリッドの 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

どこから始めればいいのかわからない。

前もって感謝します、ダン

4

3 に答える 3

2

... mathを使用できるのに、座標を計算するためだけに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 の 2 つ目のリング:

          5
       6    12
    7          11
       8    10
          9

次に、サイズ 12 の 3 つ目のリング:

         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が含まれているのでしょうか? それは 2 r ( r + 1) ≥ nとなるような最小のrであり、次の 2 次式を使用して見つけることができます。

2 r ( r + 1) ≥ n
∴ 2 r 2 + 2 rn ≥ 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);
    }
}
于 2012-12-15T18:11:48.577 に答える
0

できるよ

for (int n=1; n < max; n++) {
    for(int x = -n; x < n; x++)
        process(x, n);
    for(int y = n; y > -n;y--)
        process(n, y);
    for(int x = n; x > -n;x--)
        process(x, -n);
    for(int y = -n; y < n;y++)
        process(-n, y);
}
于 2012-12-15T16:50:36.517 に答える
0

これは、パターンを一連の同心シェルと見なします。最初に、内側のシェルをすばやく列挙します。次に、右側から始めて反時計回りに外側のシェルを通り抜けます。

int tot = 1, r=0; // r is "radius", tot is # of points so far
// since each "shell" has 4r points, quickly find the desired radius
while(tot + 4*r < i){tot += 4*r; r++;}
// enumerate the boundary counter-clockwise
int x = r; y = 0, j;
for(j=0; j<r && tot<i; j++, x--, y++, tot++);
for(j=0; j<r && tot<i; j++, x--, y--, tot++);
for(j=0; j<r && tot<i; j++, x++, y--, tot++);
for(j=0; j<r && tot<i; j++, x++, y++, tot++);
// answer in x,y
于 2012-12-15T17:42:10.603 に答える