3

I'm making a drawing where I need nodes sampled uniformly at random within another node.

Here is my current attempt:

\documentclass[11pt]{article} 
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,automata,chains,calc, decorations,decorations.text,decorations.pathmorphing,shapes.callouts,shapes.symbols}
\newcommand{\tikzcircle}[2][red,fill=red]{\tikz[baseline=-0.5ex]\draw[#1,radius=#2] (0,0) circle ;}%
\usepackage{ifthen}

\begin{document}


\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=5cm,
  thick,main node/.style={circle,fill=green!20,draw,font=\sffamily\Large\bfseries}]
  \node[main node] (1) {\begin{tikzpicture}
    \foreach \l in {1,2,...,10}
      {
          \coordinate (myangle) at (rand*180:rand*20pt);
          \node[draw=black,thick,fill=green,fill opacity=0.3,inner sep=0pt,minimum size=5pt] at (myangle) {};
      }
  \end{tikzpicture}};
\end{tikzpicture}
\end{document}

The problem with this approach is first that the points are not uniformly at random in a circle. Essentially I need to define a local variable, call it u, which is a sum of two rand. Then I define another variable u' as u if u<1 and 2-u otherwise. Then myangle should then be defined as the point (rand*180:u'*20pt).

That solves the problem of uniform sampling (unfortunately I don't know how to define local variables so I was unable to achieve this :( ). The next problem is that the inside picture is in a box but I would like it to be in a circle such that the margin around the randomly sampled points does not appear so big, any ideas on how to let the output of tikzpicture be a circle instead of a square? Or can I crop it afterwards such that it works out?

Thank you in advance!

Edit: The answer below provides a great example of how to sample uniformly in a circle and that's why I selected it as the "correct" answer. I managed to remove the margin inside the circles by letting the outer nodes have the options

  inner sep=0,outer sep=0

Hope that helps if anyone else runs into this problem.

2 Answers 2

5

For sampling uniformly in a circle, you can use the approach described in http://www.anderswallin.net/2009/05/uniform-random-points-in-a-circle-using-polar-coordinates/: sample the angle uniformly, but use the square root of a random number between 0 and 1 for scaling the radius. You can use the random function for this, which returns a pseudo-random number between 0 and 1:

\documentclass[11pt]{article} 
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\pgfmathsetseed{2}
\edef\radius{2cm}
\foreach\i in {1,...,250}{
    \draw [gray] (0,0) circle [radius=\radius];
    \pgfmathsetmacro\randA{random}
    \pgfmathsetmacro\randB{sqrt(random())}
    \fill ({\randA*360}:{\radius*\randB}) circle [radius=2pt];
}
\end{tikzpicture}
\end{document}
1

You can sample in any region (for example in any kind of nodes) by sampling in a rectangle and clipping.

\documentclass[tikz,border=7mm]{standalone}
\usetikzlibrary{calc, shapes.geometric,shapes.misc, shapes.symbols}
\begin{document}
  \begin{tikzpicture}
    \node[circle,draw,minimum size=2cm, path picture ={
      \foreach \i in {1,...,100}
      \path let \p1=(path picture bounding box.south west),
                \p2=(path picture bounding box.north east),
                \n1={rnd}, \n2={rnd} in
      ({\n1*\x1+(1-\n1)*\x2},{\n2*\y1+(1-\n2)*\y2}) node[shape=star, star points=5,fill=red,draw,minimum size=4pt, inner sep=0pt]{};
    }
    ] {};
  \end{tikzpicture}
\end{document}

enter image description here

And if you replace circle by cloud,cloud puffs=7 you obtain :

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .