Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating triangular/hexagonal coordinates (xyz)

I'm trying to come up with an iterative function that generates xyz coordinates for a hexagonal grid. With a starting hex position (say 0,0,0 for simplicity), I want to calculate the coordinates for each successive "ring" of hexagons, as illustrated here:

So far, all I've managed to come up with is this (example in javascript):

var radius = 3 var xyz = [0,0,0];  // for each ring for (var i = 0; i < radius; i++) {     var tpRing = i*6;     var tpVect = tpRing/3;     // for each vector of ring     for (var j = 0; j < 3; j++) {         // for each tile in vector         for(var k = 0; k < tpVect; k++) {             xyz[0] = ???;             xyz[1] = ???;             xyz[2] = ???;             console.log(xyz);         }     } } 

I know each ring contains six more points than the previous and each 120° vector contains one additional point for each step from the center. I also know that x + y + z = 0 for all tiles. But how can I generate a list of coordinates that follow the sequence below?

    0, 0, 0      0,-1, 1     1,-1, 0     1, 0,-1     0, 1,-1    -1, 1, 0    -1, 0, 1      0,-2, 2     1,-2, 1     2,-2, 0     2,-1,-1     2, 0,-2     1, 1,-2     0, 2,-2    -1, 2,-1    -2, 2, 0    -2, 1, 1    -2, 0, 2    -1,-1, 2 
like image 994
John Schulze Avatar asked Jan 12 '10 13:01

John Schulze


People also ask

How to calculate hexagon points?

Where A₀ means the area of each of the equilateral triangles in which we have divided the hexagon. After multiplying this area by six (because we have 6 triangles), we get the hexagon area formula: A = 6 * A₀ = 6 * √3/4 * a² A = 3 * √3/2 * a²

How many hexagons make a hexagon?

Hexagons have 6 sides and 6 corners. Each side is shared by 2 hexagons. Each corner is shared by 3 hexagons. For more about centers, sides, and corners, see my article on grid parts (squares, hexagons, and triangles).


2 Answers

Not only is x + y + z = 0, but the absolute values of x, y and z are equal to twice the radius of the ring. This should be sufficient to identify every hexagon on each successive ring:

var radius = 4;  for(var i = 0; i < radius; i++)  {      for(var j = -i; j <= i; j++)      for(var k = -i; k <= i; k++)      for(var l = -i; l <= i; l++)          if(Math.abs(j) + Math.abs(k) + Math.abs(l) == i*2 && j + k + l == 0)              console.log(j + "," + k + "," + l);      console.log("");  }
like image 112
Eric Mickelsen Avatar answered Oct 02 '22 18:10

Eric Mickelsen


Another possible solution, that runs in O(radius2), unlike the O(radius4) of tehMick's solution (at the expense of a lot of style) is this:

radius = 4 for r in range(radius):     print "radius %d" % r     x = 0     y = -r     z = +r     print x,y,z     for i in range(r):         x = x+1         z = z-1         print x,y,z     for i in range(r):         y = y+1         z = z-1         print x,y,z     for i in range(r):         x = x-1         y = y+1         print x,y,z     for i in range(r):         x = x-1         z = z+1         print x,y,z     for i in range(r):         y = y-1         z = z+1         print x,y,z     for i in range(r-1):         x = x+1         y = y-1         print x,y,z 

or written a little more concisely:

radius = 4 deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]] for r in range(radius):     print "radius %d" % r     x = 0     y = -r     z = +r     print x,y,z     for j in range(6):         if j==5:             num_of_hexas_in_edge = r-1         else:             num_of_hexas_in_edge = r         for i in range(num_of_hexas_in_edge):             x = x+deltas[j][0]             y = y+deltas[j][1]             z = z+deltas[j][2]                         print x,y,z 

It's inspired by the fact the hexagons are actually on the exterior of a hexagon themselves, so you can find the coordinates of 1 of its points, and then calculate the others by moving on its 6 edges.

like image 21
Ofri Raviv Avatar answered Oct 02 '22 19:10

Ofri Raviv