有两个不相交的圆。它们的圆心和半径都已给出。无需进行额外计算,我们可以使用 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.