This experiment is based on matsys pseudo-code, which is not completely self explained. Nevertheless I found the way to fill the gaps crating a mixture between the 2 algorithms. Circle Packing has different applications, The pseudo code and algorithm showed below is focused in Unequal circles (random radius).
According to Wikipedia:
There are also a range of problems which permit the sizes of the circles to be non-uniform. One such extension is to find the maximum possible density of a system with two specific sizes of circle (a binary system). Only nine particular radius ratios permit compact packing, which is when every pair of circles in contact is in mutual contact with two other circles (when line segments are drawn from contacting circle-center to circle-center, they triangulate the surface). For seven of these radius ratios a compact packing is known that achieves the maximum possible packing fraction (above that of uniformly-sized discs) for mixtures of discs with that radius ratio. All nine have ratio-specific packings denser than the uniform triangular packing, as do some radius ratios without compact packings.
It is also known that if the radius ratio is above 0.742, a binary mixture cannot pack better than uniformly-sized discs. Upper bounds for the density that can be obtained in such binary packings at smaller ratios have also been obtained.
CIRCLE PACKING ALGORITHM
- Input: Maximum radius, boundary, iterations (not necessary the number of circles).
- Add in a random position, a circle with the maximum radius. Which is the maximum space that the circle can fill up.
- Add a Random Point.
- Test if the random Point is inside of the circle created. Else, delete the point and add another random point until the point is outside.
- Add line from the point to the center of the circle. If the distance is greater than the maximum radius add a circle at that point with the maximum radius. If the distance is less than the maximum radius, add a circle with the measured distance.
- Add another point and test if this point is within the other circles.
- Add a line to every center circle to find the closest circle.
- Repeat from step 5 until the number of iterations is reached.
Option Explicit 'Script written by Carlos de la Barrera 'Script copyrighted by Carlos de la Barrera Call Main() Sub Main() Dim Pt, R Pt = Array(rnd * 100, rnd * 100, 0) R = FuncCir(Pt, 10) Call Pack(R) End Sub Function Pack(R) Dim Pt, i, count count = Rhino.GetInteger(" number of circles ", 50, 2, 1000) If IsNull (count) Then Exit Function Dim ArrData() For i = 0 To count ReDim Preserve ArrData(i) ArrData(i) = R Pt = Array(Rnd * 100, rnd * 100, 0) Dim j Dim t: t = 0 For j = 0 To UBound(ArrData) If Rhino.IsPointOnSurface(ArrData(j)(1)(0), Pt)Then Call Rhino.print ("point in surface") t = t + 1 End If Next If (t = 0) Then ReDim ArrLine(UBound(ArrData)) Dim k, line For K = 0 To UBound(ArrData) line = Rhino.AddLine(Pt, Rhino.CircleCenterPoint(ArrData(k)(0))) ArrLine(k) = Line Next Dim d, d2, l d = funcDist(Pt, ArrData(0)(0), ArrLine(0)) For l = 0 To UBound(ArrLine) d2 = funcDist(Pt, ArrData(l)(0), ArrLine(l)) If d < d2 Then 'Call Rhino.Print ("nothing") Else d = d2 End If Next R = FuncCir(Pt, d) Call Rhino.DeleteObjects (ArrLine) End If Next End Function Function FuncCir(p, D) If D >= 10 Then D = 10 End If Dim plane Dim R(1) plane = Rhino.PlaneFromFrame(p, Array(1.0,0.0,0.0), Array(0.0,1.0,0.0)) R(0) = Rhino.AddCircle(plane, D) R(1) = Rhino.AddPlanarSrf(Array(R(0))) FuncCir = R End Function Function funcDist(Pt, circleP, Line) Dim Ap, j, d Ap = Rhino.CurveCurveIntersection (circleP, Line) For j = 0 To UBound(Ap) d = Rhino.Distance(Pt, Ap(j, 1)) Next funcDist = d End Function
Test with bigger radius, 10,000 iterations and the max radius is 500
The number of iterations is 4,000, which is approximate the number of circles included in the packing. Max radius is 100
It's not difficult to implement spheres instead circles in the algorithm
The process runs very similar way
Close up to the sphere packing