8

I wonder if one can draw tangent lines out of a point to a path of an ellipse using tikz. Actually for the case of circle paths this can be accomplished easily as given in the tikz-pgf manual, but for other paths it wouldn't be an easy task.

I have tried to solve this problem with the help of some threads, but my solution, unfortunately, relies on some mathematical background. I wonder if I could solve the same problem with pure tikz.

Here is my solution:

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

I appreciate your help and thank you in advance.

  • Is this actually valid or is it just a good approximation? I don't mean to downplay it, but I cannot figure out how it works. – John Kormylo Jul 18 '14 at 22:30
  • I was checking out how tikz does intersections, and discovered it uses closed form solutions. Specifically, paths consist of segments of lines and a limited variety of curves. For any given combination of segments, it finds the intersections and checks to see if they lie within the segment limits. – John Kormylo Jul 25 '14 at 3:56
8

If we were dealing with circles, then the radius would be perpendicular to the tangent, so we would need to find a right triangle connecting the center C, point P, and the circle. If you recall your geometry, any triangle inscribed in a circle where one side of the triangle passes through the center will form a right triangle. So if we construct a circle whose center is the midpoint between P and C, the intersection of the two circles is the point(s) of tangency.

Since ellipses can be thought of as circles seen from an angle, instead of a circle we need an ellipse with the same aspect ratio.

For the purposes of illustration, I made the construct visible (pink).

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

tangents

  • 1
    Thank you Kormylo for your contribution. I wrote "but my solution, unfortunately, relies on some mathematical background". In your solution you have used similar approach to mine except you have used circles to calculate intersection points and I used lines. The accepted solution should only be based on tikz algorithms without much geometry. – AboAmmar Jul 18 '14 at 19:46
  • @AboAmmar The use of TikZ always relies on some mathematical background... – Paul Gaborit Jul 19 '14 at 7:38
2

A pure PSTricks solution for fun.

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

enter image description here

Note: \ChangeEvalVariable{t} and \ResetEvalVariable are macros developed by Christoph here (click).

2

This uses a binary search to find the tangent. The only knowledge of geometry required here is that the tangent is located somewhere inside the arc formed by a miss. Will work on any closed shape.

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

search

If you look closely you can see little pink lines of chords from misses.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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