逐步通过六边形图案的2D数组

时间:2018-01-01 15:51:07

标签: c# for-loop unity3d math unity5

我使用嵌套for循环来创建六边形网格。这会创建一个方格:

for (int z = 0; z < gridSize; z++)
{
    for (int x = 0; x < gridSize; x++)
    {
            // creates verts for a hexagon shape which later form a mesh
            // x and z form the basis of the Vector3 position of the center 
            // of each hexagon
            CreateCell(x, z); 
    }
}

enter image description here

我已经绘制了z&amp;的起点和终点值。 x在图像上。

我想要的是让网格本身也形成六边形:

enter image description here

我认为找出x的限制:

int greaterThan = Mathf.RoundToInt(gridSize/ 3) - 1;
int lessThan = width - greaterThan;

而且(我认为)当z = gridSize / 2向上舍入时,x应该仅在它的最小值和最大值(示例中为0和6),尽管我可能错了!

我尝试在循环中放入IF但很快就开始变得过于复杂,我认为必须有一个更多的数学&#39;这样做的方法,但遗憾的是我不是数学家!

我知道如何编写一个循环来形成所需的模式吗?

3 个答案:

答案 0 :(得分:1)

根据您的例外图片,中心是长行(gridSize = 7)。

floor(7/2) = 3(/ 2,因为长行位于中心)

现在,gridSize - 3 = 4 ==&gt;第一行中的4个项目

然后每个迭代添加一个,直到你在一行中有7个项目。

然后做一个减...

它是代码(绘制&#34; *&#34;,没有在..之前和之后添加空格)

int gridSize = 7;
int center = 7/2;
int delta = 1;
for (int r = 0; r < gridSize; r++) {
    for (int c = gridSize - center; c < gridSize + delta; c++){
        System.out.print("*");
        // location of c = c - delta (position)
    }
    System.out.println();
    if (r < center)
        delta++;
    else
        delta--;
}

答案 1 :(得分:1)

感谢AsfK的提示,我解决了这个问题

int xL, xU, xMid, zM2;
xL = Mathf.FloorToInt(width / 3) - 1;
xU = (width - xL) + 1;
xMid = Mathf.FloorToInt(width / 2);

for (int z = 0; z < height; z++)
{
    for (int x = xL; x < xU; x++)
    {
        CreateCell(x, z);
    }

    zM2 = z % 2;

    if(z < xMid)
    {
        if (zM2 == 0)
        {
            xL--;
        }
        if (z > 0 && zM2 == 1)
        {
            xU++;
        }
    } else
    {
        if (zM2 == 1)
        {
            xL++;
        }
        if (zM2 == 0)
        {
            xU--;
        }
        if (z == width - 1)
        {
            xL--;
            xU++;
        }
    }
}

如果有人能想到更优雅的解决方案,那会很棒!

答案 2 :(得分:1)

如果@ AsfK的解决方案不够好,我也会尝试一下:

    private static void PrintHexLine(int z, int size)
    {
        if (z >= size)
        {
            z = 2 * size - 2 - z;
        }
        int start = size - z - 1;
        int end = start + size + z;
        for (int x = 0; x < start; x++)
        {
            Console.Write(" ");
        }
        for (int x = start; x < end; x++)
        {
            Console.Write("* ");
            //Console.Write((x - start / 2) + " "); // position v1
            //Console.Write((x - (start + 1) / 2) + " "); // position v2

        }
        Console.WriteLine();
    }

    public static void PrintHex(int size)
    {
        for (int z = 0; z < 2 * size - 1; z++)
        {
            PrintHexLine(z, size);
        }
    }

使用此类代码PrintHex(4)导致

   * * * *
  * * * * *
 * * * * * *
* * * * * * *
 * * * * * *
  * * * * *
   * * * *

如果您取消注释position v1行而不是打印"* "的行,那么您将获得

   2 3 4 5
  1 2 3 4 5
 1 2 3 4 5 6
0 1 2 3 4 5 6
 1 2 3 4 5 6
  1 2 3 4 5
   2 3 4 5

同样position v2

   1 2 3 4
  1 2 3 4 5
 0 1 2 3 4 5
0 1 2 3 4 5 6
 0 1 2 3 4 5
  1 2 3 4 5
   1 2 3 4

看起来像你想要的x索引。根据您的数据,我不确定您是否需要v1v2变体。 v2看起来更加一致,但这实际上取决于CreateCell(x, z);如何处理x = 0案例。

P.S。显然你可以内联PrintHexLine调用,但它意味着有两个不同的z变量,你不应该搞砸了,我认为用一个单独的方法移动它是更清晰的。