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.

The planet and a ring are easily drawn. The challenge is to layer them in such a way that the far side of the ring is hidden from view behind the planet, and the near side of the ring eclipses the planet in the foreground. My instinct tells me that this can be done using clipping, scopes, or the backgrounds package, but I apparently lack the cleverness to turn the trick.

Here's the code for Saturn and one ring:

\documentclass{article}

\usepackage{tikz}

\begin{document}

%Saturn on top
\begin{tikzpicture}
\draw[fill=blue] (0,-.2) circle [x radius=4, y radius=1];
\draw[fill=white] (0,0) circle [x radius=3, y radius=.5];
\draw[fill=red] (0,0) circle [radius=2];
\end{tikzpicture}

\bigskip

%ring on top
\begin{tikzpicture}
\draw[fill=red] (0,0) circle [radius=2];    
\draw[fill=blue] (0,-.2) circle [x radius=4, y radius=1];
\draw[fill=white] (0,0) circle [x radius=3, y radius=.5];    
\end{tikzpicture}

\end{document}  
share|improve this question

4 Answers 4

up vote 27 down vote accepted

Example with some clipping:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
  % red Saturn as background
  \draw[fill=red] (0,0) circle [radius=2];
  % blue ring with white in the middle
  \draw[fill=blue, even odd rule]
    (0,-.2) circle [x radius=4, y radius=1]
    (0,0) circle [x radius=3, y radius=.5];
  % redraw red Saturn in the foreground with clipping
  \begin{scope}
    \clip[overlay] (-2.1,0) rectangle (2.1,2.1);
    \draw[fill=red] (0,0) circle [radius=2];
  \end{scope}
\end{tikzpicture}

\end{document}

Remarks:

  • Instead of filling the interior of the ring with white, the code uses option even odd rule for filling. The "white" interior is specified twice for filling. According to that rule, it is not filled with the fill color.

Result

share|improve this answer
2  
Bravo! That's exactly what I thought could be done, but couldn't do it. Thanks, Heiko. –  steven_nevets Jan 25 at 20:41
    
That looks strangely familiar. –  episanty Jan 26 at 2:45

With PSTricks just for fun as usual. No clipping used here.

\documentclass[pstricks,border=12pt]{standalone}
\begin{document}
\begin{pspicture}[linecolor=blue](-4,-2)(4,2)
    \pscustom*{\psellipticarcn(4,1){180}{0}\psellipticarc(0,.2)(3,.5){0}{180}}
    \pscircle*[linecolor=red]{2}
    \pscustom*{\psellipticarc(4,1){180}{0}\psellipticarcn(0,.2)(3,.5){0}{180}}
\end{pspicture}
\end{document}

enter image description here

share|improve this answer
3  
Can you make it animated with an actual asteroid belt rotating :-) just saying.... –  azetina Jan 25 at 23:24
1  
@azetina: I am thinking of it. –  In PSTricks we trust Jan 25 at 23:40

Another example:

\documentclass[x11names]{beamer}
\usepackage{lmodern,tikz}
\usetikzlibrary{decorations.markings,overlay-beamer-styles}

\pgfdeclareverticalshading{Saturn}{2cm}{
color(0cm)=(AntiqueWhite4);
color(0.1cm)=(LightGoldenrod2);
color(0.15cm)=(Bisque1);
color(0.25cm)=(LemonChiffon3);
color(0.3cm)=(NavajoWhite3);
color(0.6cm)=(LemonChiffon3);
color(0.7cm)=(Wheat2);
color(0.85cm)=(Wheat1);
color(0.95cm)=(Bisque3);
color(1.25cm)=(Cornsilk2);
color(1.5cm)=(Bisque3);
color(1.7cm)=(AntiqueWhite3);
color(1.9cm)=(AntiqueWhite4)
}

\tikzset{satellite orbit/.style args={at pos #1 with #2}{
   postaction=decorate,
   decoration={
    markings,
    mark=
    at position #1
      with
      {
       #2
      }
    }
  },
}

\begin{document}
\begin{frame}
\begin{center}
\begin{tikzpicture}[rotate=21]

\path[shading=Saturn,shading angle=21] (0,0) circle [radius=2];

