Fill Circles Node
Fill_Circles is the official version of the circle packing nodes developed with Floris using Claude AI. For more about that see:
http://support.nodebox.net/discussions/general-discussion/15337-ai-...
Floris and I (mostly Floris) made a lot of progress with this. The version I shared in May was producing good results, but still had a few issues, partly due to a rather fuzzy idea about exactly what we were trying to accomplish. With further development stalled and my desire to wrap things up for the next release of my library, I decided to make one small change and finalize this version.
I renamed the node from pack_circles to fill_circles partly to make a clean break with earlier versions, but mostly because I don't think this node is a true circle packer. That term is used in various ways, but in general it refers to "circles (of equal or varying sizes) on a given surface such that no overlapping occurs and so that no circle can be enlarged without creating an overlap" (Wikipedia). In practice this means that all the circles are touching each other (each circle is tangent to at least one other circle). Circle packing tools and libraries size the circles to fit within a certain boundary, but do not necessarily try to press against the edges of that boundary (except for mathematical puzzles in which the boundary is more of a factor).
Our fill_circles node does something a little different. It seeks to fill a given shape with circles. Even with no padding, most of those circles are not touching each other, and it does not even try to approach the maximum density theoretically possible for a given shape. But it generally does a good job filling up the shape's interior, which can produce some interesting effects for generative artists. And because it can optionally size the circles in proportion to a list of values, it is great for data visualizations.
Fill_circles take 6 parameters:
- Boundary - The shape containing the circles
- Values. A list of relative sizes (OPTIONAL)
- Total circles. If no values supplied, the number of uniform circles desired. Ignored if Values list is supplied.
- Padding. Minimum space around each circle (in pixels)
- Max Attempts. The maximum number of attempts. More attempts may increase the size of the circles and thus increase density within the container.
- Seed. Each seed generates a different arrangement. Some arrangements will have higher densities.
If values are supplied, they determine the relative area of each circle, and the circles returned are sorted from largest to smallest . So if you want to maintain an association between specific values and specific circles (as you would need to do in a data visualization), you will want to sort your values before submitting them.
For the demo I fill a lower case 'a' with 200 circles sized proportionally to a list of 200 random values between 10 and 100. You can change the values list, disconnect it to use some number of uniform circles, alter the seed or padding, or try other boundary shapes to see what happens.
You can sometimes improve the density of circles by increasing the number of Max Attempts. The default of 200 attempts may already be a tad slow (depending on the shape and the number of circles); increasing it will further slow performance, so it's up to you to make that tradeoff. Regardless of the number of attempts, the density will not exceed 50% for rectangular boundaries, and will rarely exceed 55% for other shapes. The algorithm only achieves a few distinct levels of density (typically around 50%, 42% or 36%); changing the seed alters circle positioning and can make the density jump up or down, but does move density from these levels. Once you get an acceptable density (within these limits), you can then try decreasing max attempts to see how much you can improve performance.
I think both the efficiency and density could be improved with a more sophisticated algorithm. But densities which approach the theoretical limits for a given shape tend to have a more uniform layout and may be less aesthetically pleasing. In practice I find that fill_circles does a pretty decent job in most situations.
Fill_circles requires the circle_pack.py external library (included).
Note to Floris: circle_pack.py is just a renamed version of pack_circles_v2 with one small change. I modified the Python code to remove the boolean "ensure_all_fit" argument, since we're no longer using that option. I maintained our earlier versioni numbering system, now 3.7.3, for the core node inside the fill_circles subnetwork and in the comments of the Python code, in case there are any further changes before my library is released.
Also, I included a credit node inside fill_circles mentioning the work you did with Claude on this, but somehow managed to misspell your name. I fixed that for the official version soon to be released in Library 3.7. Sorry about that. And thanks again for your work on this.
-
fill_circles_screenshot.png
791 KB
- fill_circles_demo.zip 12.4 KB
Keyboard shortcuts
Generic
| ? | Show this help |
|---|---|
| ESC | Blurs the current field |
Comment Form
| r | Focus the comment reply box |
|---|---|
| ^ + ↩ | Submit the comment |
You can use Command ⌘ instead of Control ^ on Mac