Given a list of circles of different areas, I need to arrange them tangentially in order of increasing area and spiraling outward. An example of the type of packing I'm attempting is shown by the orange circles in the figure below:
Is there a concise way to calculate the centers of the circles?
Answer
Here's my version. I don't know how fast/slow it is compared to the other solutions, but at least is shortish.
spiral[rlist_ /; Length[rlist] >= 2] := Module[{findCentre},
findCentre[zlist_] := Module[{coslst, theta, ind, k},
k = Length[zlist] + 1;
coslst = Table[
With[{dist = N@Norm[zlist[[-1]] - zlist[[l]]]},
((rlist[[k - 1]] + rlist[[k]])^2 - (rlist[[k]] + rlist[[l]])^2 + dist^2)/dist],
{l, k - 2}]/2/(rlist[[k - 1]] + rlist[[k]]) ;
ind = Flatten[Position[coslst, a_?NumericQ /; Abs[a] < 1]];
theta = Min[Mod[#, 2 Pi,
ArcTan @@ (zlist[[-2]] - zlist[[-1]])] &@(-ArcCos[
coslst[[ind]]] + (ArcTan @@ (# - zlist[[k - 1]]) & /@
zlist[[ind]]))];
zlist[[k - 1]] + (rlist[[k]] + rlist[[k - 1]]) {Cos[theta], Sin[theta]}];
Nest[Append[#, findCentre[#]] &, {{0, 0}, {Total[rlist[[;; 2]]], 0}}, Length[rlist] - 2]]
testList = Union@RandomReal[{1, 10}, 50];
result = spiral[testList];
Graphics[MapThread[Circle, {result, testList}]]
Comments
Post a Comment