Create a pattern like bubbles with 120 degree angles connections

I’ve been trying to figure out how to do this and I’m starting to thin it’s not possible with grasshopper.

Does anyone maybe have a solution. I tried voronoi but it’s not really resembling soup bubbles as it is using a variety of angles.

Thanks in advance,

1 Like

With only 120 degree angles it would be hexagon pattern with eqal area of each polygon. Soap foam is not only 120 degree, even at your picture.

1 Like

Foam soap is something like this:–Phelan_structure

What you’re suggesting would be a rounded hexagonal tiling, somewhere between regular hexagons and circles.

Here’s a way you could draw it. (There are faster ways to do it but I’m picking a method that’s easier to explain in words because I’m on my phone on a train.)

  1. Draw a regular hexagon, edge length, for example, 5 units.
  2. Copy it, paste it on top of itself, change its color to, for example, red, and lock it.
  3. Change the color of the unlocked hexagon to, for example, blue, and explode it.
  4. Scale1D each segment of the blue hexagon, with the origin at the midpoint. Scale it down to 0.01 units, giving you tiny new segments with a length of 0.02 units each.
  5. BlendCrv the segments to each other, and join them.
  6. Offset this new blue closed curve inward by, for example, 0.1 units. Delete the original. Make sure the new one is blue.
  7. Unlock your red hexagon, group it with your blue rounded hexagon. Copy-paste and Array as needed to create your pattern.
  8. SelAll, was ungroup, select a red hexagon. SelColor. Delete.

Again, there are much quicker ways to do this, especially using grids available in Grasshopper plugins. But this seemed like the easiest way to explain the broader idea.

It won’t look like soap. But it’ll have 120° Intersections and rounding like in the drawing you shared.

1 Like

They can be all 120° when the edges curve, as they do in a foam.
These are not just rounded hexagons either. In 2d the edges should be arcs.
This nice paper by David Eppstein describes a way of constructing these diagrams based on circle packings. I’ve been meaning for a while to have a go at implementing it.


Got it working.
All edges are arcs, and all junctions 120°

I’ll post the definition once I’ve cleaned it up a little


…and as this property is Möbius invariant, we can do this and it stays a valid bubble graph throughout:


thats neat

1 Like

That’s interesting. I didn’t realize that soap bubbles junctions are always 120 degree.
Here is similar pattern obtained by relaxed voronoi diagrams.

1 Like


That’s exactly it. Thank you so much Daniel.

Could you please post your definition if you have it?

Hi Daniel,

Would be able to share your definition for this?

Even if i’s a bit messy it would be really great to see!!

Aideen (16.3 KB)
Here’s a basic definition. It uses Kangaroo to find a triangular mesh with tangent incircles, then there’s a script to find the first isodynamic point of the pedal triangle of the incenter of each triangle.


bubbles00000 (25.0 KB)
I updated this so that the circle packing mesh is kept tangent to a circle, and the outer arcs of the boundary bubbles are included.
Angles at the nodes are always exactly 120°. Makes me wonder how well it would work to cut some flexible pipes to the arc lengths and connect them with a standard joint like this…


What are the requirements of input mesh? I’ve tried apply it to other mesh made from triangles but it gives solver component error.

For the bubble graph construction above you need a circle packing (which can be generated from a triangulated mesh with tangent incircles). If you want to generate the outer bubble edges too, this circle packing also has to be tangent to one circle enclosing all the others (or equivalently, be a circle packing that covers a sphere, because we can transform between the two via stereographic projection).

It is possible to generate such a circle packing mesh for any triangulated mesh.
Practically though, the definition above might sometimes need a bit of extra guidance to stop the mesh folding over itself and getting stuck on its way to this circle packing optimum.
Which is why in the bubblegraph2 definition I posted above, you’ll see a slider connected to the ‘Rod’ goal, and set to 0.
When you start the relaxation with this set to some positive value, this gives the boundary some stiffness, which can help stop the mesh distorting too wildly at first.
However, this rod goal also prevents it from reaching a true circle packing. So the idea is to start with it up, then slide it down to zero. Guiding the mesh in to a gentle landing, so to speak.
For some more complex meshes it may be though that some other strategy is needed here. If you have an example of one that isn’t working I can take a look.

3dm in attachment. I’ve made it from LunchBox triangle paneling tool. I’ve tried also SimpleRemesh but I’ve always got this error.
bubble_test_12-11-2019.3dm (164.5 KB)

It looks like it just needs cleaning up to get rid of duplicate vertices. You can do this with the Combine&Clean component. Also, if using the boundary circle, it helps to position it relative to the initial mesh, so it encloses it with a slight border: (30.1 KB)

Nice but is it possible to limit it to surface boundary. I want to wrap it on 3d surface later. I’ve tried to make it directly by circle packing on 3d surface but grasshopper stops respond like on infinite loop.