# How to color randomly drawn dots within a circle?

I'd like to create the following plot (illustrating a population and a random sample) with tikz where the dots are created/placed randomly; all dots inside the circle, however, are supposed to be coloured in red:

Using answers based on previous (somewhat similar) questions, I was able to create the following plot.

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (4,0) -- (4,4) -- (0,4) -- cycle;
\foreach \x in {1,...,40}
{
\pgfmathrandominteger{\a}{10}{390}
\pgfmathrandominteger{\b}{10}{390}
\fill (\a*0.01,\b*0.01) circle (0.1);
};
\draw (2,2) circle (1cm);
\end{tikzpicture}
\end{document}


However, I have no clue how to color the dots inside the circle in red (I have a vague idea that involves basic geometry and ifelse by checking every dot if it is placed inside the circle... does that make sense?).

• a simpler way imho would be to draw some red dots inside a circle and some black ones outside, in two different loops... and maybe using polar coordinates would help! – Davide Jan 9 '16 at 7:52
• What happens to the ones on the boundary? – percusse Jan 9 '16 at 8:56

Mathematically, a circle with radius r with center at (a,b) is defined by the equation

(x-a)^2 + (y-b)^2 = r^2


So, to check if a point lies within this circle, you can check if the random points (x,y) satisfy

(x-a)^2 + (y-b)^2 <= r^2


i.e. they are less than r away from the center of the circle. If you use <=, then points on the border still count as "inside", if you use <, they won't.

To do that in TikZ, you can use the ifthenelse function provided by PGF Math. That is:

\pgfmathparse{ ifthenelse(condition, "value A", "value B")}


If the condition is satisfied, \pgfmathresult will contain "value A", if not it will contain "value B". We can use this to set the color either to "black" or "red":

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}

% Random seed for RNG
\pgfmathsetseed{\number\pdfrandomseed}

% Define circle parameters
\newcommand{\cX}{2}
\newcommand{\cY}{2}
\newcommand{\cR}{1}

\draw (0,0) -- (4,0) -- (4,4) -- (0,4) -- cycle;

\foreach \x in {1,...,40}
{
% Find random numbers
\pgfmathrandominteger{\a}{10}{390}
\pgfmathrandominteger{\b}{10}{390}

% Scale numbers nicely
\pgfmathparse{0.01*\a}\let\a\pgfmathresult
\pgfmathparse{0.01*\b}\let\b\pgfmathresult

% Check if numbers are inside circle
\pgfmathparse{ifthenelse((\a-\cX)^2 + (\b-\cY)^2 <= \cR^2,%
"red",
"black")}
\fill[\pgfmathresult] (\a,\b) circle (0.1);
};
\draw (\cX,\cY) circle (\cR);
\end{tikzpicture}
\end{document}


If you don't mind working in points, then the TikZ math library may be helpful. Here, points are rejected if they would lie on the border of the circle.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}[x=1pt,y=1pt]
\tikzmath{%
coordinate \c, \p, \q;
\q = (100, 100);
\c = (30, 30);
\R = 50;
\r = 1;
{
\draw (-\qx, -\qy) rectangle (\qx, \qy);
};
\x = \qx - \r; \y = \qy - \r;
for \i in {0,...,100}{
\p = (rand * \x, rand * \y);
\v = veclen(\cx - \px, \cy - \py);
if \v > (\R + \r) then {
{ \fill [black] (\p) circle [radius=\r]; };
} else {
if \v < (\R - \r) then {
{ \fill [red] (\p) circle [radius=\r]; };
};
};
};
}
\end{tikzpicture}
\end{document}


Here is one "clipping mask" solution:

\documentclass[varwidth, border=7pt]{standalone}
\usepackage{tikz}

\begin{document}
% define clip mask with random points
\fill[transparent!0] foreach ~ in {1,...,100}{(rand,rand) circle (0.02)};
% use it to clip rectangle and circle
\begin{tikzpicture}
\begin{scope}
\fill[red] (2,2) circle (1cm);
\end{scope}
\draw (0,0) rectangle (4,4);
\draw[red] (2,2) circle (1cm);
\end{tikzpicture}
\end{document}


Metapost is also very good at this sort of diagram.

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

numeric N, s, r;
N = 100; % population
s = 300; % size of square
r = 40; % radius of circle
z0 = (200,160); % center of circle;
color selected; selected = .73 red;

for i=1 upto N:
z[i] = (uniformdeviate s, uniformdeviate s);
drawdot z[i] withpen pencircle scaled 4
if r > length(z[i]-z0): withcolor selected fi;
endfor

draw fullcircle scaled 2r shifted z0 withcolor selected;
draw unitsquare scaled s;

endfig;
end.


Here's yet another solution that:

1. Sets the circle whose center defines the coordinate center, with a radius \ra (expressed in pt).
2. A \foreach loop that creates 200 random points, but you can change the number.
3. A measurement is done between center and each dot point.
4. Using an \if statement, if the length is above 50pt, dots will be standard black, otherwise, they'll be colored red.

## Code

\documentclass[margin=20pt]{standalone}
\usepackage{tikz,tkz-euclide}
\usetkzobj{all}

\usetikzlibrary{calc}
\newcommand\ra{50}

\begin{document}
\begin{tikzpicture}
\draw (1,2) coordinate (center) circle (\ra pt);

\foreach \point in {1,...,200}{%
\pgfmathparse{rand}
\pgfmathsetmacro\xdot{-7*\pgfmathresult}
\pgfmathparse{rand}
\pgfmathsetmacro\ydot{-5*\pgfmathresult}
%
\coordinate (c\point) at (\xdot,\ydot);
\tkzCalcLength(center,c\point) \tkzGetLength{myl}
\pgfmathtruncatemacro\distance{\myl}
\ifnum\distance>\ra
\fill (c\point) circle (2pt);
\else
\fill[red] (c\point) circle (2pt);
\fi
}%
\end{tikzpicture}
\end{document}