0

I'm trying to pack hexagons, within bigger hexagons, as shown here:

enter image description here

For this example, I have 5 "children" to put in my "father" hexagon.

Each time I've got too many children, I would like to reduce the size (divide by 3?) of the children, to store more of them, as shown on this image (ignore the bad position quality):

enter image description here

Have you ever worked on this kind of problem? Is there any algorithm I could use to determine for a given hexagon size, the position for each new hexagon?

I've seen a lot of these algorithms for circle packing, but nothing for hexagon packing.

Thanks for your help

Vico
  • 1,696
  • 1
  • 24
  • 57
  • Possible duplicate of [Algorithm to generate a hexagonal grid with coordinate system](https://stackoverflow.com/questions/20734438/algorithm-to-generate-a-hexagonal-grid-with-coordinate-system) – Vico Sep 26 '19 at 13:41

1 Answers1

0

I've found exactly what I was looking for on this topic: Algorithm to generate a hexagonal grid with coordinate system

Thanks to the link above, here is the algorithm I used to generate a grid, itemCount is the number of hexes you need to put on your grid.

this.x and this.y are the origin of the main hex. this.radius is the radius of the main hex, in px.

generateHexGrid(itemCount) {
  let size = 0;
  let pushed = 0;

  /*
  `n` must be odd

    n | columns-per row sequence
    --+-------------------------
    3 | 2 3 2
    5 | 3 4 5 4 3
    7 | 4 5 6 7 6 5 4
    9 | 5 6 7 8 9 8 7 6 5
    */

  // This can be optimised to make it generic if you need more hexes
  if (itemCount <= 7) {
    size = 3;
  } else if (itemCount <= 19) {
    size = 5;
  } else if (itemCount <= 37) {
    size = 7;
  } else if (itemCount <= 61) {
    size = 9;
  }
  const radius = this.radius / size;
  const toReturn = [];
  const ang30 = 30 * (Math.PI/180);
  const xOff = Math.cos(ang30) * (radius);
  const yOff = Math.sin(ang30) * (radius);
  const half = Math.floor(size / 2);

  for (let row = 0; row < size; row++) {
    const cols = size - Math.abs(row - half);

    for (let col = 0; col < cols; col++) {
      const x = Math.ceil(this.x + xOff * (col * 2 + 1 - cols));
      const y = Math.ceil(this.y + yOff * (row - half) * 3);
      toReturn.push({
        x,
        y,
        radius,
      });
      pushed ++;
      if (pushed === itemCount) {
        return toReturn;
      }
    }
  }
  return toReturn;
}
Vico
  • 1,696
  • 1
  • 24
  • 57
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/24155049) – Markus Dresch Sep 26 '19 at 14:10
  • Sure sorry, let me update my answer – Vico Sep 26 '19 at 14:47