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

问题描述 投票:2回答:3

我使用嵌套的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&x的开始值和结束值。

我想要的是网格本身也是六角形的:

enter image description here

我想出了x的限制:

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

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

我尝试在循环中放入一堆但是很快就开始变得过于复杂,我认为必须有一种更“数学”的方法来做到这一点,但遗憾的是我不是数学!

知道我怎么能写一个循环来形成所需的模式吗?

c# for-loop unity3d math unity5
3个回答
1
投票

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

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

现在,gridSize - 3 = 4 ==>第一行中有4个项目

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

然后做一个减...

它是代码(绘制“*”,而不是在...之前和之后添加空格)

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
投票

感谢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++;
        }
    }
}

如果有人能想到更优雅的解决方案,那就太棒了!


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案件。

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

© www.soinside.com 2019 - 2024. All rights reserved.