10

The following question is based on an assignment I wrote for my students to determine the point of tangency of a circle with center origin and radius r.

enter image description here

I have managed to get the diagram I wanted with the following code:

\begin{tikzpicture}
\pgfmathsetmacro{\tangentpoint}{sqrt(19)}%
    \draw[-stealth] (-2,0)--(2,0) node [right]{$x$};
    \draw[-stealth] (0,-2)--(0,2) node [above]{$y$};
    \draw[thick,Cerulean] (0,0) circle (1cm);
    \draw (0,0)--(0.9,\tangentpoint/10);
    \draw[domain=0.25:1.5,smooth,variable=\x,OrangeRed,thick] plot ({\x},{(-9*\tangentpoint)*\x/19+(10*\tangentpoint)/19});
    \node[fill, inner sep=0.75pt, circle, draw] at (0,0) {};
    \node[fill, inner sep=0.75pt, circle, draw] at (0.9,\tangentpoint/10) {};
\end{tikzpicture}

The output is as desired. Of course, now I am trying to develop a general form of the determination of the point of tangency and the tangent line only based on the given x-coordinate. The following does it between the intervals (-0.99999,-0.00001) and (0.00001,0.99999). It fails at x=0 and x= +- 1 as seen in the code below:

\begin{tikzpicture}
    \newcommand{\Xtangent}{-0.4}
    \newcommand{\Radius}{1}     
        \pgfmathsetmacro{\Ytangentcalc}{sqrt(pow(\Radius,2)- pow(\Xtangent,2))}%
        \pgfmathsetmacro{\Yintercepttangentlinecalc}{pow(\Radius,2)/\Ytangentcalc}%
        \pgfmathsetmacro{\mtangentlinecalc}{(\Ytangentcalc-\Yintercepttangentlinecalc)/\Xtangent}%
        %\clip (-2,-2) rectangle (2,2);
        \draw[-stealth] (-2,0)--(2,0) node [right]{$x$};
        \draw[-stealth] (0,-2)--(0,2) node [above]{$y$};
        \draw[thick,Cerulean] (0,0) circle (\Radius);
        \draw (0,0)--(\Xtangent,\Ytangentcalc);
        \draw[domain=-2:2,smooth,variable=\x,OrangeRed,thick] plot ({\x},{\mtangentlinecalc*\x+\Yintercepttangentlinecalc});
        \node[fill, inner sep=0.75pt, circle, draw] at (0,0) {};
        \node[fill, inner sep=0.75pt, circle, draw] at (\Xtangent,\Ytangentcalc) {};
\end{tikzpicture}

The questions are: how can I address the fails and how can I decide if the point of tangency is in either of the quadrants, especially 3 and 4?

Here is a complete MWE:

\documentclass[letterpaper,dvipsnames]{article}
\usepackage{tikz}

\begin{document}
    \begin{tikzpicture}
    \newcommand{\Xtangent}{-0.4}
    \newcommand{\Radius}{1}     
        \pgfmathsetmacro{\Ytangentcalc}{sqrt(pow(\Radius,2)- pow(\Xtangent,2))}%
        \pgfmathsetmacro{\Yintercepttangentlinecalc}{pow(\Radius,2)/\Ytangentcalc}%
        \pgfmathsetmacro{\mtangentlinecalc}{(\Ytangentcalc-\Yintercepttangentlinecalc)/\Xtangent}%
        %\clip (-2,-2) rectangle (2,2);
        \draw[-stealth] (-2,0)--(2,0) node [right]{$x$};
        \draw[-stealth] (0,-2)--(0,2) node [above]{$y$};
        \draw[thick,Cerulean] (0,0) circle (\Radius);
        \draw (0,0)--(\Xtangent,\Ytangentcalc);
        \draw[domain=-2:2,smooth,variable=\x,OrangeRed,thick] plot ({\x},{\mtangentlinecalc*\x+\Yintercepttangentlinecalc});
        \node[fill, inner sep=0.75pt, circle, draw] at (0,0) {};
        \node[fill, inner sep=0.75pt, circle, draw] at (\Xtangent,\Ytangentcalc) {};
    \end{tikzpicture}
