1. real getR(real R, real r) =   (R*r)/(R - r)  2. real getD(real R, real r) =   sqrt((R*R) +(r*r) +(R*r))  3. real getDist(real R, real r) =   sqrt((R*R) +(r*r) - (R*r))  4.  5. makeBubble(rA,rB,rD) {  6. — swap to make rA > rB > rD  7.  8. — use A and B to find bubble C  9. dAB =getDist(rA, rB)  10. rC =getR(rA, rB)  11. dAC =getD(rA, rC)  12.  13. — use A and D to find bubble E  14. dAD =getDist(rA, rD)  15. rE =getR(rA, rD)  16. dAE =getD(rA, rE)  17.  18. — use A and B to find bubble F  19. dBD =getDist(rB, rD)  20. rF =getR(rB, rD)  21. dBF =getD(rB, rF)  22.  23. — locate D at distance dAD,   rotate by angle BAD  24. thetaA = acos(((dBD*dBD)-(dAB*dAB) -(dAD*dAD))/(2*dAB*dAD))  25. dCenter = [dAD*cos(thetaA), -dAD*sin(thetaA)]  26.  27. — locate E on the line D-A  28. normDminusA = normalize(dCenter- [0,0])  29. eCenter = [0,0] + dAE * normDminusA  30.  31. — locate F on the line D-B  32. normDminusB = normalize(dCenter- [dAB, 0])  33. fCenter = [dAB,0] + (dBF * normDminusB)  34.  35. — make bubble spheres    36. bA = sphere([0,0], rA)  37. bB = sphere([dAB, 0], rB)  38. bC = sphere([dAC, 0], rC)  39. bD = sphere(dCenter, rD)  40. bE = sphere(eCenter, rE)  41. bF = sphere(fCenter, rF)  42.  43. — use CSG to make the cluster  44. — build the three outer sections  45. secA = bA - (bB + bD)  46. secB = bB - (bA + bD)  47. secD = bD - (bA + bB)  48.  49. — build the inner walls  50. secC = (bC inside bA) - bD  51. secE = (bE inside bA) - bC  52. secF = bF inside (bD intersect bE)  53.  54. cluster = group(secA, secB, secC, secD, secE, secF)  55.  56. — delete temporary objects  57. delete(bA, bB, bC, bD, bE, bF)  58.  59. return(cluster)  60. }