Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

There are two disjoint circles. Their centers and radii are given. Without doing extra calculations, can we draw the 4 tangent lines using PSTricks (preferred) or others?

I asked many Illustrator, Free-hand, CAD experts, they cannot do it exactly. :-)

share|improve this question
2  
What do you mean by "without doing extra calculations"? –  Yossi Farjoun Dec 16 '10 at 9:05
    
@Yossi, without doing extra calculation means we don't need to do trigonometric calculations. I think you know what I mean. –  xport Dec 16 '10 at 11:11
    
Actually, I'm really not sure...is the answer given by Andrew good or did you hope for something like the TikZ tangent option only that it can take two circles instead of a point and a circle? –  Yossi Farjoun Dec 16 '10 at 11:40
    
This can be done by rule and compass. Some GUI grograms, like GeoGebra, Geometer's Sketchpad can draw such Euclidian geometry graphs easily. –  Leo Liu Feb 1 '11 at 16:11
add comment

4 Answers

up vote 26 down vote accepted

pstricks-add knows a macro for calculating and saving 10 points as nodes, the two central points and the four points on each circle. See the documentation (run texdoc pstricks-add) for the names:

\documentclass[pstricks,border=20pt]{standalone}
\usepackage{pstricks-add}% loads also pst-node

\begin{document}
\begin{pspicture}[showgrid](-2,-2)(10,10)
\pnodes(1,1){M1}(7,7){M2}
\pscircle(M1){1}\pscircle(M2){3}
\psCircleTangents(M1){1}(M2){3}
\pcline[nodesepA=-1cm,nodesepB=-4.5cm,linecolor=blue](CircleTO1)(CircleTO2)
\pcline[nodesepA=-1cm,nodesepB=-4.5cm,linecolor=blue](CircleTO3)(CircleTO4)
\pcline[nodesep=-1cm,linecolor=red](CircleTI1)(CircleTI2)
\pcline[nodesep=-1cm,linecolor=red](CircleTI3)(CircleTI4)
\psdots(M1)(M2)(CircleTC1)(CircleTC2)%
  (CircleTO1)(CircleTO2)(CircleTO3)(CircleTO4)%
  (CircleTI1)(CircleTI2)(CircleTI3)(CircleTI4)%
\end{pspicture}

\end{document}

enter image description here

share|improve this answer
    
This is a solution with no extra calculations! +1 Very nice! –  Yossi Farjoun Dec 17 '10 at 15:37
2  
Just out of curiosity: Did you just implement that feature/function? Two versions (that is 4 days - from ctan.org) back it did not exist. –  Carsten Thiel Dec 17 '10 at 15:55
1  
The solution in pst-eucl needs some understanding on how tangent lines are build. The tangents of two circles is the same as 2 times the tangents of a point and one circle. The macro \psCircleTangents from pstricks-add didn't need any understanding of the geometry behind the constructiong of the tangent lines. The package on texnik.dante.de are development versions and will be as soon as possible on CTAN when no problems are posted. –  Herbert Dec 17 '10 at 18:20
2  
from today it should be available by the TeXLive update manager. Read the documentation (run "texdoc pstricks-add") to see how the macro works for one circle and two circles. –  Herbert Dec 19 '10 at 8:04
1  
thanks. Indeed the documentation was written with hot needles ... I'll correct the typos –  Herbert Dec 19 '10 at 20:13
show 5 more comments

TikZ can work out the tangent line between a circle and a point, so it's halfway there for this. With a tiny bit of mathematics, this can be bootstrapped to the tangent lines you want. The following code will do it (though it ought to check for the case where the two radii are the same - at the moment, that will produce an error, as will the situation where the circles overlap).

Here's the result:

Tangent lines

Here's the code:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\rone}{3}
\pgfmathsetmacro{\rtwo}{2}
\pgfmathsetmacro{\mid}{\rone/(\rone + \rtwo)}
\pgfmathsetmacro{\out}{\rone/(\rone - \rtwo)}
\node[draw,circle,minimum size=2 * \rone cm,inner sep=0pt] (c1) at (1,0) {};
\node[draw,circle,minimum size=2 * \rtwo cm,inner sep=0pt] (c2) at (-1,-6) {};
\path (c1.center) -- node[coordinate,pos=\mid] (mid) {} (c2.center);
\path (c1.center) -- node[coordinate,pos=\out] (out) {}  (c2.center);

