六角形のフィールド上のスパイラルによって細胞を作成するためのアルゴリズム

StackOverflow https://stackoverflow.com/questions/2142431

  •  22-09-2019
  •  | 
  •  

質問

六角形のフィールド上のスパイラルによって細胞を作成するためのアルゴリズムを見つけるために、

ヘルプます。

画像を見ます:

レッツ・無次元2D配列を想像してみてください。 X軸は青線であり、Yが水平で、螺旋は赤色である。

私は螺旋

でN点に中心点X0Y0から細胞を追加する必要があります

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

役に立ちましたか?

解決

私はあなたがダウンして行くと右(または上、左)ときXは同じままだから、sligtly番号細胞を変更することをお勧めしたいです。 そして、次のような単純なアルゴリズムが動作するはずます:

  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
  }

これは、次のように点を生成

私たちが得る形質転換後:

他のヒント

の" ここに画像の説明を入力します。 (円は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 );
  }

そしてm画素左に言う、すべての奇数のyをシフトすることによって、それを描き、そのグリッドを使用してスパイラルを作成し、あなたは正方形の代わりに、六角形と通常のグリッドを持っていた想像し、それはあなたにその効果を与えるでしょう。

あなたは前のラウンドを選択進に6未選択隣接ヘクスの最善を選択するために、適切なスコア関数を使って、一度にヘクスものを選ぶことができます。私が考える作品は(0,0)(一度に一つの「シェル」のヘクスを選択する力)、力((1,0)に最も近いを選択することで、絆を壊す一貫性のスパイラル方向に最も近いを選択することであるとスコア関数新しいシェルで)。六角グリッドの距離は、以下の機能を使用して計算することができます:

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

あなたは方向性をシミュレートすることによってそれを行うことができます。あなたの方向性は、あなたが時計回りに行くと、その後1ずつ増加「0ポイントアップ」、ある場合は、次のように実行する必要があります:

Pick a centre cell.
Pick the second cell (ideally in direction 0).
Set direction to 2.

While you have more cells to mark:
  if the cell in (direction+1)%6 is free:
    set direction = (direction+1)%6
  mark current cell as used
  go to cell in direction

私はこの問題にアプローチする修羅の道@愛したが、仕事への正確なアルゴリズムを得ることができませんでした。また、私は(X細胞を2離間され、そして他のすべてのXアイテムが隠されている場合)間隔2×1六角を使用しています。

ここで私は(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
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top