3

I'm making a hexagon tile based game, which generates a honeycomb arrangement of hexagons in a spiral shape. My goal is to convert a world position (e.g. a mouse click) to a spiral coordinate (index / layer / position around layer). I can't think of how to do this, so instead I've been looking to simplify the problem by converting to/from axial coordinates first. How can this be done?

My configuration is pointy-topped as follows: spiral coordinates layer/position

And here are the spiral indexes: spiral coordinates index

Axial Coordinates for reference:

axial coordinates

I already have these equations for spiral coordinates:

const Layer = (index: number): number => {
    return Math.floor((3 + Math.sqrt(12 * index - 3)) / 6);
}
const Position = (index: number, layer: number): number => {
    return index - 3 * layer * (layer - 1) - 1;
}
const Index = (layer: number, position: number): number => {
    return 3 * layer * (layer - 1) + 1 + position;
}
Jomity
  • 56
  • 8

1 Answers1

2

You can check the individual cases as follows. Here L is layer, P is position, (x, y) are the axial coordinates; coordinates are in agreement with your images.

From (L, P) to (x, y):

if L == 0:
   return (0,0)

otherwise:
k = floor(P/L) mod 6
j = P mod L

k   x     y     z
-------------------
0   j     L-j   -L
1   L     -j    j-L
2   L-j   -L    j
3   -j    j-L   L
4   -L    j     L-j
5   j-L   L     -j

From (x, y) to (L, P):

z = -x-y
L = max(abs(x), abs(y), abs(z))

  x    y    z       P
------------------------
>=0  >=0              x
      <0   <0     L - y
>=0       >=0    2L + z
 <0   <0         3L - x
     >=0  >=0    4L + y
 <0        <0    5L - z

Disclaimer: I didn't test this.

You may also be able to fold some of the cases by exploiting the symmetry, but coding these directly may be easier, albeit a bit more verbose.

You already coded the functions to go between (L, P) and spiral.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • I think this is close, but when testing, I got a weird result. See: [images](https://imgur.com/a/Km3s1ag) – Jomity Jan 10 '23 at 17:45
  • 2
    @Jomity I don't think you coded it right; e.g. for `x=1`, `y=0`, we get: `z=-1`, `L=1`, and through the first case (`x>=0, y>=0`): `P=x=1`. So the value should be `(1,1)`, but in your first image you have `(-1,1)`. – Yakov Galka Jan 10 '23 at 19:25
  • Haha yes, my compiler failed to mention I had omitted all my `break` statements. My bad. Thank you!! – Jomity Jan 10 '23 at 19:50