1

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.

  • What's the formula for tile_h? At a guess I think the problem is that you need to handle odd and even numbers of tiles differently. horiz_dist is only going to be 1.5 averaged over 2 tiles unless I'm misunderstanding it. Also please explain why you multiply width by 1/4 but height by 1/2 – samgak Aug 05 '16 at 12:51
  • Hi samgak. tile_h was truncated from tile_height, sorry, didn't spot that. I add 1/4 width because the first column is exactly one tile wide, every succeeding column adds 3/4 width. For height, every even row adds 1 width, and if (and only if, see aichao's answer) my odd columns have the same height as the even columns, then the odd rows add another half height to the total. You can seed that on the pictures in the link I provided. – user3410194 Aug 10 '16 at 09:28

1 Answers1

1

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.

aichao
  • 7,375
  • 3
  • 16
  • 18
  • Thanks... you're right. The number of odd columns was one less than number of even columns, hence the distortion. – user3410194 Aug 10 '16 at 09:24