I'm rendering a grid of flat-topped hex tiles onto a HTML5 canvas. Placement and picking work flawlessly. At all times, the whole grid should be visible.
For this I calculate the minimum rectangle containing all hexagons completely and use its height and width to calculate the canvas size (letterboxed). To calculate the size I use the same coordinates I use to pick and layout the tiles and calculate:
tile_width = 2 // 2 * distance center-corner
tile_height = 1.7320508075688772 // sqrt(3) * distance center-corner
horiz_dist = 1.5 // 3/4 * tile_width
width = 1/4 * tile_width + number_x_tiles * horiz_dist
height = 1/2 * tile_height + number_y_tiles * tile_h
aspect = width/height
However, the displayed tiles are distorted, they are stretched in x-direction. Is there anything wrong with my formula? The measurements were derived as the fantastic redblob games resource describes it.
I'm pretty sure the function that applies x- and y-scaling depending on the aspect ratio works fine, as orthogonal maps look exactly as they should.
From your post, you seem to want a flat-topped grid. Given the information from your link,
tile_width = size * 2 = 2
tile_height = sqrt(3) * size = sqrt(3)/2 * tile_width = sqrt(3)
horiz_dist = (tile_width + size) / 2 = tile_width * 3/4 = 1.5
where size = 1
is the length of the edge of the hexagon.
Defining number_x_tiles
as being the number of odd columns and even columns in the grid, your computation for the grid width
is correct:
width = tile_width + (number_x_tiles - 1) * horiz_dist
= tile_width + (number_x_tiles - 1) * tile_width * 3/4
= tile_width - tile_width * 3/4 + number_x_tiles * tile_width * 3/4
= 1/4 * tile_width + number_x_tiles * horiz_dist
So the problem is in computing the grid height
. Your formula
height = 1/2 * tile_height + number_y_tiles * tile_height
is correct when the number of rows of hexagons in an odd column is the same as an even column (by convention say the first column is the even column and the second column is odd). If not, then you need to determine whether there are more rows of hexagons in the odd column versus even column. Therefore, the logic should be:
if (num_rows_in_odd_column == num_rows_in_even_column)
height = 1/2 * tile_height + number_y_tiles * tile_height
else
number_y_tiles = max(num_rows_in_odd_column, num_rows_in_even_column)
height = number_y_tiles * tile_height
Hope this helps.