I seem to be having a bit of trouble drawing a proper hex grid:
As you can see, the hexagons are just slightly misaligned, though I believe my math is correct (some of which is verfied via http://www.redblobgames.com/grids/hexagons/).
My method of drawing is to start at the top left hexagon (first tile in the first row) and draw that row of tiles. Then for the next row, there is a negative X offset and positive Y offset, etc until it reaches the middle row, at which the X offsets increase until 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()
The actual drawing of each hexagon is in this loop:
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
At first glance, I think the issue is due to floating point math accuracy, though I'm not sure how to go about fixing/improving this.
Any ideas?
I am aware that my drawing method would end up with many overlapping lines, which is fine for the moment. If it helps, the overall code is meant for a hexagon maze generator, which is working fine and thus can be ignored as it isn't part of the problem.
And if it helps, how I am storing the hexagon tiles is just in one long array, indexed like this:
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