\path[inner color=LemonChiffon3,outer color=Bisque3,even odd rule]
    (0,-.2) circle [x radius=4, y radius=1.25]
    (0,-.15) circle [x radius=3.8, y radius=1.2]; 

\path[inner color=Bisque2,outer color=NavajoWhite3,even odd rule]
    (0,-.15) circle [x radius=3.8, y radius=1.2]
    (0,-.15) circle [x radius=3.6, y radius=1.1]
    ;  

\path[left color=AntiqueWhite3,right color=Wheat3!98!black,even odd rule,
shading angle=31]
    (0,0) circle [x radius=3, y radius=.75]
    (0,-.15) circle [x radius=3.6, y radius=1.1];

\path[inner color=NavajoWhite2,outer color=Bisque3,even odd rule]    
    (0,0) circle [x radius=3, y radius=.75]
    (0,0) circle [x radius=2.8, y radius=.725]; 

\foreach \x[count=\xi] in {0.35,0.4,...,1,0,0.05,...,0.25}{
\tikzset{visibility/.style={
    shading=Saturn,
    visible on=<\xi>,
  }
}
\ifnum\xi<3
\tikzset{visibility/.append style={
    background default shade={shading=Saturn},
    background shade={right color=gray,left color=gray!80},
    shade on=<\xi>,
  }
}
\fi
\ifnum\xi>16
\tikzset{visibility/.append style={
    background default shade={shading=Saturn},
    background shade={left color=gray,right color=gray!80},
    shade on=<\xi>,
  }
}
\fi
\path[satellite orbit=%
  at pos {\x} with {%
  \node[circle,visibility]{};%
  }](0,-.2) circle [x radius=5, y radius=1.45];
}

\begin{scope}
    \clip[overlay] (-2.1,0) rectangle (2.1,2.1);
    \path[shading=Saturn,shading angle=21] (0,0) circle [radius=2];
\end{scope} 

\end{tikzpicture}
\end{center}
\end{frame}
\end{document}

The result:

enter image description here

share|improve this answer
    
Really cool drawing! –  Svend Tveskæg Jan 29 at 16:17
    
Amazing code, Claudio! In other news, Houston, we have a problem... :) –  Paulo Cereda Jan 29 at 17:03
    
@PauloCereda: the birth of alien ducks :) What else will you invent? ;) –  Claudio Fiandrino Jan 29 at 17:50
    
@Claudio: my original plan was to replace the moon with the duck, but apparently I injected the duck code in the wrong place. :) –  Paulo Cereda Jan 29 at 18:06
    
@PauloCereda: oh, I may have some clues for that; let me have a look tomorrow. –  Claudio Fiandrino Jan 29 at 19:02

Not sure I like the colour scheme, so here's a more restrained Metapost version, featuring the useful buildcycle macro.

% prologues :=3; outputtemplate := saturn.eps; % uncomment if you want these
beginfig(1);
path globe, gap, ring[], limb[];
globe = fullcircle scaled 2cm;
gap   = fullcircle xscaled 3cm yscaled .8cm;
ring1  = fullcircle xscaled 4cm yscaled 1.2cm;
ring2  = ring1 scaled 0.93;
ring3  = ring1 scaled 0.89;
limb1 = buildcycle(subpath (5,7) of ring1, subpath (8,4) of globe);
limb2 = buildcycle(subpath (5,7) of gap, subpath (-2,6) of globe);
picture saturn; saturn = image(
fill ring1 withcolor .1red+.1green+.4white;
fill ring2 withcolor .2white;
fill ring3 withcolor .1red+.1green+.6white;
unfill gap; 
fill limb1 withcolor .2red+.1green+.7white;
fill limb2 withcolor .2red+.1green+.7white;
);
draw saturn rotated 30;
endfig;
end.  % don't include this if you are making this part of another file

enter image description here

share|improve this answer
    
Really cool drawing! –  Svend Tveskæg Jan 29 at 16:42
    
Impressively economical code. –  Faheem Mitha Jan 29 at 22:58
    
This example (according to @egreg), is missing a final end.. At any rate, it does not work without that addition, and does work with it. –  Faheem Mitha Jan 29 at 23:25
    
@FaheemMitha that's right. You might also need some context at the beginning. I'll update it. –  Thruston Jan 30 at 0:07

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.