PSTricks 或其他人是否可以在不进行额外计算的情况下绘制两个“不相交”圆的 4 条公切线?

PSTricks 或其他人是否可以在不进行额外计算的情况下绘制两个“不相交”圆的 4 条公切线?

有两个不相交的圆。它们的圆心和半径都已给出。无需进行额外计算,我们可以使用 PSTricks(首选)或其他工具绘制 4 条切线吗?

我询问了许多 Illustrator、Free-hand、CAD 专家,他们都无法做到这一点。:-)

答案1

pstricks-add知道一个宏,用于计算并保存 10 个点作为节点,两个中心点和每个圆上的四个点。请参阅文档 (run texdoc pstricks-add) 以了解名称:

\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}

在此处输入图片描述

答案2

TikZ 可以计算出圆和点之间的切线,所以这已经完成了一半。通过一点点数学运算,就可以将其引导到您想要的切线。以下代码将做到这一点(尽管它应该检查两个半径相同的情况 - 目前,这将产生错误,圆重叠的情况也会产生错误)。

结果如下:

切线

代码如下:

\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}

注释掉的线将绘制切线到精确的点,我选择稍微延长它们以显示它们确实是切线,这就是代码注释掉的行用于。

尽管我是一名数学家,但我并没有真正计算出交叉点的公式——我只是猜测了一些“感觉正确”的东西,然后测试了一下,似乎有效。然而,我不能保证它正确的。

答案3

tkz-euclide 的下一个版本可以绘制切线。我为两个圆的内部相似中心和外部相似中心创建了两个宏。

\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}

获取这些中心的代码非常简单:

%<--------------------------------------------------------------------------–> 
%                    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
}

然后我们就可以得到切线了。代码将在几天内上传到 ctan 服务器上。

在此处输入图片描述

答案4

最近我看到这个老问题出现了(因为有人编辑了评论的答案之一),我觉得应该用 MetaPost 来解决这个问题。这就是它 — 一个“规则和指南针”解决方案。

由于 MetaPost 中没有提供通过外部点的圆的切线的原生宏,因此我创建了自己的宏,并用它来解决一般问题。诀窍是考虑两个圆是同位的(因此相似),并找到相应同位的中心(如果存在)。该程序考虑了两个圆共享相同半径的情况。

% 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.

一般情况

两个半径相同的圆

相关内容