Understanding a macro for drawing (irregular) circles

I'm trying to understand the code in an answer regarding drawing closed paths so that I might be able to manipulate it further. Here is a small portion of it:

\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections,calc}
\usetikzlibrary{decorations.pathreplacing,decorations.markings}

% decorating every segment of a path
% https://tex.stackexchange.com/a/69225
\tikzset{
% style to apply some styles to each segment of a path
on each segment/.style={
decorate,
decoration={
show path construction,
moveto code={},
lineto code={
\path [#1]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
},
curveto code={
\path [#1] (\tikzinputsegmentfirst)
.. controls
(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
..
(\tikzinputsegmentlast);
},
closepath code={
\path [#1]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
},
},
},
% style to add an arrow in the middle of a path
mid arrow/.style={postaction={decorate,decoration={
markings,
mark=at position .5 with {\arrow[#1]{stealth}}
}}},
}

\pgfextra {\pgfmathsetmacro\len{(#1)+rand*(#2)}}
+(0:\len pt)
\foreach \a in {10,20,...,350}{
\pgfextra {\pgfmathsetmacro\len{(#1)+rand*(#2)}}
-- +(\a:\len pt)
} -- cycle
}

\begin{document}
\begin{tikzpicture}
% Set the seed for the random function to a fixed value to get
% the same picture at every run
\pgfmathsetseed{12345}
\coordinate (c) at (0,0);
\draw[blue,rounded corners=1mm] (c) \irregularcircle{3cm}{1.5mm};
\draw[red,rounded corners=1mm] (c) \irregularcircle{1cm}{1.5mm};

\end{tikzpicture}
\end{document}


I get stuck with understanding the following macro:

\newcommand\irregularcircle[2]{% radius, irregularity
\pgfextra {\pgfmathsetmacro\len{(#1)+rand*(#2)}}
+(0:\len pt)
\foreach \a in {10,20,...,350}{
\pgfextra {\pgfmathsetmacro\len{(#1)+rand*(#2)}}
-- +(\a:\len pt)
} -- cycle
}


This Tikz-pfg manual says that

... this operation (\pgfextra) should only be used by real experts and should only be used deep inside clever macros, not on normal paths.

Would anybody explain how each line in the definition of the macro \irregularcircle works?

• Every line? If you need every line explained, then there are some lines which will not be explainable in an answer here, I think. If you really are asking about the use of \pgfextra, then why not say so? – cfr Mar 23 '17 at 1:58
• If you want to understand just the irregular circle part, you can delete the \tikzset part. – Symbol 1 Mar 23 '17 at 2:48
• @cfr: Thank you for your comment. "Each line" means the six lines in the definition of the macro irregularcircle, not all the lines in the code mentioned in the beginning. My question is indeed mainly about \pgfextra. I don't understand the part +(0:\len pt) either. I should have made the question clearer. – Jack Mar 23 '17 at 12:26
• @Symbol1: Thank you for your comment. I was trying to tailor the code to a "minimum" example. I didn't know that that part does not matter. I will try to improve my question later. – Jack Mar 23 '17 at 12:28

The \irregularcircle macro assumes that the current point is the center of the irregular circle. The points calculated by the macro are relative to this center thanks to the notation +(...).

The \pgfextra macro (or operation) allows to interrupt momentarily the current path to evaluate any code (or, as said in pgfmanual, to "do some calculations or some other stuff").

In this particular case and with the current version of TikZ/pgf, the \pgfextra operation is not really necessary. I could have written the following macro:

\newcommand\irregularcircle[2]{% radius, irregularity
+(0:{(#1)+rand*(#2)})
\foreach \a in {10,20,...,350}{
-- +(\a:{(#1)+rand*(#2)})
} -- cycle
}


The braces {...} around a calculation included in a coordinate allows to use parenthesis in this calculation.

An even simpler version could be:

\newcommand\irregularcircle[2]{% radius, irregularity
+(0:#1+rand*#2)
\foreach \a in {10,20,...,350}{
-- +(\a:#1+rand*#2)
} -- cycle
}


But in this case, the values of the two parameters can no longer be any calculations but just simple values.

• Thank you for your answer! Would you say a few words about how +(0:{(#1)+rand*(#2)}) and -- +(\a:{(#1)+rand*(#2)}) work or point me to some references? – Jack Mar 23 '17 at 12:32
• – Paul Gaborit Mar 23 '17 at 12:57
• I see. (And (x:y) means the polar coordinates.) This is very helpful! – Jack Mar 23 '17 at 14:27