【问题标题】:hexagon grid drawing issue六边形网格绘图问题
【发布时间】:2016-10-24 03:37:54
【问题描述】:

我似乎在绘制正确的十六进制网格时遇到了一些麻烦:

如您所见,六边形只是略微未对齐,但我相信我的数学是正确的(其中一些已通过 http://www.redblobgames.com/grids/hexagons/ 验证)。

我的绘制方法是从左上角的六边形(第一行的第一个瓦片)开始画那一行瓦片。然后对于下一行,有一个负的 X 偏移和正的 Y 偏移等,直到它到达中间行,X 偏移增加直到 0:

private function drawHexGrid(inputGraphics:Graphics, inputPos:Point, inputGrid:HexGrid, inputTileSize:int):void {

    var rootThree:Number = Math.sqrt(3); // seems like this will be used a lot

    // total number of rows and also size of largest row (in tiles)
    var totalRows:int = (2 * inputGrid.size) - 1;

    // the other useful dimension of a hex tile
    var triSize:Number = rootThree * 0.5 * inputTileSize;

    var topLeft:Point = new Point(-(inputGrid.size - 1) * triSize, -(1.5 * (inputGrid.size - 1) * inputTileSize));
    topLeft.x += inputPos.x;
    topLeft.y += inputPos.y;
    var currentPos:Point = topLeft.clone();

    // step size between each tile and row
    var xStep:Number = rootThree * inputTileSize;
    var yStep:Number = triSize * rootThree;

    var offsetDirection:int = -1;
    var rowLimit:int = inputGrid.size;
    var offsetAmount:int = 0; // offsetAmount goes 1 to n, then back to 0 again, used for calculating thw row offsets

    var mazeTiles:Vector.<Tile> = inputGrid.getTiles();
    var tileCounter:int = 0; // index to cycle through mazeTiles

    for(var rowCount:int = 0; rowCount < totalRows; rowCount++){
        currentPos.x = topLeft.x + (offsetAmount * rootThree / -2 * inputTileSize);

        for(var counter:int = 0; counter < rowLimit; counter++){
            drawHexTile(inputGraphics, currentPos.x, currentPos.y, inputTileSize, mazeTiles[tileCounter++]);
            currentPos.x += xStep;
        }

        currentPos.y += yStep;

        if(rowCount == (inputGrid.size - 1)){
            offsetDirection *= -1;
        }
        rowLimit += offsetDirection * -1;
        offsetAmount -= offsetDirection;

    } // end of for loop
} // end of drawHexGrid()

每个六边形的实际绘制都在这个循环中:

private function drawHexTile(inputGraphics:Graphics, inputX:int, inputY:int, inputSize:int, inputTile:Tile):void {
    inputGraphics.lineStyle(0.1, 0, 1);

    var convertToRadians:Number = Math.PI / 180;

    // easier to draw by wall, since need to look up each wall and can set a starting degree without having to worry about the 'end degree'
    // (since the end may not be 360 degrees if the starting degree is in the negatives or a high degree)
    var degrees:int = -150; // starting wall is the top left wall of the hexagon tile
    for(var counter:int = 0; counter < 6; counter++){

        if(inputTile.walls[counter] == true){
            inputGraphics.moveTo(inputX + (Math.cos(degrees * convertToRadians) * inputSize), 
                                    inputY + (Math.sin(degrees * convertToRadians) * inputSize));

            inputGraphics.lineTo(inputX + (Math.cos((degrees + 60) * convertToRadians) * inputSize), 
                                    inputY + (Math.sin((degrees + 60) * convertToRadians) * inputSize));
        }
        degrees += 60;
    }

} // end of drawHexTile() method

乍一看,我认为问题在于浮点数学准确性,但我不确定如何修复/改进此问题。

有什么想法吗?

我知道我的绘图方法最终会产生许多重叠的线条,目前这很好。如果有帮助,整个代码适用于六边形迷宫生成器,它工作正常,因此可以忽略,因为它不是问题的一部分。

如果有帮助,我如何存储六边形图块只是在一个长数组中,索引如下:

where n=4

             0       1       2       3
         4       5       6       7       8
     9      10      11      12      13      14   
15      16      17      18      19      20      21
    22      23      24      25      26      27   
        28      29      30      31      32
            33      34      35      36

【问题讨论】:

  • 虽然不适合您的最终产品,但请尝试将所有 int 值更改为 Num 值。走着瞧吧。还要关注处理每个新图块的 X 位置的代码。
  • ……呃……这行得通。我不知道为什么。 =|我刚刚对 Numbers 的整数进行了全局替换,它起作用了。嗯,将返回并手动替换以查看确切的 int 变量。
  • 哦!我想到了。在 drawHexTile() 中,我将 inputX 和 inputY 设置为 int 类型。但实际上,计算的位置是浮动值,因此它们被四舍五入到整数,这隐含地导致了错位。简单的错误(通过反射),毕竟修复中没有涉及任何魔法。如果您将您的评论重新发布为答案,我会将其标记为已接受。

标签: actionscript-3 drawing hexagonal-tiles


【解决方案1】:

虽然不适合您的最终产品,但请尝试将所有 int 值更改为 Num 值。走着瞧吧。还要关注处理每个新图块的 X 位置的代码。

来自您的 cmets

……呃……这行得通。我不知道为什么。 =|我刚刚对 Numbers 的整数进行了全局替换,它起作用了。嗯,会回去手动替换看看到底是什么int变量做的。

哦!我想到了。在 drawHexTile() 中,我将 inputX 和 inputY 设置为 int 类型。但实际上,计算的位置是浮动值,因此它们被四舍五入到整数,这隐含地导致了错位。简单的错误(通过反射),毕竟修复中没有涉及任何魔法。

【讨论】:

    【解决方案2】:

    在您的 drawHexTile 中看起来像一个浮点问题。您是否尝试过四舍五入您的绘图坐标,以便您始终拥有一个圆形像素坐标?类似的东西

    inputGraphics.moveTo(Math.floor(inputX + (Math.cos(degrees * convertToRadians) * inputSize)), Math.floor(inputY + (Math.sin(degrees * convertToRadians) * inputSize)));
    
    inputGraphics.lineTo(Math.floor(inputX + (Math.cos((degrees + 60) * convertToRadians) * inputSize)), Math.floor(inputY + (Math.sin((degrees + 60) * convertToRadians) * inputSize)));
    

    【讨论】:

    • 我也尝试过。用于绘制和定位瓷砖的各个点的地板、圆角、天花板等。我似乎在间距中也看不到任何图案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    相关资源
    最近更新 更多