Hmm. I think generating the centers is not so hard. All the centers for one triangular section lie along the points
(x,y) = i * u1 + j * u2
where (i,j) are nonnegative integers and the basis vectors u1 and u2 are:
u1 = (1,0)
u2 = (1/2, sqrt(3)/2)
There is a 1:1 correspondence of (i,j) to centers, so you could generate all centers with a nested for loop.
If you want to generate all centers in the hexagon (not just the triangle) and still preserve the 1:1 nature of the map from (i,j) to (x,y), you could just rotate 6 times by 60 degrees each time.
Doing just this would introduce duplicates along the edges, where the triangular segments abut each other. You could eliminate those by insisting that i>0 rather than just i>=0.
You could get the same effect as rotation by introducing a third basis vector u3, but then there would be duplicates in the map from (i,j,k) -> (x,y).
That's smart - coupling this with the 'min layers' equation could lead to a 100% iterative solution. We could swap this component in and remove the recursive triangle generation :)
As mentioned in the post - deduping is cheap and easy so introducing the third basis vector u3 could potentially be a great move away from the recursive logic that currently plagues the project.
The above is known to be the optimal 2D packing for equal-size circles. If you want to geek out, consider an algorithm for the optimal packing for unequal-size circles. Say, if there is an importance or frequency measure associated with each plotted circle. Now you've got yourself a math problem.
If you want to generate all centers in the hexagon (not just the triangle) and still preserve the 1:1 nature of the map from (i,j) to (x,y), you could just rotate 6 times by 60 degrees each time.
Doing just this would introduce duplicates along the edges, where the triangular segments abut each other. You could eliminate those by insisting that i>0 rather than just i>=0.
You could get the same effect as rotation by introducing a third basis vector u3, but then there would be duplicates in the map from (i,j,k) -> (x,y).