# Drawing circular paths in random locations (TikZ)

How can I draw circular paths as shown below in random locations (randomly spaced in the x and y directions)?

MWE:

\documentclass[border = 0.12cm,tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing,snakes}
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}[x = 4.5in, y = 2in]
\fill [blue!20] (0,0) -- (1,0) -- (1,0.5) -- (0,0.5) -- cycle;

\foreach \x in {0.05,0.075,0.25,0.35,0.45,0.55,0.65,0.85}
\draw [>=stealth,->] (\x,0.1) arc (280:0:.1cm) -- +(283:0.05cm);

\end{tikzpicture}
\end{document}


-
May they overlap? – Jake Jul 16 '14 at 11:19
Instead of \fill [blue!20] (0,0) -- (1,0) -- (1,0.5) -- (0,0.5) -- cycle;, you can use \fill [blue!20] (0,0) rectangle (1,0.5);. – Jake Jul 16 '14 at 11:20
@Jake No they should not overlap – KatyB Jul 16 '14 at 11:33

You can use the poisson disc sampling library (you can get it in this answer).

You need to copy/paste the content of poisson.sty and poisson.lua from that answer into two files with these names. You need also a working lualatex to compile.

Then, using it, you can compile the following code (this one requires PGF=>3.0, see later on for other examples that work with PGF<3.0)

\documentclass{article}
\usepackage{tikz}
\usepackage{poisson}
\begin{document}
\edef\mylist{\poissonpointslist{5}{5}{0.5}{20}}

\tikzset{
circular arrow/.pic={
\draw [>=stealth,->] (0,0.1) arc (280:0:.1cm) -- +(283:0.05cm);
}
}
\begin{tikzpicture}
\foreach \x/\y in \mylist {
\path (\x,\y) pic {circular arrow};
}
\end{tikzpicture}
\end{document}


The line \edef\mylist{\poissonpointslist{5}{5}{0.5}{20}} is the one which creates the random coordinates to place each pic. You can change the parameters: the first two are the width an height of the rectangle in which the coordinates will be placed. The third one (0.5) is the minimum distance allowed between the random coordinates. The last one (20) is used internally by the algorithm and provides a trade-off between speed and results, and usually it is set to a value between 15 or 30.

Here is another example in which the arrows are more densely packed, and which does not use pic (and thus it compiles with PGF<3.0, but still requires lualatex)

\documentclass{article}
\usepackage{tikz}
\usepackage{poisson}
\begin{document}
\edef\mylist{\poissonpointslist{5}{5}{0.25}{20}}

\begin{tikzpicture}
\foreach \x/\y in \mylist {
\draw[>=stealth, ->] (\x,\y) arc (280:0:.1cm) -- +(283:0.05cm);
}
\end{tikzpicture}
\end{document}


Result:

# Update

To create the rectangle you provided in your example, I would use the same scale in x and y, to enforce the even distribution of the centers. Also, the size of the area to be filled by the algorithm should be a bit smaller than your filled rectangle (because the algorithm only generates coordinates, not knowing in advance the size of the pictures you will draw at each coordinate). So, for example:

\edef\mylist{\poissonpointslist{4.4}{0.9}{0.2}{20}}
\begin{tikzpicture}[x=1in, y=1in]
\fill[blue!20] (0,0) rectangle (4.5,1);
\foreach \x/\y in \mylist {
\draw[>=stealth, ->] (.02,0.02) +(\x,\y) arc (280:0:.1cm) -- +(283:0.05cm);
}
\end{tikzpicture}


This example does not require PGF3.0, and produces:

-
This does not work on mine. Is there a method that does not require lualatex and PGF>=3.0 – KatyB Jul 16 '14 at 12:33
@KatyB The last two examples do not require PGF 3.0. This requirement is only for the first one which uses pic. Lualatex is however required to compile, but as long as you have lualatex installed, there are no other dependencies, so it should work. What problem in particular did you have? I edited the question to give some more instructions and clarifications. – JLDiaz Jul 16 '14 at 14:12

An alternative method, which is much slower and leads to much less appealing results than JLDiaz's Poisson sampling is the brute force one from tikz: Distribute evenly and randomly circles. The only advantage is that this doesn't require lualatex.

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\def\xlist{4}
\def\ylist{4}

\newcommand{\fillrandomly}[4]{
\pgfmathsetmacro\diameter{#3*2}
\draw (0,0) rectangle (#1,#2);
\foreach \i in {1,...,#4}{
\pgfmathsetmacro\x{0.5*#3+rnd*(#1-#3)}
\pgfmathsetmacro\y{0.5*#3+rnd*(#2-#3)}
\xdef\collision{0}
\foreach \element [count=\i] in \xlist{
\pgfmathtruncatemacro\j{\i-1}
\pgfmathsetmacro\checkdistance{ sqrt( ({\xlist}[\j]-(\x))^2 + ({\ylist}[\j]-(\y))^2 ) }
\ifdim\checkdistance pt<\diameter pt
\xdef\collision{1}
\breakforeach
\fi
}
\ifnum\collision=0
\xdef\xlist{\xlist,\x}
\xdef\ylist{\ylist,\y}
\draw [>=stealth,->] (\x,\y) ++(280:#3) arc (280:0:#3) -- +(283:0.05cm);
\fi

}
}

\begin{tikzpicture}
\pgfmathsetseed{1}
\fillrandomly{10}{4}{0.1}{50}

\end{tikzpicture}
\end{document}

-