在六边形地图上显示最大范围

时间:2013-05-27 19:15:49

标签: ios logic

我想在我的十六进制地图中显示最大移动覆盖。例如:

中心点位于50,50 最大允许移动为5个十六进制。

这是我用于叠加的代码:

for (int height = lowHeight; height <= highHeight; height++)
{
    for (int width = lowWidth; width <= highWidth; width++)
    {
        [self hexOnMap:height :width :@"green"];
    }
}

宽度为x坐标50 身高是yCoordinate 50

lowHeight = height - 5

highHeight =身高+5

lowWidth = width - 5

hightWidth = width + 5

显然我的循环不起作用,因为角落的移动超过5个六角形。因为我觉得我的智商一分钟都在下降,有人请告诉我明显的情况:)并且5的移动值不是静态的。

enter image description here

编辑:@DPenner

感谢您的回复。我尝试了类似的东西,但这个被诅咒的东西仍然拒绝工作。您的代码显示以下结果:

enter image description here

编辑2:@DPenner - 你几乎拥有它。我正在使用您的代码上传叠加层,以便您可以看到。我昨晚找到了一篇很棒的文章,它给了我解决这个问题所需的线索。但我真的很感谢你的帮助,并试图解决这个问题!

enter image description here

2 个答案:

答案 0 :(得分:1)

我删除了我的旧答案,因为它完全错误:我忘了考虑相邻的六边形有时在x和y坐标上都不同。抓住这个很棘手,但下面的代码应该可行:

如果中心X坐标是偶数:

for (int width = lowWidth; width <= highWidth; width++)
{        
    double heightNeeded = 5 - abs((centerX - width)/2.0);
    for (int height = centerY - (int)ceil(heightNeeded); height <= centerY + (int)floor(heightNeeded); height++)
    {
        [self hexOnMap:height :width :@"green"];
    }
}

如果中心X坐标为奇数,则交换地板和天花板功能。将5更改为不同大小的叠加层。

我手工检查了它,似乎工作正常。外部循环是宽度/ X循环,因为它的X坐标在水平方向上锯齿形,其中ceil和floor函数在内部高度/ Y循环中“固定”。

答案 1 :(得分:1)

经过近24小时的无眠,我找到了一篇很好的文章来处理这个问题。文章在这里:

http://keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/

以下是使其全部工作的代码:

for (int y = minY; y <= maxY; y++)
{
    for (int x = minX; x <= maxX; x++)
    {
        int xDistance = (x - startXcoordinate);

        int yStart = 0;
        if(x > startXcoordinate)
            yStart = -1;

        int yDistance = ((xDistance * -1) + yStart) / 2;

        yDistance = yDistance + (y - startYcoordinate);

        int z = (xDistance + yDistance)* -1 ;


        int maxDistance = 0;

        if(abs(xDistance) > maxDistance)
            maxDistance = abs(xDistance);

        if(abs(yDistance) > maxDistance)
            maxDistance = abs(yDistance);

        if(abs(z) > maxDistance)
            maxDistance = abs(z);

        if(abs(maxDistance) <= patrolRange)
            [self hexOnMap:y :x :@"green"];
    }
}

enter image description here