5

六角形のフィールドでらせんによってセルを作成するためのアルゴリズムを見つけるのに役立ちます。

画像を見てください:

代替テキスト

無次元の 2 次元配列を想像してみましょう。X 軸は青い線、Y 軸は水平、らせんは赤です。

中心点 x0y0 から点 N までスパイラルでセルを追加する必要があります

問題を解決する方法を教えてください。ありがとうございました!

4

6 に答える 6

7

セルの番号付けを少し変更して、上下左右に移動しても X が変わらないようにすることをお勧めします。次に、次のような単純なアルゴリズムが機能するはずです。

  int x=0, y=0;   
  add(x, y); // add the first cell
  int N=1 
  for( int N=1; <some condition>; ++N ) {
    for(int i=0; i<N; ++i) add(++x, y);  // move right
    for(int i=0; i<N-1; ++i) add(x, ++y); // move down right. Note N-1
    for(int i=0; i<N; ++i) add(--x, ++y); // move down left
    for(int i=0; i<N; ++i) add(--x, y); // move left
    for(int i=0; i<N; ++i) add(x, --y); // move up left
    for(int i=0; i<N; ++i) add(++x, --y); // move up right
  }

これにより、次のようにポイントが生成されます。

生成点のプロット

変換後、次のようになります。

生成されたポイントの 16 進グリッドへの変換

于 2010-01-26T23:28:03.387 に答える
1

ここに画像の説明を入力 (円の直径は 1)

位置を取得する関数は次のiとおりです。

  void getHexPosition( int i, ref double x, ref double y )
  {
     if ( i == 0 ) { x = y = 0; return; }

     int layer = (int) Math.Round( Math.Sqrt( i/3.0 ) );

     int firstIdxInLayer = 3*layer*(layer-1) + 1;
     int side = (i - firstIdxInLayer) / layer; // note: this is integer division
     int idx  = (i - firstIdxInLayer) % layer;                  
     x =  layer * Math.Cos( (side - 1) * Math.PI/3 ) + (idx + 1) * Math.Cos( (side + 1) * Math.PI/3 );
     y = -layer * Math.Sin( (side - 1) * Math.PI/3 ) - (idx + 1) * Math.Sin( (side + 1) * Math.PI/3 );
  }

Math.Sqrt(.75)結果を次のようにスケーリングすると、

ここに画像の説明を入力

修羅の答えのように歪んだ座標に興味がある場合:

  int[] h = { 1, 1, 0, -1, -1, 0, 1, 1, 0 };
  void getHexSkewedPosition( int i, ref int hx, ref int hy )
  {
     if ( i == 0 ) { hx = hy = 0; return; }

     int layer = (int) Math.Round( Math.Sqrt( i/3.0 ) );

     int firstIdxInLayer = 3*layer*(layer-1) + 1;
     int side = (i - firstIdxInLayer) / layer;
     int idx  = (i - firstIdxInLayer) % layer;

     hx = layer*h[side+0] + (idx+1) * h[side+2];
     hy = layer*h[side+1] + (idx+1) * h[side+3];
  }

  void getHexPosition( int i, ref double hx, ref double hy )
  {
     int x = 0, y = 0;
     getHexSkewedPosition( i, ref x, ref y );
     hx = x - y * .5;
     hy = y * Math.Sqrt( .75 );
  }
于 2016-09-29T21:12:52.653 に答える
0

あなたは方向をシミュレートすることによってそれを行うことができます。方向が「0ポイント上」の場合、時計回りに進むにつれて1ずつ増加し、次のようになります。

中央のセルを選択します。
2番目のセルを選択します(理想的には方向0)。
方向を2に設定します。

マークするセルが増えている間:
  (direction + 1)%6のセルが空いている場合:
    方向を設定=(方向+ 1)%6
  現在のセルに使用済みのマークを付ける
  方向にセルに行きます
于 2010-01-27T07:34:31.833 に答える
0

六角形ではなく正方形の通常のグリッドがあり、そのグリッドを使用してらせんを作成し、奇数 y ごとに m ピクセル左にシフトして描画すると、その効果が得られます。

于 2010-01-26T21:06:40.413 に答える
0

適切なスコア関数を使用して、前のラウンドで選択したヘクスに隣接するまだ選択されていない 6 つのヘクスの中から最適なものを選択することにより、ヘクスを 1 つずつ選択できます。機能するスコア関数は、(0,0)に最も近いものを選択し(一度に1つの「シェル」でヘックスを選択することを強制します)、(1,0)に最も近いものを選択して同点を破ることです(一貫したスパイラル方向を強制します)新しいシェルで)。16 進グリッドの距離は、次の関数を使用して計算できます。

double grid_distance(int dx, int dy) {
  double real_dx = dx + y/2.0;
  double real_dy = dy * sqrt(3)/2.0;
  return sqrt(real_dx * real_dx + real_dy * real_dy);
}
于 2010-01-26T22:44:58.027 に答える
0

問題にアプローチする@shuraの方法が気に入りましたが、その正確なアルゴリズムを機能させることができませんでした。また、2x1 の六角形の間隔を使用しています (x セルは 2 間隔で配置され、他のすべての x アイテムは隠されています)。

これが私が取り組んだことです(JavaScriptではありますが):

    //Hexagon spiral algorithm, modified from 
    for(var n=1; n<=rings; ++n) {
        x+=2; add(x, y);
        for(var i=0; i<n-1; ++i) add(++x,++y); // move down right. Note N-1
        for(var i=0; i<n; ++i) add(--x,++y); // move down left
        for(var i=0; i<n; ++i) { x-=2; add(x, y); } // move left
        for(var i=0; i<n; ++i) add(--x,--y); // move up left
        for(var i=0; i<n; ++i) add(++x, --y); // move up right
        for(var i=0; i<n; ++i) { x+=2; add(x, y); }  // move right
    }
于 2015-11-16T00:34:20.250 に答える