I'm trying to pack hexagons, within bigger hexagons, as shown 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):
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
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;
}