\end{document}

5 Answers 5

8

Just for fun hence not an exact answer. tkz-euclide makes this with no effort.

\documentclass[dvipsnames]{article}

\usepackage{tkz-euclide,tikz}
\usetkzobj{all}

\begin{document}
\begin{tikzpicture}
\newcommand{\myangle}{120}
\tkzInit[xmin=-2,xmax=2,xstep=1,ymin=-2,ymax=2,ystep=1]
\tkzDrawX \tkzDrawY
\tkzDefPoint(0,0){c}
\tkzDefPoint(1,1){a0}
\tkzRadius=1 cm
\tkzDrawCircle[R,thick,color=Cerulean](c,\tkzRadius)
\tkzDefPointBy[rotation=center c angle \myangle](a0)
\tkzGetPoint{a}
\tkzTangent[from with R = a](c,\tkzRadius)
\tkzGetPoints{e}{f}
\tkzDrawLine[add = 1 and 2,color=OrangeRed,thick](a,f)
\tkzDrawSegment(c,f)
\tkzDrawPoints[size=3,fill](f,c)
\end{tikzpicture}
\end{document}

enter image description here

With \newcommand{\myangle}{180}

enter image description here

With \newcommand{\myangle}{0}

enter image description here

2
  • I had contemplated on using this but I opted for the challenge. I was also looking at the tangent construct that is referenced in the pgfmanual but I have not figured how to use it.
    – azetina
    Commented Jan 18, 2015 at 6:05
  • +1 without any doubt, euclide is the right tool to use here.
    – yo'
    Commented Jan 18, 2015 at 18:44
6

Here's another Metapost version, that defines a function to draw the tangent. This is just plain Metapost, so you can compile it with mpost xxx.mp as usual.

enter image description here

The arguments to the function should be a circular path, and a number between -1 and 1 for the x-coordinate. The corresponding y-coordinate is calculated using the handy "Pythagorean subtraction" operator, documented on p.66 of The Metafont Book (essentially a +-+ b is equivalent to sqrt(a**2-b**2), but more efficient). The tangent line is rotated using the fact that (x,y) rotated 90 is (-y,x).

prologues := 3;
outputtemplate := "%j%c.eps";

vardef mark_upper_tangent(expr circle, dx) = 
  save r, p, dy; pair p; numeric r, dy;
  if abs(dx) <= 1:
    dy = 1 +-+ dx;
    r = xpart (point 0 of circle - center circle);
    p = (dx,dy) scaled r shifted center circle;
    draw center circle -- p withcolor .67 white;
    draw (left--right) scaled r rotated angle (-dy,dx) shifted p withcolor .67 red;
    fill fullcircle scaled dotlabeldiam shifted p;
  fi
enddef;

beginfig(1);

u := 1cm;

path xx, yy, C;
xx = (left--right) scaled 2u;
yy = (down-- up  ) scaled 2u;
C = fullcircle scaled 3u;

drawarrow xx; label.rt (btex $x$ etex, point 1 of xx);
drawarrow yy; label.top(btex $y$ etex, point 1 of yy);
draw C withcolor .67 blue;
mark_upper_tangent(C, 0.4);

endfig;
end.
4
  • Nice catch, the use of the +-+ operator! There was a small typo, "0.67 blue" should have been "0.67blue" (fixed). Commented Jan 18, 2015 at 16:15
  • @fpast, thanks for the comment, but 0.67 blue works fine for me; the space between a numeric and a colour-triple is entirely optional, and I prefer it for readability and to allow Vim syntax highlighting to work.
    – Thruston
    Commented Jan 18, 2015 at 16:36
  • you're right, sorry for that. I've learnt something more about MetaPost :) Commented Jan 18, 2015 at 17:14
  • This is the first time I have seen (left--right) scaled r being used. Interesting!
    – Aditya
    Commented Jan 19, 2015 at 16:51
5

