I saw this old problem showing up recently (because someone edited one of the answers of comments), and I felt like making a MetaPost solution of it. Here it is — a "rule-and-compass" solution.
Since there is no native macro in MetaPost giving the tangents of a circle through an external point, I've created my own, which I use to solve the general problem. The trick is to consider that the two circles are homothetic (thus similar) and to find the centers of the corresponding homotheties (when existing). This program takes into account the case where both circles share the same radius.
% parameters
numeric u; u = 1cm; % unit length;
% For drawing straight lines, not segments
vardef straight_line(expr A, B) =
A + 1.5u*unitvector(A-B) -- B + 1.5u*unitvector(B-A)
enddef;
% Macro finding the point M of the circle such that (IM) is tangent to the circle
% and such that the angle (IC, IM) is positive
vardef tangent_point_circle(expr I)(expr C, r) =
save intersect, cercle; pair intersect; path cercle[];
cercle1 = fullcircle rotated (angle(C-I)) scaled 2r shifted C;
cercle2 = fullcircle scaled (abs(C-I)) shifted (.5[C, I]);
if cercle1 intersectiontimes cercle2 <> (-1, -1):
cercle1 intersectionpoint cercle2
fi
enddef;
% Macro taking care of the four tangents
def four_tangents_of_circles(expr C_a, r_a)(expr C_b, r_b) =
begingroup;
save I, J, w, C, r, circle; clearxy;
numeric r[]; pair I, J, C[], w[]; path circle[];
C1=C_a; C2=C_b; r1=r_a; r2=r_b;
for i=1,2:
circle[i] = fullcircle scaled 2r[i] shifted C[i]; draw circle[i];
endfor;
% Creating two intermediate radii for finding the centers of the homothecies
z1 = ((C1--C2) rotatedaround (C1,90)) intersectionpoint circle1;
w1 = z1 rotatedaround(C1, 180);
z2 = ((C2--C1) rotatedaround (C2, 90)) intersectionpoint circle2;
w2 = z2 rotatedaround(C2, 180);
if r1 + r2 < abs(C2-C1): % The circles must be distinct, otherwise nothing is done
% First couple of tangents (intersection located between the circles)
drawoptions(withcolor blue);
I = whatever[w1, w2] = whatever[z1, z2];
pair S[], T[];
for i=1,2:
S[i] = tangent_point_circle(I)(C[i], r[i]);
T[i] = S[i] reflectedabout(C1, C2);
endfor;
draw straight_line(S1, S2);
draw straight_line(T1, T2);
% Second couple of tangents (intersection located outside both circles)
drawoptions(withcolor red);
if r1<>r2:
J = whatever[w1, z2] = whatever[w2, z1];
pair S[], T[];
S1 = tangent_point_circle(J)(C1, r1);
T1 = S1 reflectedabout(C1, C2);
S2 = tangent_point_circle(J)(C2, r2);
T2 = S2 reflectedabout(C1, C2);
if r1 > r2:
draw straight_line(J, S1);
draw straight_line(J, T1);
else:
draw straight_line(J, S2);
draw straight_line(J, T2);
fi;
else: % (same radius)
draw straight_line(z1, w2);
draw straight_line(z2, w1);
fi;
fi;
endgroup;
enddef;
% Two examples in two separated figures
beginfig(1);
four_tangents_of_circles ((-u, 2u), 2u) ((3u, 3u), u);% illustration of the general case
endfig;
beginfig(2);
four_tangents_of_circles ((-u, 2u), 2u) ((5u, 2u), 2u);% two circles with same radius
endfig;
end.


tangentoption only that it can take two circles instead of a point and a circle? – Yossi Farjoun Dec 16 '10 at 11:40