# Mathematically positioning hexagons in a grid format

This topic is 2628 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm working on getting a grid using hexagons in a honeycomb pattern. Thanks to the work of the previous developer, here's where it stands in terms of layout:

http://imgur.com/BBDZB

The code is:

 generateTiles : function(f) { var xyz = [0,0,0]; var radius = 7; var max_out = 14; var deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]]; var output = "" for (var i = 0; i < radius; i++) { var x = xyz[0]; var y = xyz[1]-i; var z = xyz[2]+i; for (var j = 0; j < 6; j++) { for (var k = 0; k < i; k++) { x = x+deltas[j][0] y = y+deltas[j][1] z = z+deltas[j][2] f(x,y,z); } } } }, 

The f function that is called passes an x and y value for coordinates:

 var coords = [0,0,0]; this.x = function() { var x = (Math.sqrt(3) * (radius + 1) * (coords[2]/2 + coords[0])); return GridInterface.HexGrid.x_offset + x; }; this.y = function() { var y = (3/2 * (radius + 1) * coords[2]); return GridInterface.HexGrid.y_offset + y; }; 

The x/y offset values is the center of the grid.

What I want to achieve is to have it work when the hexagons are rotated 30 degrees, so the sides are flat at the top and bottom. When i rotate them now, the points are touching as supposed to being directly side by side. Any suggestions on how i can make this happen would be greatly apprecated.

##### Share on other sites

What I want to achieve is to have it work when the hexagons are rotated 30 degrees, so the sides are flat at the top and bottom. When i rotate them now, the points are touching as supposed to being directly side by side. Any suggestions on how i can make this happen would be greatly apprecated.

Ignoring some minor adjustments: swap x and y and just rotate 90° instead.

##### Share on other sites
Worked like a charm, thanks very much. Really need to brush up on my math to get better at this stuff .

##### Share on other sites
Hexagon are actually not really that hard, once you deconstruct them in your mind into a rectangle and two "tips".

Assuming your orientation has vertical sides and the tip at the top and bottom, some values you will need a lot are:

Calling the height of this "tip" A and the height of the rectangle B (and assuming that hexWidth is the width of the rectangle, ie. one edge to the opposite edge):

Precalculate sin of 60°, you will need it a lot:

[color="#000000"]A = hexWidth / (4 * sin60); [color="#000000"]B = 2*A;
TipToTip = 4*A
RowHeight = 3*A (or A+B.. note how A is the overlap of two rows)
The slope of the tip is: A / width => .25 / sin60

One piece of code I keep rederiving every time I use hex grids is mapping a point to hex coordinates (because I hate copy pasting stuff without understanding it, even if I copy from myself)

 //x and y are float coordinates, col and row are the grid coords (indices) of the hexagon const float sin60 = 0.8660254f; const float hexColumnWidth = cellSize_; const float hexRowHeight = .75f * cellSize_ / sin60; //In combination with the numbers above, this means the ratio width/height of a hexagon is 1/sin60 const float slope = 2.0f / 3.0f; //Needs to be relative to 3/4 of hexagon height ie. slope / hexRowHeight = (.5 * cellSize_ / sin60) / (.75 * cellSize_ / sin60) = 2/3 float hexSpaceY = y / hexRowHeight; row = floor(hexSpaceY); hexSpaceY -= row; //Every second row is offset by half a hex width (in this case to the right, so it has to be subtracted) float hexSpaceX = (x - (iy%2) * hexColumnWidth/2) / hexColumnWidth; col = floor(hexSpaceX); hexSpaceX -= col; //Now these ominous hexSpace coordinates are not grid coordinates, but imagine a rectangle around the hexagon excluding the bottom tip. The coordinates are relative to this rectangle (the vertex at the top would be [.5, 0] for example) //Upper left neighbor (ie. left half of the hexagon and above the top left edge (note that y-axis is top->bottom) if ( hexSpaceX < .5f && hexSpaceY < (.5f - hexSpaceX) * slope ) { --row; if (row%2) --col; //only in every odd row does "one left" equal a change of the column } //Upper right neighbor //Note how the slope is implicitely inverted by swapping hexSpaceX and .5 if ( hexSpaceX >= .5f && hexSpaceY < (hexSpaceX - .5f) * slope) { if (row%2) ++col; //in every even row "one right" equals a column change (hence we do the same test as above but BEFORE decrementing row) --row; }

There are probably smarter or more efficient ways to do it, but this is what I came up with this time. I have found that understanding the geometry of the hex and the ratios of its parts to be key if you want to feel comfortable with hexes. You might notice I didn't resort to a radius or any trigonometry at all. Ignoring the sin(60) which everything is based on and which is kind of weird, since basing it on A = hexWidth * .5 * tan(30°) would be a more obvious thing to do.

##### Share on other sites
An alternative way to label hexagons is to pick the center of one of the hexagons as origin, (1,0) is the hexagon to its right and (0,1) is the hexagon above it and partially to the right. You have to work with coordinates that are not orthogonal, but I haven't found any situations where that was a serious problem. I prefer to work this way, but it's probably a matter of personal taste.

##### Share on other sites

An alternative way to label hexagons is to pick the center of one of the hexagons as origin, (1,0) is the hexagon to its right and (0,1) is the hexagon above it and partially to the right. You have to work with coordinates that are not orthogonal, but I haven't found any situations where that was a serious problem. I prefer to work this way, but it's probably a matter of personal taste.

It sure is much more convenient than having to worry about odd and even rows (or columns). But assuming you want your grid as an overlay over a rectangular area, wouldn't you need to fix the coordinates by wrapping them? (Something like x = (x+y) % width )? Though in this particular case it probably doesn't matter, considering the layout of the hexes.

1. 1
2. 2
Rutin
19
3. 3
4. 4
khawk
14
5. 5

• 13
• 26
• 10
• 11
• 44
• ### Forum Statistics

• Total Topics
633743
• Total Posts
3013643
×