Get updates

Scott Hexmap Coordinates the Easy Way

When it comes to turn-based strategy games, I’ve long preferred hexes over a square grid. Naturally in working on my own projects I want to use hexes… but at first glance it seems the coordinate system for hexes must be much more complicated.

It’s actually easier than you’d think, I’ll show you how.

Hexmap Coordinate System

Determining coordinates for spaces in a hexagonal grid is relatively easy if you make a slight departure from Cartesian coordinates and slant one axis along the hex diagonal.

This neatly describes the hexes without needing additional work to accommodate the “staggered” rows that a strict Cartesian system would require.

Hex Movement Transforms

When moving a unit to a new hex using this system the coordinate transforms are pretty simple. Here, I’ll get you started:

Move N: y + 1
Move NE: x + 1, y + 1
Move SE: x + 1

I’m sure you can figure out the other three transforms.

Calculating Hex Distance

Distance in hexes from one hex to another is also reasonably simple to determine with this system.

Assuming there are no obstacles forcing an inefficient path (you are determining “straight line” distance) the calculation described by Stefano MacGregor is just what’s needed. I’ll paraphrase:

Distance is equal to the greatest of the absolute values of: the difference along the x-axis, the difference along the y-axis, or the difference of these two differences.

For example, from (1, 1) to (0, 3):
Δx = 0 - 1 = -1
Δy = 3 - 1 = 2
Δd = 2 - (-1) = 3 (greater than |2| or |-1|)
D = |3| = 3

-there’s a distance of three hexes.

Pretty easy. Now to convert between pixel coordinates on screen to this hex coordinate system is beyond the scope of this post… I may blog about that later, but in the meantime you could check out other articles on the topic such as Amit Patel’s take.

16 Responses to “Hexmap Coordinates the Easy Way”

  1. Thank you. Thank you. I’m working on a hex video game system and this is the first page on hex grids that actually made sense to me.

  2. Glad to hear it Devin, that’s what makes writing these posts worthwhile for me. Good luck with your game system!

  3. Joe Says:

    Thanks for this post. I’m working on programming a version of a board game and the game has a hex grid. BUT the ONLY thing the hex grid is used for is measuring distances between buildings. No paths, no movement, just distance. This is exactly the information I needed!

  4. You’re welcome, Joe. And if you ever write up anything about your board game project be sure to let me know!

  5. Todd Says:

    Hi, thanks so much for writing this very clear write-up. It seems like your technique should work the same for either “flat-top” or “pointy-top” hexes, but for some reason I can’t get it to calculate correctly when using pointy-top hexes.

    My code looks like this:

    int deltaX = x1 – x2;
    int deltaY = y1 – y2;
    int deltaDelta = deltaX – deltaY;
    int distance = abs(deltaDelta) > abs(deltaX) && abs(deltaDelta) > abs(deltaY) ?
    abs(deltaDelta) : abs(deltaX) > abs(deltaY) ? abs(deltaX) : abs(deltaY);

    I think that matches your explanation, though I’m not sure if my use of abs() is 100% correct. It almost works correctly, except it appears to be treating the x and y axes identically, when it should not.

    For example, when I calculate the distance from 2,2 to 4,1, I get:

    deltaX=-2, deltaY=1, deltaDelta=-3, distance=3

    Which is correct! However, when I calculate the distance form 2,2 to 1,4, I get:

    deltaX=1, deltaY=-2, deltaDelta=3, distance=3

    Which is incorrect- In a point-top hex board, that distance should actually be 2. Any idea what I’m doing wrong?

  6. If I’m not mistaken, there’s an incorrect assumption in your application of the coordinate axes to “pointy-top” hexes. When you turn the hexes you’ll also want to adjust the direction of the axes, at least to use this system.

    The point of this coordinate system is to allow the x and y axes to align with the hexes so they’re each hitting a hex face “flat side on”. You’ll want to make sure the way you’re drawing your axes they don’t hit hexes “point on”.

    If the axes-to-hexes alignment is right then the math shouldn’t change and 2,2 to 1,4 should indeed remain a distance of 3.

  7. Todd Says:

    Oh, I think I mis-communicated what I meant: by “point-top” hexes I mean what you get if you were to take either of your sample images above and rotate them 90 degrees in either direction.

    So the same exact type of hex-grid you’re using, but rotated 90 degrees. I’m trying to figure out if & how that would necessitate altering the algorithm you’ve explained here? Thanks!

  8. Mickael Says:

    Given these two points:
    a.x = 3
    a.y = 2
    b.x = 6
    b.y = 5

    The calculated distance between a and b is 3, but if I draw the 2 points on a hex map, the distance is 5. I don’t understand….

  9. Mickael:

    The distance is three, I think there’s a mistake in how you laid out your hex coordinates.

    Looking at the first image above, if you imagine the hex shown as 0,0 to instead be 3,2… the hex shown as 1,1 would be 4,3. Then 2,2 is 5,4, and 6,5 is one hex further in that same direction for a total distance of three. Hope that helps.

  10. Mickael Says:

    Thanks Scott for your time and answer :)
    I finally found the bug in my code :)

  11. Austin Says:

    This method doesn’t seem to work if the hex the start hex is 1,1 and the end hex is 2,2. The distance should be 2, but:

    deltaX = 2 – 1 = 1
    deltaY = 2 – 1 = 1
    deltaXY = 1 – 1 = 0

    Max of the set is 1. What am I doing wrong?

    Thanks for taking the time to clear to write a nice explanation, this is certainly helpful!

  12. Mickael Says:

    To me the distance is 1.

  13. Austin Says:

    Yep, you are correct. My y coordinates aren’t staggered like in the example.

  14. [...] Hexagonal Coordinates and Distance function [...]

  15. […] Hexagonal Coordinates and Distance function […]

  16. new balance 996 men

    Hexmap Coordinates the Easy Way – Development – 3DM Design

Leave a Reply

Fatal error: Call to undefined function show_subscription_checkbox() in /home/dmetro/ on line 90