29

How can I construct an asteroid belt in TikZ? That is my question: I get everything right, but I do not know how to make the asteroid belt.

I have no code to add besides the preamble with TikZ package since I don't know where to start.

enter image description here

2
  • 4
    What you want is unclear/overly broad. Do you need the output to look exactly like the screenshot you posted? Does the background have to be black? Must the planets look realistic? Or do you need more simple schematics? You should refine your question to explain what the specs are; then they'll be able to give you pointers as to how to get there.
    – jub0bs
    Commented May 2, 2013 at 16:53
  • @JubobsI can do everything except the asteroid belt. That is my question how to make the asteroid belt.
    – dustin
    Commented May 2, 2013 at 17:01

6 Answers 6

30

Quick and Dirty

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{backgrounds}
\tikzset{
    random dot/.style args={#1*#2:#3}{random dot*={#1}*{#2}:{#3} and {#3}},
    random dot*/.style args={#1*#2:#3 and #4}{
        insert path={\foreach \throwaway in {1,...,#1} {(canvas polar cs: angle={#2+rnd}, x radius={#3+#3/.5cm*rand}, y radius={{#4+#4/.5cm*rand}}) circle[]}}}
}
\tikzset{every picture/.append style={show background rectangle,background rectangle/.style={fill=black}, radius=.4pt+.2pt*rand}}
\begin{document}
\tikz{
  \draw[gray] circle[radius=2cm];
  \foreach \angle in {0,...,360}
    \fill[white] [random dot=2*\angle:2cm];}

\tikz{
  \draw[gray] circle[radius=2cm];
  \foreach \angle in {0,...,360}
    \fill[white] [random dot=1*\angle:2cm];}

\tikz{
  \draw[gray] circle[x radius=2cm, y radius=1.5cm];
  \foreach \angle in {0,...,360}
    \fill[white] [random dot*=1*\angle:2cm and 1.5cm];}
\end{document}

Output

enter image description here

enter image description here

enter image description here

PGF-keys supported

Code

\documentclass[tikz,convert=false]{standalone}
\makeatletter
\pgfkeys{
    /tikz/belt/.is family,
    /tikz/belt,
    radius/.style={x radius={#1}, y radius={#1}},
    radius dot/.style={x radius dot={#1}, y radius dot={#1}},
    x radius/.initial=1cm,
    y radius/.initial=1cm,
    x radius dot/.initial=.4pt,
    y radius dot/.initial=.4pt,
    randomize/.initial=1,
    randomize dot/.initial=1,
    start angle/.initial=0,
    end angle/.initial=360,
    step angle/.initial=1,
    density/.initial=1,
    x ring size/.initial=.1cm,
    y ring size/.initial=.1cm,
    do/.style={
        insert path={
            \pgfextra\pgfmathsetmacro\tikz@belt@next@angle{\pgfkeysvalueof{/tikz/belt/start angle}+\pgfkeysvalueof{/tikz/belt/step angle}}\endpgfextra
            \foreach \tikz@belt@angle in {\pgfkeysvalueof{/tikz/belt/start angle},\tikz@belt@next@angle,...,\pgfkeysvalueof{/tikz/belt/end angle}} {
                \foreach \@tempa[evaluate=\qrr@tikz@belt@randA using \pgfkeysvalueof{/tikz/belt/randomize}*(2*rnd-1)*\pgfkeysvalueof{/tikz/belt/step angle},
                                 evaluate=\qrr@tikz@belt@randB using \pgfkeysvalueof{/tikz/belt/randomize}*(2*rnd-1),
                                 evaluate=\qrr@tikz@belt@randC using \pgfkeysvalueof{/tikz/belt/randomize}*(2*rnd-1),
                                 evaluate=\qrr@tikz@belt@randD using \pgfkeysvalueof{/tikz/belt/randomize dot}*(.5+rnd),
                                 evaluate=\qrr@tikz@belt@randE using \pgfkeysvalueof{/tikz/belt/randomize dot}*rnd*360,] in {1,...,\pgfkeysvalueof{/tikz/belt/density}} {
                    +(canvas polar cs:%
                        angle={\tikz@belt@angle+\qrr@tikz@belt@randA},
                        x radius={\pgfkeysvalueof{/tikz/belt/x radius}+\pgfkeysvalueof{/tikz/belt/x ring size}*\qrr@tikz@belt@randB},
                        y radius={\pgfkeysvalueof{/tikz/belt/y radius}+\pgfkeysvalueof{/tikz/belt/y ring size}*\qrr@tikz@belt@randC})
                        circle[rotate=\qrr@tikz@belt@randE, x radius={\pgfkeysvalueof{/tikz/belt/x radius dot}*\qrr@tikz@belt@randD}, y radius={\pgfkeysvalueof{/tikz/belt/y radius dot}*\qrr@tikz@belt@randD}]
                }
            }
        }
    }
}
\makeatother
\newcommand*{\debug}[1][]{%
\fill[even odd rule,gray!50,#1] circle[x radius=\pgfkeysvalueof{/tikz/belt/x radius}+\pgfkeysvalueof{/tikz/belt/x ring size},
                                      y radius=\pgfkeysvalueof{/tikz/belt/y radius}+\pgfkeysvalueof{/tikz/belt/y ring size}]
                               circle[x radius=\pgfkeysvalueof{/tikz/belt/x radius}-\pgfkeysvalueof{/tikz/belt/x ring size},
                                      y radius=\pgfkeysvalueof{/tikz/belt/y radius}-\pgfkeysvalueof{/tikz/belt/y ring size}];}
\begin{document}
\tikz[belt/x radius=2cm] {\debug[gray!25]\fill[gray] [belt/do];}
\tikz[belt/x radius=3cm, belt/x radius dot=.3pt, belt/x ring size=1cm] {\debug\fill[black] [belt/do];}
\tikz\fill[gray,belt/do];
\tikz[belt, step angle=5, density=5]\fill[gray,belt/do]; % Both belt/step angle and belt/density influence the density of the dots in anti-proportional ways. (density should be integer and greater 0).
\tikz[belt, start angle=30, end angle=160]\fill[belt/do]; % not a full circle
\end{document}

Output

(Compile yourself. Don’t want to blow up this answer.)

6
  • It is more realistic if you also randomly vary the radius of the white dots. Commented May 2, 2013 at 18:25
  • 1
    @dustin Scratch that. I have updated the code that works with the stable PGF version (2.10). I have switched to the canvas polar cs which is much easier to parse (for humans and for TikZ). Commented May 2, 2013 at 19:46
  • @Bugbusters See the update. I have included a randomization in the radius of the dots (and as the rand gets executed twice the dots becomes ellipses), there are other ways, of course. Commented May 2, 2013 at 19:47
  • Elliptical dots make the asteroids more realistic. Commented May 2, 2013 at 19:52
  • 1
    @dustin Yes, of course. You can say \begin{tikzpicture}[random dot/.style=…] The every picture stuff is a) only for the black background which I assume you have created differently and b) sets the size of the dots. This can also specified in the path: \draw[gray, radius=.4pt+.2pt*rand] …. Commented May 2, 2013 at 19:58
19

With TikZ

I don't know how random your asteroids have to be, so this is maybe not good enough. It uses the dots pattern, so the 'asteroids' are evenly distributed. The border of the belt is randomized with the random steps decoration.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{patterns,decorations.pathmorphing}
\begin{document}
\begin{tikzpicture}[decoration={random steps,segment length=5pt}]
\draw [black!40] circle[radius=2.65cm];
\fill [pattern color=black,pattern=dots,even odd rule,decorate] circle[radius=2.5cm] circle[radius=2.8cm];
\end{tikzpicture}
\end{document}

not-very-good-looking asteroid belt created with TikZ

With Metapost

The following examples uses the luamplib package, and must be compiled with lualatex.

White asteroids, varying size, on black background:

\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
r=2cm;
fill unitsquare scaled 4.8cm shifted (-1.2*r,-1.2*r) withcolor black;
for i=0 upto 720:
   pickup pencircle scaled uniformdeviate(1.5);
   drawdot (r*cosd(i) + 2*normaldeviate, r*sind(i) + 2*normaldeviate) withcolor white;
endfor;
endfig
\end{mplibcode}
\end{document}

enter image description here

\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
r=2cm;
pickup pencircle scaled 1pt;
for i=0 upto 360:
   drawdot (r*cosd(i) + 2*normaldeviate, r*sind(i) + 2*normaldeviate);
endfor;
endfig
\end{mplibcode}
\end{document}

asteroid belt by Metapost

0
17

Here is a simple solution via TikZ with random rotated ellipse for each asteroid.

enter image description here

The code (ten lines):

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \fill[black] (-2,-2) rectangle (2,2);
  \foreach \aster in {1,...,1000}{
    \fill[white,rotate=360*rnd] (rnd*360:rnd*0.2+1.5) circle(rnd*0.01+0.005 and rnd*0.01+0.005);
  }
\end{tikzpicture}
\end{document}

Edit: Here is a variant to put all asteroids on an ellipse.

enter image description here

The code:

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \fill[black] (-4,-4) rectangle (4,4);
  \foreach \aster in {1,...,1000}{
    \fill[white] (rnd*360:3 and 2.5) ++(rnd*360:rnd*.3)
    circle[x radius=rnd*.02+.01,y radius=rnd*.02+.01,rotate=rnd*360];
  }
\end{tikzpicture}
\end{document}

Second edit: with Sun and planets.

enter image description here

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \fill[black] (-5.5,-5.5) rectangle (5.5,5.5);
  \fill[orange] circle(0.2)
  ++(0:.1) node[anchor=west,font=\footnotesize]{Sun};
  \foreach \name/\radius in {Mercury/0.387,Venus/0.723,Earth/1,Mars/1.524,Jupiter/5.202}{
    \draw[gray] circle(\radius);
    \pgfmathsetmacro\angle{360*rnd}
    \fill[white] (\angle:\radius) circle(.05)
    ++(0:.05) node[anchor=west,font=\footnotesize]{\name};
  }
  \foreach \aster in {1,...,3000}{
    \fill[white] (rnd*360:2.55) ++(rnd*360:rnd*.45)
    circle[x radius=rnd*.02+.01,y radius=rnd*.02+.01,rotate=rnd*360];
  }
\end{tikzpicture}
\end{document}
1
  • 1
    That is rather simple.
    – dustin
    Commented Jul 13, 2013 at 8:09
15
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\SpecialCoor\pstVerb{realtime srand}

\begin{document}
\begin{pspicture}(-2,-2)(2,2)
\psframe*(-2,-2)(2,2)
\psset{linecolor=white}
\multido{\rA=0.0+1.131}{1000}{\qdisk(!1.5 Rand 0.5 sub 3 div add \rA\space PtoC){!Rand 20 div}}%
\end{pspicture}
\end{document}

enter image description here

2
  • 2
    This really is an advertisement for PSTricks: 10 lines for the whole solution!
    – Keks Dose
    Commented May 19, 2013 at 15:01
  • I use randomly specified angles rather than equally spaced ones. Commented Nov 9, 2013 at 21:17
14

TikZ Decorations

When I saw this question I thought of using the tikz decoration methods to answer it. After several hours poring over Chapters 21 and 30 of the manual I figured out how to do it in a few lines.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{backgrounds}

\pgfkeys{
   /pgf/decoration/asteroids/.style={
      markings,
      mark=between positions 0 and 1 step \pgfdecorationsegmentlength with {
         \draw[each asteroid] (0pt,rand*\pgfdecorationsegmentamplitude) circle[
            radius=((1/\pgfdecorationsegmentaspect-\pgfdecorationsegmentaspect)*rnd+\pgfdecorationsegmentaspect)*
            \pgfmetadecorationsegmentamplitude
         ];
      },
      aspect=0.618,       % minimum aspect of asteroid (sort of)
      amplitude=5mm,      % maximum distance from asteroid to path
      meta-amplitude=1pt, % radius of each asteroid
      segment length=1pt, % separation along path between asteroids
   },
   /tikz/each asteroid/.style={draw}
}

\begin{document}
\begin{tikzpicture}[
   show background rectangle,
   background rectangle/.style={fill=black},
   each asteroid/.style={draw=none,fill=white},
   decoration={asteroids}
]
   \draw[gray,postaction=decorate] (0,0) circle [radius=4cm];
\end{tikzpicture}
\end{document}

sample code output

The aspect key is used to define the eccentricity of each asteroid. If the aspect is a, then each radius (x and y) of the asteroid is set to be a random number between a and 1/a times the value of the meta-amplitude key. So the aspect could end up being as much as a^2.

The nice thing about this code is it can be customized for other asteroids along other paths:

\begin{tikzpicture}[
   each asteroid/.style={draw=red,fill=green,opacity=0.5},
   decoration={asteroids,
      meta-amplitude=5mm,
      segment length=1cm,
      aspect=1
   }
]
   \draw[postaction=decorate] (0,0) -- ++(4,0) -- ++(-4,4)--cycle;
\end{tikzpicture}

sample code output 2

3
  • Excellent idea! Decorations are usually my last resort. One could also randomize the step part with something like \pgfdecorationsegmentlength*(rnd+.5). Commented May 3, 2013 at 3:20
  • @Qrrbrbirlbel: thanks. But why last resort? I've been looking for an excuse to learn decorations because it seems like the real TiKZ way to do things. Commented May 3, 2013 at 11:22
  • I've been looking for an excuse to not use decorations because I always need to look up the library names, the key syntax and the like. But I agree, it sure seems like the way to do stuff. :) Commented May 3, 2013 at 16:39
12

With PSTricks. I use randomly positioned ellipses with random axes and orientation.

\documentclass[pstricks,border=12pt]{standalone}

\pstVerb{realtime srand}

\begin{document}
\begin{pspicture}(-4,-4)(4,4)
\psframe*(-4,-4)(4,4)
\psset{linecolor=lightgray}
\psLoop{1000}{\psellipse*[rot=!rand 360 mod](!Rand 2 div 3 add rand 360 mod PtoC)(!Rand 30 div 0.02 add Rand 30 div 0.02 add)}
\end{pspicture}
\end{document}

enter image description here

Note that Rand no longer produces a random real number between 0 and 0.5 inclusive. Its definition had been tacitly changed. Now it produces a random real number between 0 and 1 inclusive. It is not documented, nor announced, but it is still fun!

9
  • Is it possible to have a white background. black background (not recommended) is printer ink intensive :) Commented May 2, 2013 at 17:58
  • @texenthusiast: it is not possible. Commented May 2, 2013 at 18:03
  • @MarcvanDongen: Yes. There is no white color defined in PSTricks. :-) Commented May 2, 2013 at 18:44
  • @MarcvanDongen: Please don't say that in your book. Commented May 2, 2013 at 18:49
  • 1
    @Werner: It was just a joke initiated by texenthusiast. Commented May 2, 2013 at 19:24

You must log in to answer this question.

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