![使用 calc:通过 tikz 绘制椭圆路径的切线](https://linux22.com/image/294591/%E4%BD%BF%E7%94%A8%20calc%EF%BC%9A%E9%80%9A%E8%BF%87%20tikz%20%E7%BB%98%E5%88%B6%E6%A4%AD%E5%9C%86%E8%B7%AF%E5%BE%84%E7%9A%84%E5%88%87%E7%BA%BF.png)
我想知道是否可以使用 tikz 绘制从点到椭圆路径的切线。实际上,对于圆形路径,这可以很容易地完成,如 tikz-pgf 手册中所述,但对于其他路径,这不是一项简单的任务。
我曾尝试借助一些线程来解决这个问题,但不幸的是,我的解决方案依赖于一些数学背景。我想知道我是否可以用纯 tikz。
以下是我的解决方案:
\documentclass{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc,intersections,arrows}
\usepackage{times}
\begin{document}
\begin{tikzpicture}[scale=1,>=latex',scale=1.5,outer sep=0,inner sep=0,line width=0.7pt]
\def\a{2} \def\b{1} % radii of Ellipse
\def\cx{0} \def\cy{0} % determines center of Ellipse
\def\xp{0} \def\yp{-5} % coordinates of point P
\coordinate (P) at (\xp,\yp);
\coordinate (A) at (0,\b); % up
\coordinate (B) at (0,-\b); % down
\coordinate (C) at (\a,0); % right
\draw[name path=ellipse,fill=gray!30,opacity=0.5](\cx,\cy)circle[x radius=\a,y radius=\b];
\path[name path=linePC] (P)--(C);
\path[name path=linePC] (P)--(C);
\path [name intersections={of = ellipse and linePC}];
\coordinate (E) at (intersection-2);
\coordinate (F) at (intersection of A--C and B--E);
\path let \p1=(F) in node (G) at (-1.2*\a,\y1){};
\path[name path=lineFG] (F)--(G);
\path [name intersections={of = ellipse and lineFG}];
\coordinate (X) at (intersection-1);
\coordinate (Y) at (intersection-2);
\draw (X)--(P)--(Y);
%%%%%%%%%%%%%%%%%%%%%% Second Ellipse%%%%%%%%%%%%%%
\def\a{1} \def\b{0.5} % radii of Ellipse
\def\cx{0} \def\cy{0} % determines center of Ellipse
\def\xp{0} \def\yp{-5} % coordinates of point P
\coordinate (P) at (\xp,\yp);
\coordinate (A) at (0,\b); % up
\coordinate (B) at (0,-\b); % down
\coordinate (C) at (\a,0); % right
\draw[name path=ellipse,fill=white](\cx,\cy)circle[x radius=\a,y radius=\b];
\path[name path=linePC] (P)--(C);
\path[name path=linePC] (P)--(C);
\path [name intersections={of = ellipse and linePC}];
\coordinate (E) at (intersection-2);
\coordinate (F) at (intersection of A--C and B--E);
\path let \p1=(F) in node (G) at (-1.2*\a,\y1){};
\path[name path=lineFG] (F)--(G);
\path [name intersections={of = ellipse and lineFG}];
\coordinate (X) at (intersection-1);
\coordinate (Y) at (intersection-2);
\draw (X)--(P) (P)--(Y);
\draw [->,thin](0,-5.5)--(0,1.5) node[above]{$z$};
\draw [<-,shorten <=0.2pt,thin](P)--+(0.4,-0.1) node[right]{Gap};
\draw [->,thin](0,-2.2) arc (90:65.4:2.5);
\node [fill=white] at (0.5,-2.5){$\theta_2$};
\draw [->,thin](0,-3.5) arc (90:79:1.6);
\node at (0.13,-3.7){$\theta_1$};
\end{tikzpicture}
\end{document}
我很感谢您的帮助,并提前谢谢您。
答案1
如果我们处理的是圆,那么半径将垂直于切线,因此我们需要找到一个连接中心 C、点 P 和圆的直角三角形。如果你还记得几何学,任何内接于圆的三角形,只要该三角形的一条边通过圆心,就会形成一个直角三角形。因此,如果我们构造一个圆,其圆心是 P 和 C 之间的中点,那么两个圆的交点就是切点。
由于椭圆可以被认为是从一个角度看到的圆,因此我们需要一个具有相同纵横比的椭圆而不是圆。
为了便于说明,我把构造弄得可见(粉红色)。
\documentclass{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc,intersections,arrows}
\usepackage{times}
\begin{document}
\begin{tikzpicture}[scale=1,>=latex',scale=1.5,outer sep=0,inner sep=0,line width=0.7pt]
\def\a{2} \def\b{1} % radii of Ellipse
\def\cx{0} \def\cy{0} % determines center of Ellipse
\def\xp{0} \def\yp{-5} % coordinates of point P
\coordinate (C) at (\cx,\cy);% center of ellipse
\coordinate (P) at (\xp,\yp);% focal point
\draw[name path=ellipse,fill=gray!30,opacity=0.5](C)circle[x radius=\a,y radius=\b];
\pgfmathparse{abs(\cx-\xp)/\a}% compute normalized distance from C to P
\edef\dx{\pgfmathresult}
\pgfmathparse{abs(\cy-\yp)/\b}
\edef\dy{\pgfmathresult}
\pgfmathparse{0.5*ifthenelse(\dx,ifthenelse(\dy,sqrt(\dx*\dx+\dy*\dy),\dx),\dy)}
\edef\d{\pgfmathresult}% half the distance from C to P
\pgfmathparse{\a*\d}% compute ellipse radii
\edef\rx{\pgfmathresult}
\pgfmathparse{\b*\d}
\edef\ry{\pgfmathresult}
\draw[color=pink,name path=construct] ($(C)!0.5!(P)$) circle[x radius=\rx, y radius=\ry];
\path [name intersections={of = ellipse and construct}];
\coordinate (X) at (intersection-1);
\coordinate (Y) at (intersection-2);
\draw (X)--(P)--(Y);
\end{tikzpicture}
\end{document}
答案2
纯粹的 PSTricks 解决方案,充满乐趣。
\documentclass[pstricks,border=12pt,dvipsnames]{standalone}
\usepackage{pstricks-add}
\psset
{
urx=15pt,
ury=15pt,
llx=-5pt,
lly=-5pt,
xAxisLabel=$x$,
yAxisLabel=$y$,
algebraic,
plotpoints=1000,
tickcolor=gray,
}
\def\ChangeEvalVariable#1{%
\pstVerb{tx@Derive begin
/origEvalVariable /EvalVariable load def
/EvalVariable { 2 index (#1) eq { (1) } { (0) } ifelse 4 -1 roll exch 6 2 roll } def
end }%
}%
\def\ResetEvalVariable{%
\pstVerb{tx@Derive begin
/EvalVariable /origEvalVariable load def
end }%
}%
\def\x{2*cos(t)}
\def\y{sin(t)}
\def\xp{Derive(1,\x)}
\def\yp{Derive(1,\y)}
\begin{document}
\begin{psgraph}[linecolor=gray,axespos=top]{<->}(0,0)(-3,-3)(3,3){\dimexpr6cm-30pt}{!}
\ChangeEvalVariable{t}
\psparametricplot[linecolor=NavyBlue,strokeopacity=.5]{0}{TwoPi}{\x|\y}
\psplotTangent[linecolor=Red,Derive={\xp|\yp}]{Pi 4 div}{2}{\x|\y}
\psplotTangent[linecolor=ForestGreen,Derive={-\yp|\xp}]{Pi 4 div}{2}{\x|\y}
\ResetEvalVariable
\end{psgraph}
\end{document}
注意:\ChangeEvalVariable{t}
和\ResetEvalVariable
是 Christoph 开发的宏此处(点击)。
答案3
这使用二分搜索来查找切线。这里唯一需要的几何知识是切线位于未命中形成的圆弧内的某个位置。适用于任何封闭形状。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,intersections,arrows}
\newlength{\bigenough}
\newcount\total
% locates both points on a closed shape tangent to a point outside the shape.
% \tangent{pathname}{center}{point}{first}{second}
\newcommand{\tangent}[5]% #1=path name for shape, #2=coordinate name for center, #3=cordinate name for outside point
{\begingroup% #4=coordinate name for first tangent point, #5=coordinate name for second coordinate point
\setlength{\bigenough}{1cm}
\loop% loop until big enough
\path[name path=temp] ($(#2)!\bigenough!-90:(#3)$)--($(#2)!\bigenough!90:(#3)$);
\path[name intersections={of = #1 and temp, total=\t}]%
\pgfextra{\global\total=\t};%
\ifnum\total<2 \global\bigenough=2\bigenough\repeat%
\endgroup
\coordinate (#4) at (intersection-1);% initial guess
\coordinate (#5) at (intersection-2);%
\tangentsearch{#1}{#2}{#3}{#4}%
\tangentsearch{#1}{#2}{#3}{#5}}
% find tangent using binary search
\newcommand{\tangentsearch}[4]% #1=path name for shape, #2=coordinate name for center, #3=cordinate name for outside point
{\begingroup% #4=coordinate name for tangent point (initail guess -> final)
\loop% loop until only 1 intersection
\path[name path=temp] (#3)--($(#4)!-\bigenough!(#3)$);
\path[name intersections={of = #1 and temp, total=\t}]%
\pgfextra{\global\total=\t};%
\ifnum\total=2 \coordinate (#4) at ($(intersection-1)!0.5!(intersection-2)$);
\draw[pink] (intersection-1)--(intersection-2);% included only for debugging purposes
\path[name path=temp] (#4)--($(#4)!-\bigenough!(#2)$);
\path[name intersections={of = #1 and temp}];%
\coordinate (#4) at (intersection-1);%
\repeat%
\endgroup}
\begin{document}
\begin{tikzpicture}[scale=1,>=latex',scale=1.5,outer sep=0,inner sep=0,line width=0.7pt]
\def\a{2} \def\b{1} % radii of Ellipse
\def\cx{0} \def\cy{0} % determines center of Ellipse
\def\xp{0} \def\yp{-5} % coordinates of point P
\coordinate (C) at (\cx,\cy);
\coordinate (P) at (\xp,\yp);
\coordinate (A) at (\a,0); % initial guess
\draw[name path=ellipse,fill=gray!30,opacity=0.5](\cx,\cy)circle[x radius=\a,y radius=\b];
\tangent{ellipse}{C}{P}{X}{Y}
\draw (X)--(P)--(Y);
\end{tikzpicture}
\end{document}
如果你仔细观察,你会看到错过的和弦的粉红色小线。