10

It is rather straightforward to come up with a rusty code that determines the extremal points of an arbitrary path in TikZ. I am aware that pgfplots has this functionality, but I really want to have this functionality for all paths and have applications in mind that are sort of orthogonal to pgfplots. Here is my rusty code.

\documentclass[border=5pt,tikz]{standalone}
\usetikzlibrary{intersections}
\makeatletter
\def\GetPathBB{
  \typeout{path:(\the\pgf@pathminx,\the\pgf@pathminy),(\the\pgf@pathmaxx,\the\pgf@pathmaxy)}
  \xdef\BBmin{\the\pgf@pathminx,\the\pgf@pathminy}
  \xdef\BBmax{\the\pgf@pathmaxx,\the\pgf@pathmaxy}
}
\makeatother  
\begin{document}
\begin{tikzpicture}
\draw[-latex] (-1,0) -- (5.5,0) node[above] {$x$};
\draw[-latex] (0,-3) -- (0,4) node[left] {$y$};
\draw[blue,thick,name path=myplot] plot[variable=\x,domain=0:5] ({\x},{cos(-20+50*\x)})
\pgfextra{\GetPathBB}; %<- instead of inserting this "by hand" I'd like to 
% put this into an option of the path command, but all my attempts
% with "append after command" or "postaction" failed
\path[name path global=minline] (\BBmin)  to[bend left=0] (\BBmin-|\BBmax);
\path [name intersections={of=minline and myplot, name=min}];
\draw[fill=red] (min-1) circle (2pt) node[below] {min};
\path[name path global=maxline] (\BBmin|-\BBmax)  to[bend left=0] (\BBmax);
\path [name intersections={of=maxline and myplot, name=max}];
\draw[fill=red] (max-1) circle (2pt) node[above] {max};
% the extrema should also be computed automatically, ideally also the leftmost
% and rightmost points 
\end{tikzpicture}
\end{document}

It works:

enter image description here

and you can also find some extremal points of other paths:

enter image description here

It is also obvious how to find the left- and rightmost points of the path. However, the code is not too elegant. It would be much nicer if one could just pass an option find extrema to the plot and not have the above mess. Specifically, I'd like to absorb the \pgfextra{...} before the semicolon and the codes for maxline and minline in this option. I played a bit with append after command, postaction and the like, but I failed.

4
  • 2
    For that TikZ has current path bounding box node that does these computations.But if you use control points, this approach will fail. – percusse Mar 29 '18 at 23:42
  • @percusse Yes, that's already a great help, now I can simply write \draw[blue,thick,name path=myplot] plot[variable=\x,domain=0:5] ({\x},{cos(-20+50*\x)}) coordinate (BBmax) at (current path bounding box.north east) coordinate (BBmin) at (current path bounding box.south west); but I still fail to convert this to a style. – user121799 Mar 29 '18 at 23:51
  • 1
    For that you need a plot handler. There are some ideas here tex.stackexchange.com/questions/249860/… – percusse Mar 30 '18 at 0:04
  • @percusse Your suggestion works really great, see here. Thanks!!!! – user121799 Mar 30 '18 at 2:28
10
+500

You could use path picture.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}

\tikzset{name path min max/.style = {
    name path global=#1,
    path picture={
      \coordinate (ll) at (path picture bounding box.south west);
      \coordinate (ur) at (path picture bounding box.north east);
      \path[name path=minline] (ll) to[bend left=0] (ll-|ur);
      \path[name intersections={of=minline and #1, name=#1-min}];
      \path[name path=maxline] (ll|-ur) to[bend left=0] (ur);
      \path[name intersections={of=maxline and #1, name=#1-max}];
    }
  }
}

\begin{document}
\begin{tikzpicture}
  \draw[-latex] (-1,0) -- (5.5,0) node[above] {$x$};
  \draw[-latex] (0,-1.5) -- (0,2) node[left] {$y$};

  \draw[blue,thick,name path min max=myplot] plot[variable=\x,domain=0:5] ({\x},{cos(-20+50*\x)});

  % Use min and max
  \draw[fill=red] (myplot-min-1) circle (2pt) node[below] {min};
  \draw[fill=red] (myplot-max-1) circle (2pt) node[above] {max};

  % Reuse path in other intersections
  \path[name path=diag] (0,0) -- (1,1);
  \path[name intersections={of=diag and myplot, name=inter}];
  \node[draw,fill=green,circle,inner sep=2pt] at (inter-1) {};
\end{tikzpicture}
\end{document}

enter image description here

4
  • @marmot More bells and whistles... – Henri Menke Mar 30 '18 at 0:29
  • Very, very clever ! And very nice code. – Kpym Mar 30 '18 at 5:23
  • 1
    @marmot I hope this is more like your taste (screenshot). Thanks for the suggestions, I'll update my answer. – Henri Menke Mar 30 '18 at 7:27
  • Those who may want to use this for smooth curves may be interested in this answer which determines the true bounding box. Otherwise TikZ may not find an intersection. – user121799 Aug 5 '19 at 21:26

Your Answer

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