I couldn't be sure to which direction I should automate this. Maybe you can build on it by making things more parametric.

The basic idea is to place a node on the 360 degrees arc with pos using also the sloped option. Then use that node's anchors to bypass the angle computations (all computations actually).

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[
place tannode/.style={insert path={
          node[pos=#1,sloped,fill, circle,inner sep=0.75pt] (tannode){}}},
place tannode/.default=0.5,
draw tannode/.style={insert path={
    ($(tannode.center)!1cm!(tannode.west)$)--($(tannode.center)!1cm!(tannode.east)$)
}}
]

\def\XR{10mm}
\draw (\XR,0) arc(0:360:\XR) [place tannode=7/8];% You can use acos for the value
\draw[red,thick,draw tannode];
\end{tikzpicture}
\end{document}

enter image description here

2
  • Interesting...So you are using points on an arc and then drawing a line 1 cm away on both sides right?
    – azetina
    Commented Jan 18, 2015 at 6:10
  • @azetina Yes but the name of the tangent is available later so you can draw from that node to wherever you want.
    – percusse
    Commented Jan 18, 2015 at 6:43
4

I am not sure either of the way the question must be understood. For my part, given the x coordinate I would deduce the corresponding arc point (on the upper half circle) and draw the subsequent tangent (very easily: it's the perpendicular to the radius, after all). I give it with MetaPost, since I'm not fluent in Tikz, but I can't see why Tikz should be worse at it.

u = 2cm; % unit length;
xmax = 1.5 ; ymax = 1.5 ; % axes parameters
beginfig(1);
  path circle; circle = fullcircle scaled 2u; draw circle withcolor blue ;
  x = 0.4 ; % any value between -1 and 1
  len = 3u; % tangent length
  t = (acos x)/45 ; % point-node of fullcircle corresponding to x
  pair I; I = point t of circle ; 
  if (x <> 0) and (abs(x) <> 1): draw origin -- I ; fi ;
  % tangent on the upper part of circle 
  pair v ; v = unitvector I rotated 90 ;   
  draw I - 0.5len*v -- I + 0.5len*v  withcolor red ; 
  draw I withpen pencircle scaled 3bp;
  drawarrow (-xmax*u, 0) -- (xmax*u, 0) ; % horizontal axis
  drawarrow (0, -ymax*u) -- (0, ymax*u) ; % vertical axis
  label.bot(btex $x$ etex, (xmax*u, 0)) ; 
endfig;
end.

To be compiled with the MetaFun format and numbersytem set to "double" (not compulsory, but the results are more accurate).

mpost --mem=metafun --numbersystem="double" mygraph.mp

x = 1:

enter image description here

x = 0:

enter image description here

x = -1:

enter image description here

x = 0.4:

enter image description here

2

Here is a solution that allows you to use style tangent over={.5 r 2} which put a tangent over x=.5 to circle with radius 2 and center at (0,0):

\documentclass[varwidth,border=7mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
  tangent at/.style = {
    insert path={
      let \p1=(#1) in {
        (\p1) node[scale=2]{.} -- +(\y1,-\x1) -- +(-\y1,\x1)
      }
    }
  },
  tangent over/.code args={#1 r #2}{
    \pgfmathparse{sqrt((#2)^2-(#1)^2)}
    \pgfkeysalso{tangent at={#1,\pgfmathresult}}
  },
  tangent under/.code args={#1 r #2}{
    \pgfmathparse{sqrt((#2)^2-(#1)^2)}
    \pgfkeysalso{tangent at={#1,-\pgfmathresult}}
  }
}
\begin{document}
\begin{tikzpicture}
  \draw circle(1) circle(2) [tangent under={.5 r 1}];
  \draw[red,tangent under={1 r 1}, tangent over={-1 r 1}];
  \draw[green,tangent over={-.5 r 2}];
\end{tikzpicture}
\end{document}

enter image description here

Notes:

  • If you want to draw tangent to circle that is not centered at (0,0) you can use shift.
  • To keep it simple I haven't added parameter for the tangent length, but you can do it easily.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .