Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}

share|improve this question
    
May they overlap? –  Jake Jul 16 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 at 11:20
    
@Jake No they should not overlap –  KatyB Jul 16 at 11:33

2 Answers 2

up vote 9 down vote accepted

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}

Result

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:

Second example

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:

Result

share|improve this answer
    
This does not work on mine. Is there a method that does not require lualatex and PGF>=3.0 –  KatyB Jul 16 at 12:33
1  
@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 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}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.