4

I'd like to combine different plots which I generate by some algorithms to some long path (which may be used for clippings). I am lacking an understanding of the \noexpand, \expandafter and so on magic. Here is my MWE:

\documentclass{article}
\usepackage{tikz}
\newcommand{\myparabola}[2]{
\pgfmathsetmacro{\myxmin}{min(2*sin(#1),-1)}
\pgfmathsetmacro{\myxmax}{max(2*sin(#1),1)}
plot[domain=\myxmin:\myxmax,variable=#2] ({#2},{#2*#2})
}
\begin{document}
This, of course, works:
\begin{center}
\begin{tikzpicture}
 \pgfmathsetmacro{\myxmin}{min(2*sin(100),-1)}
 \pgfmathsetmacro{\myxmax}{max(2*sin(100),1)}
 \draw plot[domain=\myxmin:\myxmax,variable=\x] ({\x},{\x*\x});
 \draw[clip] plot[domain=0:180,variable=\x] ({\x/100},{sin(\x)})
 plot[domain=0:180,variable=\x] ({\x/100},{-sin(\x)});
 \fill[red] circle (1.1);
\end{tikzpicture}
\end{center}
I want the result here be the same as above:
\begin{center}
\begin{tikzpicture}
% \draw \myparabola{100}{\x} ; % DOES NOT WORK
\end{tikzpicture}
\end{center}
Ultimately I'd like to plot several of those and/or use them in some clippings:
\begin{center}
\begin{tikzpicture} %DOES NOT WORK
% \clip \myparabola{100}{\x}  \myparabola{200}{\x} \myparabola{-100}{\x};
\end{tikzpicture}
\end{center}
And of course I'm not really interested in parabolae, but more general functions
which I construct with an analogue of \verb|\myparabola|.
\end{document}

enter image description here

Is it possible to define the \myparabola command and use it in such a way that I can just insert it into some \draw or \clip command?

ADDENDUM: I made a tiny bit of progress and am now stuck at a much more basic question. Look at this MWE:

\documentclass{article}
\usepackage{tikz}
\newcommand{\myparabola}[1]{%
%\pgfmathsetmacro{\myxmin}{1}% IF I UNCOMMENT THIS LINES, THERE IS AN ERROR
plot[domain=-1:1] ({\noexpand\x},{#1*\noexpand\x*\noexpand\x})
}
\begin{document}
\begin{tikzpicture}
 \draw[variable=\x] \myparabola{1} \myparabola{-1}; 
\end{tikzpicture}
\end{document}

enter image description here

It produces what is expected. However, if I dare to uncomment the line \pgfmathsetmacro{\myxmin}{1}, there is an error ! Package tikz Error: Giving up on this path. Did you forget a semicolon?.. Why is that? Any partial answer would be highly appreciated.

  • Basically you can't just put a \pgfmathsetmacro in a path. You could perhaps use \pgfextra{\pgfsetmacro..}, see section 14.20 The PGF-extra Operation in the manual. But note the warning in the first paragraph of that section. – Torbjørn T. Jan 15 '18 at 22:52
  • @TorbjørnT. That's fantastic! Thank you so much! Would you mind turning this into an answer? – user121799 Jan 15 '18 at 22:57
3

The problem is that you're using \pgfmathsetmacro inside a path. It is possible to do that if you use \pgfextra{\pgfmathsetmacro...}, but I should point out what the manual says of this (section 14.20 The PGF-extra operation):

In some cases you may need to “do some calculations or some other stuff” while a path is constructed. For this, you would like to suspend the construction of the path and suspend TikZ’s parsing of the path, you would then like to have some TeX code executed, and would then like to resume the parsing of the path. This effect can be achieved using the following path operation \pgfextra. Note that this operation should only be used by real experts and should only be used deep inside clever macros, not on normal paths.

I don't consider myself a real expert, and I don't know if there are any caveats to this.

\documentclass{article}
\usepackage{tikz}
\newcommand{\myparabola}[2]{
\pgfextra{% <- put path construction on hold, and do the following:
  \pgfmathsetmacro{\myxmin}{min(2*sin(#1),-1)}
  \pgfmathsetmacro{\myxmax}{max(2*sin(#1),1)}
} 
plot[domain=\myxmin:\myxmax,variable=#2] ({#2},{#2*#2})
}
\begin{document}
This, of course, works:
\begin{center}
\begin{tikzpicture}
 \pgfmathsetmacro{\myxmin}{min(2*sin(100),-1)}
 \pgfmathsetmacro{\myxmax}{max(2*sin(100),1)}
 \draw plot[domain=\myxmin:\myxmax,variable=\x] ({\x},{\x*\x});
 \draw[clip] plot[domain=0:180,variable=\x] ({\x/100},{sin(\x)})
 plot[domain=0:180,variable=\x] ({\x/100},{-sin(\x)});
 \fill[red] circle (1.1);
\end{tikzpicture}
\end{center}
I want the result here be the same as above:
\begin{center}
\begin{tikzpicture}
 \draw \myparabola{100}{\x} ; % DOES NOT WORK
\end{tikzpicture}
\end{center}
Ultimately I'd like to plot several of those and/or use them in some clippings:
\begin{center}
\begin{tikzpicture}
 \clip \myparabola{100}{\x}  \myparabola{200}{\x} \myparabola{-100}{\x};
\end{tikzpicture}
\end{center}
And of course I'm not really interested in parabolae, but more general functions
which I construct with an analogue of \verb|\myparabola|.
\end{document}
  • That's super helpful, thanks! How do you know all these things? (I know of course that they are written in the manual, but how do you manage to keep them in your memory?) – user121799 Jan 15 '18 at 23:24
  • @marmot I don't remember everything, though some things stick. In the case of \pgfextra, that is something i first heard of through answers by other users here on TeX.SX, and I had recently used it in another answer of mine, so it was fairly fresh in memory. – Torbjørn T. Jan 15 '18 at 23:59

Your Answer

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