This may not be what you want but I thought it was interesting so I looked into it a little.
Below is a python script for the intersection of two bubbles. It takes a sphere as an input and from a given radius of a second sphere it calculates its position from the center (it's center is never on the first spheres surface unless they are exactly the same size). Then it places that bubble randomly on the surface (sphere symmetry, so no preferred position).
A third sphere is calculated which represents the intersecting surface. The 3 surfaces always create angles of 120 degrees between them.
I also attached a vopsop version that is more interactive but less transparent on the algorithmic side.
There is a solution for 3 bubbles but as far as I know there is no known exact general solution for n-bubbles, although people have “faked” it of course.
Here is the code. It's a bit flaky.
import math
import random
# This code is called when instances of this SOP cook.
geo = hou.pwd().geometry()
points = geo.points()
# Add code to modify the contents of geo.
#——Get radius——————-
def getRadius(nodename,sphere_name):
nodepath = nodename.path() + “/” + sphere_name
obj = hou.node( nodepath )
r = obj.parm(“radx”).eval()
v_pos = hou.Vector3()
return r, v_pos
#–Make Merge————————————–
def makemergenode():
nodename = hou.pwd().parent()
nodepath = nodename.path()
obj = hou.node(nodepath)
if hou.node(nodepath).glob(“mergebubble”) !

):
pass
else:
print “make merge”
obj = hou.node(nodepath)
merge = obj.createNode(“merge”,“mergebubble”)
merge.setDisplayFlag(1)
mergeobj = hou.node(“/obj/sphere_object1/mergebubble”)
print mergeobj, type( mergeobj)
for i in hou.node(nodepath).glob(“sphere*”):
mergeobj.setNextInput(i)
#
#–Make Sphere————————————–
def makesphere( name, center, radius ):
nodename = hou.pwd().parent()
nodepath = nodename.path() #+ “/” + sphere_name
if hou.node(nodepath).glob(name) !

):
pass
else:
obj = hou.node(nodepath)
bA = obj.createNode(“sphere”,name)
bA.setTemplateFlag(1)
# bA.insertInput( hou.node(nodepath+“/mergebubble”) )
pt =
pr =
pt.set(center)
pt.set(center)
pt.set(center)
pr.set(radius)
pr.set(radius)
pr.set(radius)
#——Calculate B sphere properties—————-
def makeB(vs,radii):
#make a new sphere
A, rA = vs,radii
rB = random.random()*rA
radii.append(rB)
rC = (rA * rB)/(rA-rB)
#find position of B
dAB = math.sqrt(rA**2 + rB**2 - rA*rB)
#knowing the AB distance we can randomly place B around A by converting to spherical coordinates
r = dAB
theta = random.random()*math.pi*2
phi = random.random()*math.pi
x = r*math.sin(theta)*math.cos(phi)
y = r*math.sin(theta)*math.sin(phi)
z = r*math.cos(theta)
B = hou.Vector3()
# find C
dAC = math.sqrt(rA**2 + rC**2 + rA*rC)
vAB = B - A
C = A + (vAB.normalized() * dAC)
dAC = math.sqrt( rA**2 + rC**2 + rA*rC )
# make sphere geometry
bubblename = “sphereB”+str(rB)
makesphere( bubblename , B, rB )
bubblename = “sphereC”+str(rC)
makesphere( bubblename , C, rC )
#—–MAIN———————————
def main():
nodename = hou.pwd().parent()
sphere_name = “sphere1”
r,v = getRadius(nodename, sphere_name)
radii,vs =,
for i in range(2):
makeB(vs,radii)
makemergenode()
nodepath = nodename.path()
# print hou.node(nodepath).glob(“sphere*”)
#—————————————-
main()
print “————”