简体   繁体   English

以六边形图案逐步浏览2D阵列

[英]Step through 2D array in hexagon pattern

I use a nested for loop to create a grid of hexagons. 我使用嵌套的for循环创建六边形网格。 This creates a square grid: 这将创建一个正方形网格:

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

在此处输入图片说明

I've drawn the start and end values for z & x on the image. 我已经在图像上绘制了z和x的开始和结束值。

What I'd like is to have the grid itself also shaped hexagonally: 我想让网格本身也呈六角形:

在此处输入图片说明

I think figured out the limits for x: 我认为找出x的限制:

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

And that (I think) x should only be at it's min and max (0 & 6 in the examples) when z = gridSize / 2 rounded up, though I may well be wrong! 而且(我认为)当z = gridSize / 2向上取整时,x应该仅是其最小值和最大值(在示例中为0&6),尽管我可能错了!

I tried putting a bunch if IFs in the loops but it quickly started to get overly complicated, I figure there must be a more 'mathsy' way to do it, but sadly I'm not mathsy! 我试过在IF中加入一堆,但很快就变得过于复杂,我认为必须有一种更“数学”的方法,但可惜我不是数学!

Any idea how I can write a loop to form the required pattern? 知道如何编写循环以形成所需的模式吗?

According your excepted picture the center is the long row (gridSize = 7). 根据您的例外图片,中心是长行(gridSize = 7)。

floor(7/2) = 3 (/2 because the long row is in the center) floor(7/2) = 3 (/ 2,因为长行位于中间)

Now, gridSize - 3 = 4 ==> 4 items in your first row 现在, gridSize - 3 = 4 ==>第一行有4个项目

Then each iterate add one till you have 7 items in one row. 然后每个迭代添加一个,直到一行中有7个项目。

Then do a minus... 然后减负...

it's the code (draw "*", not added spaces before and after..) 这是代码(绘制“ *”,不在前后添加空格..)

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

Thanks to a hint from AsfK I solved it like this 感谢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++;
        }
    }
}

Would be great if anyone can think of a more elegant solution! 如果有人可以想到一个更优雅的解决方案,那就太好了!

If @AsfK's solution is not good enough, I'll give it a try as well: 如果@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);
        }
    }

With such code PrintHex(4) results in 有了这样的代码, PrintHex(4)导致

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

And if you uncomment the position v1 line instead of the one that prints "* " , you'll get 如果取消注释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

similarly position v2 类似地, 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

which looks like the x indices you want. 看起来像您想要的x索引。 Basing on your data I'm not really sure whether you need v1 or v2 variant. 根据您的数据,我不确定是否需要v1v2版本。 The v2 looks more consistent to me but it really depends on how your CreateCell(x, z); v2对我来说看起来更一致,但实际上取决于您的CreateCell(x, z); treats the x = 0 case. 对待x = 0情况。

PS obviously you can inline PrintHexLine call but it means having two different z variables that you should not mess up with and I think it is cleaner to move that in a separate method. PS显然,您可以内联PrintHexLine调用,但这意味着您应避免使用两个不同的z变量,并且我认为将其移动到单独的方法中会更干净。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM