Circle Packing - only one circle width on a non-flat surface

Hi There,

I would like to get my Kangaroo2 to circle pack on the given surface (or any surface):

  1. goal: one circle width
  2. goal: start with the bigger end, pack as many circles as possible

Unfortunately I have no clue how to achieve this.
Please see the screenshot where I put the first two circles by hand…

Thank you very much in advance for your help!

Post a file of what you have so far…

This is not a packing problem… this is a recursion thing. You’ll want to draw a circle tan-tan-tan with the three curves being the top chord of the surface, the bottom chord of your surface, and the previous circle. you could achieve this in code (obvs) but loopsnake or similar would work as well.


This could be set up with a combination of EqualLength and OnCurve Goals, but I tend to agree that it’s simpler approached with a more direct iterative approach.
It can even be done without scripting or plugins (a double data-dam lets you work around the cyclic data stream prevention):


“human paced manual light weight recursion”
nice concept / craft.

1 Like

Can we assume that this is essentially a bent paper tape? By that, I mean whether we can assume that it ‘was’ a two dimensional sheet with circles printed on it that was then bent and twisted in the third dimension but not stretched or compressed: local coordinate system distances and angles within the surface remained the same.

As Martin requested, a copy of the model and anything else you have would be helpful.

Hi Martin,
here you are
2023-11-14 - (36.2 KB)

As you can see, the circles (TTT) are not completely on the surface - but that should not be a problem.
Once I have the centers, I can drag them to the surface (nearest point).

Thank you very much for your answer!
And also for the double data-dam solution!
Unfortunately I didn’t get it to work because the TTT circle works only with a given point (so it knows on wich side to be created)

Can you maybe also give me a hint how to solve this issue with the OnCurve and EqualLength goals?
I studied hours on this problem so I would really enjoy to see this Kangaroo solution working :slight_smile:

Here is my GH file:
2023-11-14 - (37.6 KB)

Thanks a lot for your help!

You can take the current circle center and get the closest point on one of the rails, then shift it along a couple of radii in the direction of the curve tangent there, and use that as the point input to TTT.
I also added here auto refreshing data dams.
They’re also on a shorter delay than you can create normally through Grasshopper. (40.5 KB)


Absolutely beautiful - thank you!

Last question:
Is there a possibility to use the RepeatData to automatically end the loop if the length of the rail is reached?

You can make it stop adding circles to the list by checking distance to the end. You can’t make it stop the auto-refresh automatically though. (42.1 KB)

I should point out this isn’t really a ‘proper’ way to use Grasshopper and at some point it makes more sense just to write a short script.

1 Like

I tried to build this as an example - but yes, afterwards it would be interesting to find out what happens, if this is performed on a stretched surface.
Of course now the circles are placed quite adequate on the bent surface. the resulting center marks have to be dragged/projected on the surface - where I can create new corresponding circles.

Interesting question of yours (bent paper type):
What would happen if the circles are placed on a Möbius strip?

I thought that was what you were trying to build with your opening question.

Given my knowledge of Rhino (still in awe of what some of the folks here can get it to do, for example @danielpiker 's creative use of Grasshopper: my reaction was similar to that upon seeing Duff’s Device for the first time), the best I can come up with is treating it like a strip of paper and walking along the parameterization of each curve “printing” the extensions of the two curves of the circle onto the surface by envisioning a line segment perpendicular to both curves moving along their lengths.

The result would be one or two curves per circle (if you buffer you can get one per circle) which would lie within whatever tolerance you need of the actual surface.