# How can I pack circles of different sizes into a spiral?

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?

-
Vi Hart has a great little video on a related idea. No help with doing this problem, but it does put this kind of problem in and interesting light. youtube.com/watch?v=DK5Z709J2eo – Jagra Jun 14 '12 at 20:45
Could you post a minimal set of radii you want to have positioned (and perhaps how that should look like)? The image is somewhat more complicated than what your request implies and breaking down the problem may be helpful. – Yves Klett Jun 15 '12 at 13:25

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];


-
This works really well. +1 – Mr.Wizard Jun 18 '12 at 21:12
(* Position of a circle tangential to other two circles *)
pos[{{x1_, y1_}, r1_}, {{x2_, y2_}, r2_}, r3_] :=
(k = N@( ((x1 - x3)^2 + (y1 - y3)^2 == (r1 + r3)^2) &&
(x2 - x3)^2 + (y2 - y3)^2 == (r2 + r3)^2);
({x3, y3} /. FindInstance[k, {x3, y3}, Reals, 2])
)

(*Select the correct center*)
{Last@SortBy[Select[Flatten[Table[
pos[p, Last@prevCirc, currentCircRadius], {p, Most@prevCirc}], 1],
Im[#] == {0., 0.} && prevCirc[[-1, 1, 1]] #[[2]] - prevCirc[[-1, 1, 2]] #[[1]] <=0 &],