%\draw[red] (tangent cs:node=c2,point={(mid)}) -- (tangent cs:node=c1,point={(mid)});
%\draw[red] (tangent cs:node=c2,point={(mid)},solution=2) -- (tangent cs:node=c1,point={(mid)},solution=2);

%\draw[red] (tangent cs:node=c2,point={(out)}) -- (tangent cs:node=c1,point={(out)});
%\draw[red] (tangent cs:node=c2,point={(out)},solution=2) -- (tangent cs:node=c1,point={(out)},solution=2);

\foreach \i in {1,2}
\foreach \j in {1,2}
\foreach \k in {mid,out}
\coordinate (t\i\j\k) at (tangent cs:node=c\i,point={(\k)},solution=\j);

\foreach \i in {1,2}
\foreach \k in {mid,out}
\draw[red] ($(t1\i\k)!-1cm!(t2\i\k)$) --  ($(t2\i\k)!-1cm!(t1\i\k)$);

\end{tikzpicture}
\end{document}

The commented-out lines will draw the tangent lines to the exact points, I chose to extend them a little to show that they were genuinely tangent and that's what the code after the commented-out lines are for.

Despite being a mathematician, I didn't actually compute the formulae for the crossing points - I just guessed something that "felt right" and then tested it and it seems to work. However, I can't guarantee that it is right.

share|improve this answer
    
Fantastic...I was working on it myself...but you beat me to the punch! –  Yossi Farjoun Dec 16 '10 at 10:29
    
@Yossi: If you had a different implementation, you should still post it. –  Andrew Stacey Dec 16 '10 at 10:31
    
cheers, it is not significantly different, and much less neat...I like your answer. don't worry.. –  Yossi Farjoun Dec 16 '10 at 10:33
add comment

The next version of tkz-euclide can draw the tangent lines. I created two macro for the internal similitude center of two circles and the external similitude center.

\documentclass{scrartcl}
\usepackage[usenames,dvipsnames]{xcolor}  
\usepackage{tkz-euclide} 
\usetkzobj{all} 
\definecolor{fondpaille}{cmyk}{0,0,0.1,0}
\pagecolor{fondpaille}
\color{Maroon}   

\begin{document}  
\begin{tikzpicture}
   \tkzInit[xmin=-5,ymin=-5,xmax=5,ymax=5]
   \tkzDefPoint(0,0){O}
   \tkzDefPoint(4,-5){A}
   \tkzDrawCircle[R](O,3 cm)
   \tkzDrawCircle[R](A,2 cm) 
   \tkzIntSimilitudeCenter(O,3)(A,2) \tkzGetPoint{I}
   \tkzDrawPoint(I) 
   \tkzExtSimilitudeCenter(O,3)(A,2) \tkzGetPoint{J}
   \tkzDrawPoint(J) 
   \tkzTangent[from with R= I](O,3 cm)  \tkzGetPoints{D}{E} 
   \tkzTangent[from with R= I](A,2 cm)  \tkzGetPoints{D'}{E'}
   \tkzTangent[from  with R= J](O,3 cm) \tkzGetPoints{F}{G}
   \tkzTangent[from with R= J](A,2cm)   \tkzGetPoints{F'}{G'} 
   \tkzDrawSegments[color=red](I,D I,E I,D' I,E')   
   \tkzDrawSegments[color=blue](J,F J,G)
  \end{tikzpicture}     

\end{document}

the code is very simple to get these centers:

%<--------------------------------------------------------------------------–> 
%                    Internal Similitude center
%<--------------------------------------------------------------------------–>
\def\tkzIntSimilitudeCenter(#1,#2)(#3,#4){%
\begingroup
\path[coordinate]  (barycentric cs:#1=#4,#3=#2) coordinate (tkzPointResult);
\endgroup
}
%<--------------------------------------------------------------------------–> 
%                    External Similitude center
%<--------------------------------------------------------------------------–>
\def\tkzExtSimilitudeCenter(#1,#2)(#3,#4){%
\begingroup
 \path[coordinate]  (barycentric cs:#1=-#4,#3=#2) coordinate (tkzPointResult);
\endgroup
}

Then we can get the tangents. The code will be upload in a few days on the ctan servers.

enter image description here

share|improve this answer
    
Thanks for this solution. I am learning PGF/Tikz now because of its better syntax and one-step compilation. –  xport Mar 10 '11 at 1:08
    
@xport: I think it's a good experience. Andrew's solution is interesting too. My package will be updated in a few days beacause I have a lot of works on others packages. –  Alain Matthes Mar 10 '11 at 5:59
add comment

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.

general case

two circles with same radius

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.