9

For a paper, I must draw an ellipse, which is filled by random dots in a coordinate system.

Of course it isn't a problem to draw an ellipse and the coordinate system. Also I know the function "rand" to create random dots in combination with "only marks". How is it possible to create these (random) dots in an ellipse?

12

Here's a very, very easy one. Some (or, in worst case, all) points might be invisible as they are hidden. You can alter \pgfmathsetseed to get another distribution or comment it out to get a new distribution on every run.

Code

\documentclass[tikz, border=2mm]{standalone}

\begin{document}

\begin{tikzpicture}

\draw (0,0) ellipse (4 and 2);
\clip (0,0) ellipse (4 and 2);
\pgfmathsetseed{24122015}
\foreach \p in {1,...,50}
{ \fill (4*rand,2*rand) circle (0.05);
}

\end{tikzpicture}

\end{document}

Output

enter image description here


Edit 1: I played around with it a little, as I wanted to keep all points inside of the ellipse. The second version generates a random x value and then computes a random y value in such a way that it is inside. As there is less "y space" for extremal values of x, the points cluster at the end points of the major axis. The third is an ellipse in polar form: first, an angle is randomly chosen and the radius is computed to be on the inside of the ellipse. Here, the points cluster at the minor axis and the center, a so called Gorthaur1-Distribution.

Code

\documentclass[tikz, border=2mm]{standalone}

\begin{document}

\begin{tikzpicture}
    \draw (0,0) ellipse (4 and 2);
    \clip (0,0) ellipse (4 and 2);
    \pgfmathsetseed{24122015}
    \foreach \p in {1,...,1000}
    { \fill[black]  (4*rand,2*rand) circle (0.05);
    }
\end{tikzpicture}

\begin{tikzpicture}
    \draw (0,0) ellipse (4 and 2);
    \clip (0,0) ellipse (4 and 2);
    \pgfmathsetseed{24122015}
    \foreach \p in {1,...,1000}
    { \pgfmathsetmacro{\x}{4*rand}
        \pgfmathsetmacro{\y}{rand*0.5*sqrt(16-pow(\x,2))}
        \fill[black]    (\x,\y) circle (0.05);
    }
\end{tikzpicture}

\begin{tikzpicture}
    \fill[inner color=black, outer color=yellow!20!black] (0,0) ellipse (4 and 2);
    \clip (0,0) ellipse (4 and 2);
    \pgfmathsetseed{24122015}
    \foreach \p in {1,...,1000}
    { \pgfmathsetmacro{\t}{360*rnd}
        \pgfmathsetmacro{\r}{rnd*4*2/(sqrt(pow(2*cos(\t),2)+pow(4*sin(\t),2)))}
        \pgfmathsetmacro{\c}{abs(\r)/4*100}
        \fill[yellow!\c!red]    (\t:\r) circle (0.05);
        \typeout{\t, \r, \c}
    }
\end{tikzpicture}

\end{document}

Output

enter image description here

enter image description here

enter image description here

1: I totally made this up. Gorthaur is a name Sauron, the villain in the lord of the rings, used in earlier ages ;-) As I usually watch the trilogy with my family over christmas I felt this little joke was in order.

  • Thank you very much! You are a master! I search for this! – danielg Dec 16 '15 at 21:01
  • 1
    @danielg: The clip command is very useful. Hoever, all commands following it will be clipped. To keep the effect local, you can put the clip and relevant commands in a scope. – Tom Bombadil Dec 16 '15 at 21:05
10

Whenever there's a question about filling something with random dots, there has to be an answer using JLDiaz's Poisson Disc Sampling code:

\documentclass{article}
\usepackage{tikz}
\usepackage{poisson}
\begin{document}
\edef\mylist{\poissonpointslist{8}{4}{0.1}{20}}
\begin{tikzpicture}
\begin{scope}
    \clip (4,2) ellipse (4 and 2);
    \foreach \x/\y in \mylist {
        \fill (\x,\y) circle(1pt);
    }
\end{scope}
\draw (4,2) ellipse (4 and 2);
\end{tikzpicture}
\end{document}

And here's the approach from Filling specified area by random dots in TikZ: 150 equally distributed dots that all lie in the ellipse:

The equation for the top half of the ellipse is

sqrt( 2^2 * (1 - x^2/(4^2) )

The antiderivative of the inverse is

2 * asin(x/4)

and the scaling factor is 4/pi.

\documentclass[tikz, border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfmathsetseed{3}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
    hide axis,
    axis equal,
    declare function={a(\x) = sqrt( 2^2 * (1 - \x^2/(4^2) );},
    declare function={b(\x) = -sqrt( 2^2 * (1 - \x^2/(4^2) );},
    declare function={f(\x) = 2 * rad(asin(x/4)) * 4 / pi;}
]
\addplot [only marks, samples=150, domain=-4:4] ({f(x) },{rand * ( a(f(x)) - b(f(x)) ) / 2} );
\draw (0,0) ellipse [x radius=4, y radius=2];
\end{axis}

\end{tikzpicture}

\end{document}

Here's the code for an ellipse with x radius=2 and y radius=1:

\documentclass[tikz, border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\pgfmathsetseed{3}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
    %hide axis,
xmin=-4, xmax=4,
    axis equal,
    declare function={a(\x) = sqrt( 1^2 * (1 - \x^2/(2^2) );},
    declare function={b(\x) = -sqrt( 1^2 * (1 - \x^2/(2^2) );},
    declare function={f(\x) = 2 * rad(asin(x/4)) * 2 / pi;}
]
\addplot [only marks, samples=150, domain=-4:4] ({f(x) },{rand * ( a(f(x)) - b(f(x)) ) / 2} );
\draw (0,0) ellipse [x radius=2, y radius=1];
\end{axis}

\end{tikzpicture}

\end{document}
  • However, that does not appear truly random. With that many dots one would expect some clustering and overlaps, right? – Tom Bombadil Dec 16 '15 at 20:43
  • It's not "truly random" in that the points aren't independent, but I think it's prettier than completely random points. It's definitely not "ordered" (i.e. there's no grid structure). Whether this distribution is useful probably depends on the exact use case. – Jake Dec 16 '15 at 20:58
  • Yeah, definitely looks nice, I'll remember this for future applications :D – Tom Bombadil Dec 16 '15 at 21:00
  • @Jake Thank you for your answer! Your solution is also good and simple. But I have a little problem with the scaling factor, which you write here. Because I change your code with sqrt( 1^2 * (1 - x^2/(2^2) ) at the specific places (I want to create an ellipse with xRadius = 2 and yRadius = 1). Also I change the scaling factor to 2 / pi, but I get an error. Latex said: ! Missing number, treated as zero ! He write the "addplot - line" as the mistake place. Where is my mistake? If you want, I can post this minimal code. – danielg Dec 17 '15 at 22:53
  • @danielg: I've edited my answer to show how to get an ellipse with x radius=2 and y radius=1. Let me know if that helps – Jake Dec 18 '15 at 7:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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