3
\$\begingroup\$

I have been using @amitp's excellent guide (and javascript library) to create a hexagonal grid system https://www.redblobgames.com/grids/hexagons/. I'm using flat-top, inverse-y cubic/axial system. However, I have elements that are located on the vertices, rather than "within" a tile. How would I refer to their position? I have considered using the index of the corner, but then the question is which tile do I use as my base? I would also like to extend the concept so that I could precisely position an element anywhere within a tile. I am thinking of something relating to the Ordnance Survey's method of sub-division within the British National Grid (OSGB 1936) but I cannot get my head around how this relates to a cubic/axial coordinate system.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Maybe not the most elegant way, but if you refer the coordinate as a tripled of the 3 tiles, you dont have the problem of deciding which one is the base tile and you always can refer to the corner. For the side you just need to refer two tiles, for within a single tile with the offset \$\endgroup\$
    – Zibelas
    Commented Feb 13, 2020 at 9:28
  • 1
    \$\begingroup\$ An interesting idea but effectively that results in a fairly complex and inconsistent data storage: [q,r,s] for centre of tile; [[q,r,s],[q,r,s]] for edge; [[q,r,s],[q,r,s],[q,r,s]] for vertex. And I'm still none the wise how to do the offset within a tile. And as for calculating distances between these... \$\endgroup\$ Commented Feb 13, 2020 at 9:54
  • \$\begingroup\$ Possible duplicate: gamedev.stackexchange.com/questions/167628/… \$\endgroup\$
    – Max
    Commented Feb 13, 2020 at 21:15

4 Answers 4

1
\$\begingroup\$

I have considered using the index of the corner, but then the question is which tile do I use as my base?

In an (infinite) hexagonal grid, every hex got 6 adjacent vertices and every vertex is shared by 3 adjacent hexes. That means that if you want each vertex to "belong" to one and only one hex, then each hex would have to "own" two vertices. That way every vertex would have an "owner". Which two vertices? That's up to you. If you choose the same two vertices of each hex (the upper pair, the lower pair, left&right, or any other), then you will notice that every vertex now clearly belongs to a hex.

Unless, of course, if you have a finite grid. Then you would have vertices at the border which would need to be owned by a "virtual" hex that's outside of the grid. But that's a problem you have with rectangular tiles as well.

That means you can address every vertex by the address of its owning tile, plus an additional bit for "left vertex" or "right vertex".

I would also like to extend the concept so that I could precisely position an element anywhere within a tile.

In that case I would use a sub-coordinate system for position within the tile. For consistency, I would recommend to use the same axis conventions as you are using for the tiles themselves. But that might depend on your requirements and personal preference.

\$\endgroup\$
0
\$\begingroup\$

Only regarding your first question

but then the question is which tile do I use as my base?

ANY as long as you use a consistent scheme. For example ALWAYS find the leftmost tile (you need phantom extra ones for the edge of your map), and then (if applicable) the topmost of the two possible ones.

And then you only have one line (with a bent) on which to place any objects

\$\endgroup\$
0
\$\begingroup\$

An answer depends on a couple of facts: Can your elements only rest on vertices? If not can they move from a vertex of a hex to the center of that hex?

My first thought on this question was to set each vertex's coordinates to the average of the coordinates of the 3 hex' surrounding it, for instance, if a unit was on the vertex between the three tiles [0, 0], [0, -1] and [+1, -1] it would have the coordinate [0.5, -1].

But this results in two issues: one the vertex coordinates aren't unique when compared to the hex coordinates (There is a [-2, +1] tile and its rightmost vertex is also [-2, +1]) and two, referring back to my questions, if the elements can move from vertices to hex center's then when working out the distance becomes weird. Basically the distance from a vertex to an adjacent vertex is 1, from a vertex to one of the connected hexes' centers is also 1 and from a vertex to another vertex that is 2 vertices away (i.e. with flat top hexes from the left most vertex to the top right vertex) is a distance of 1.5 .

In other words the distance from hex to hex becomes equal to that from vertex to vertex with a couple twists.

Hopefully this helps, if you need images to show what I'm describing I can create them but I would rather wait for you to ask for them first.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ While exploring other questions I came across this link also on @amitp 's bog. If you scroll down to Hexagon Grids he gives an example of a hexagonal coordinate system with vertices \$\endgroup\$
    – Ironcanon
    Commented Feb 14, 2020 at 12:45
  • \$\begingroup\$ Isn't the average in your first example (⅓, -⅔), not (0.5, -1)? If you calculate it this way, the coordinates are indeed unique at the vertices, and the distances are actually uniform. I think the technique shown at the link you shared would be worth summarizing in an answer. \$\endgroup\$
    – DMGregory
    Commented Jul 13, 2020 at 10:49
0
\$\begingroup\$

Maybe I'm late, but I'm having similar problems, so here's my 6 cents

If you think about it, you can refer to the corners as neigbors of the center of the hexagon, and the actual neighboring hexagons then become diagonal neighbors. That is, you get a pointy top subdivided coordinate system. And you can easily make it by taking a (hex)vector, rotating it in some direction, and adding the rotated one to the original. You can simplify it to a very cheap calculation, and here's my implementation of it (c#):

GetSubdividedVector(HexVector v) => new(v.q - v.r, v.r - v.s, v.s - v.q);

This will work great. Take note, that the new vector will have a smaller Size, (Size * (sqrt(3)/3)) to be exact.

I'm using this system to consistently label corner verticies and check overlapping positions as floating point errors would make it impossible after converting to world space.

Now tho, good luck reversing the process, that's what I'm struggling with rn 😅

\$\endgroup\$
2
  • \$\begingroup\$ Want to post a question about the part you're struggling with? \$\endgroup\$
    – DMGregory
    Commented Dec 3, 2023 at 10:00
  • \$\begingroup\$ @DMGregory nah, I think I'm gonna manage. Maybe I will if it turns out that I don't \$\endgroup\$
    – MrDoboz
    Commented Dec 3, 2023 at 10:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .