5

I have this picture:

enter image description here

and I want to draw a tangent line at each of the marked intersections. I have found some answers (and examples in the TikZ manual) using the decorations.markings library. The thing is that (from what I understood) this library only knows the tangent of a curve given the position, from 0 to 1, so I'd have to guess where, in the length of the curve, the intersection is, but I'd rather do that automagically :)

I thought about mapping the coordinate of the intersection to a normalised [0, 1] value, but I couldn't figure out how to do that either.

Code for the picture:

\documentclass[tikz]{standalone}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
  \draw (0, 0.2) .. controls ++(0.5,0.75) and ++(-0.5,-0.75) .. (1,0.2) coordinate (LP1);
  \draw [xshift=1cm, blue, name path=eta]
    (0, 0.3) .. controls ++(0.5,0.75) and ++(-0.5,0) .. (1.0,-0.4)
             .. controls ++(0.3,0)    and ++(-0.3,0) .. (1.6, 0.3) coordinate (LP2);
  \draw [gray, name path=eta0] (LP1) -- (LP1-|LP2);
  \draw [red, name intersections={of=eta and eta0,total=\t}]
    \foreach \s in {1,...,\t}{ (intersection-\s) circle (1pt) };
\end{tikzpicture}
\end{document}

I think that this problem is fairly common, but I browsed plenty of intersections/tangents/markings questions but couldn't find what I'm trying to do, so sorry if it is a duplicate.

6

This is a possible way. If you do not want to load pgfplots, I am afraid it will be considerably more effort.

How does this proposal work?

  1. The pgplots (!) library fillbetween allows us to decompose paths into intersection segments. These are called A1 and A2 in the examples below, and can be reversed, if needed.
  2. Once we have such an intersection segment, the problem boils down to attaching tangents at the ends of these segments, which is a long-solved problem, see this answer.

These codes illustrate this.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[tangent at/.style={% cf. https://tex.stackexchange.com/questions/25928/how-to-draw-tangent-line-of-an-arbitrary-point-on-a-path-in-tikz/25940#25940
    decoration={ markings,
      mark =at position #1 with {\draw[purple,-latex](0,0) -- (0.5,0);},
    }, decorate
  }]

  \draw (0, 0.2) .. controls ++(0.5,0.75) and ++(-0.5,-0.75) .. (1,0.2) coordinate (LP1);
  \draw [xshift=1cm, blue, name path=eta]
    (0, 0.3) .. controls ++(0.5,0.75) and ++(-0.5,0) .. (1.0,-0.4)
             .. controls ++(0.3,0)    and ++(-0.3,0) .. (1.6, 0.3) coordinate (LP2);
  \draw [gray, name path=eta0] (LP1) -- (LP1-|LP2);
  \draw [red, name intersections={of=eta and eta0,total=\t}]
    \foreach \s in {1,...,\t}{ (intersection-\s) circle (1pt) };
  \path [%draw,blue,
    name path=middle arc,
    intersection segments={
        of=eta and eta0,
        sequence={A1}
    },
    postaction={tangent at/.list={0,1}}];   
\end{tikzpicture}
\end{document}

enter image description here

You can do that with more intersections, too. You only need to add the tangents at the appropriate intersection segments.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[tangent at/.style={% cf. https://tex.stackexchange.com/questions/25928/how-to-draw-tangent-line-of-an-arbitrary-point-on-a-path-in-tikz/25940#25940
    decoration={ markings,
      mark =at position #1 with {\draw[purple,-latex](0,0) -- (0.5,0);},
    }, decorate
  }]

  \draw (0, 0.2) .. controls ++(0.5,0.75) and ++(-0.5,-0.75) .. (1,0.2)
  coordinate (LP1);
  \draw [xshift=1cm, blue, name path=eta]
    (0, 0.3) .. controls ++(0.5,0.75) and ++(-0.5,0) .. (1.0,-0.4)
             .. controls ++(0.3,0)    and ++(-0.3,0) .. (1.6, 0.3) 
   .. controls ++(0.6,0) and ++(-0.6,0) .. (2.8,-0.3) coordinate (LP2);
  \draw [gray, name path=eta0] (LP1) -- (LP1-|LP2);
  \draw [red, name intersections={of=eta and eta0,total=\t}]
    \foreach \s in {1,...,\t}{ (intersection-\s) circle (1pt) };
  \path [%draw,red,thick,
    intersection segments={
        of=eta and eta0,
        sequence={A1}
    },
    postaction={tangent at/.list={0,1}}];   
  \path [%draw,green,thick,
    intersection segments={
        of=eta and eta0,
        sequence={A2}
    },
    postaction={tangent at/.list={1}}]; 
\end{tikzpicture}
\end{document}

enter image description here

Of course, this can be automatized.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[tangent at/.style={% cf. https://tex.stackexchange.com/questions/25928/how-to-draw-tangent-line-of-an-arbitrary-point-on-a-path-in-tikz/25940#25940
    decoration={ markings,
      mark =at position #1 with {\draw[purple,-latex](0,0) -- (0.5,0);},
    }, decorate
  }]

  \draw (0, 0.2) .. controls ++(0.5,0.75) and ++(-0.5,-0.75) .. (1,0.2)
  coordinate (LP1);
  \draw [xshift=1cm, blue, name path=eta]
    (0, 0.3) .. controls ++(0.5,0.75) and ++(-0.5,0) .. (1.0,-0.4)
             .. controls ++(0.3,0)    and ++(-0.3,0) .. (1.6, 0.3) 
   .. controls ++(0.6,0) and ++(-0.6,0) .. (2.8,-0.3) coordinate (LP2);
  \draw [gray, name path=eta0] (LP1) -- (LP1-|LP2);
  \draw [red, name intersections={of=eta and eta0,total=\t},
  /utils/exec={\xdef\NumIntersection{\t}}]
    \foreach \s  in {1,...,\t}{ 
    (intersection-\s) circle (1pt) };
  \foreach \X [count=\Y starting from 0] in {1,...,\NumIntersection}    
  {
  \path [%draw,red,thick,
    intersection segments={
        of=eta and eta0,
        sequence={A\Y}
    },
    postaction={tangent at=1}];   
  } 
\end{tikzpicture}
\end{document}

(Same result as above.)

| improve this answer | |
  • 1
    Excellent! I was trying (and failing) to understand the link you posted in the comments when you answered. pgfplots won't be a problem at all. I hate to be the “just do this one more thing” user but, how do I add the intersection to an arbitrary number of intersections? For example, if I add .. controls ++(0.6,0) and ++(-0.6,0) .. (2.8,-0.3) to the end of the blue curve (before coordinate). I tried the tangent at/.list thingy, but apparently it doesn't do what I thought it did :/ – Phelype Oleinik Feb 28 '19 at 19:44
  • @PhelypeOleinik No problem! I added an explanation (which I should have done right away...), and added the example you suggested. – user121799 Feb 28 '19 at 19:54
  • 1
    Ooh, now I got it. I completely overlooked the sequence thing. Thanks a lot :D – Phelype Oleinik Feb 28 '19 at 20:42
  • 1
    @PhelypeOleinik I added a slightly more automatized version. – user121799 Feb 28 '19 at 20:58

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.