9

I would like to draw this picture by tikz: An atom

This is what I could achieve for now:

\documentclass{standalone}
\usepackage{tikz}
\pagecolor{yellow}

\begin{document}

\color{orange!80!red}

\begin{tikzpicture}
    \clip (-0.5,-0.5) rectangle (.5,.5);
    
    \begin{scope}[xshift=4,yshift=12.4]
        \fill (0,0) circle (0.05);
    \end{scope}
    
    \begin{scope}[xshift=10.5,yshift=-8.5]
        \fill (0,0) circle (0.05);
    \end{scope}
    
    \begin{scope}[xshift=-11.5,yshift=-5.5]
        \fill (0,0) circle (0.05);
    \end{scope}
    
    \clip[xshift=4,yshift=12.4] (0,0) circle (0.06) [insert path ={(-2,-2) rectangle (2,2)}];
    \clip[xshift=10.5,yshift=-8.5] (0,0) circle (0.06) [insert path ={(-2,-2) rectangle (2,2)}];
    \clip[xshift=-11.5,yshift=-5.5] (0,0) circle (0.06) [insert path ={(-2,-2) rectangle (2,2)}];
    
    \begin{scope}[rotate=-70]
        \clip (-0.015,0.005) ellipse (0.17 and 0.46) [insert path ={(-0.5,-0.5) rectangle (.5,.5)}];
        \fill (0,0) ellipse (0.2 and 0.5);
    \end{scope}
    
    \begin{scope}[rotate=50]
        \clip (-0.015,0.005) ellipse (0.17 and 0.46) [insert path ={(-2,-2) rectangle (2,2)}];
        \fill (0,0) ellipse (0.2 and 0.5);
    \end{scope}
    
    \begin{scope}[rotate=-10]
        \clip (-0.015,0.005) ellipse (0.17 and 0.46) [insert path ={(-2,-2) rectangle (2,2)}];
        \fill (0,0) ellipse (0.2 and 0.5);
    \end{scope}
    
    \begin{scope}[xshift=-0.33,yshift=0.05]
        \fill (0,0) circle (0.08);
    \end{scope}

\end{tikzpicture}

\end{document}

I don't know how to draw the crossing of each ellipse. Note that the background color is not determined and may NOT be white, so one can't just draw a wider ellipse of background color behind each ellipse.

I believe this can be achieved by multiple use of \clip, just like the three circle I've drown here, but for the ellipses it seems more tricky and I have no idea with it.

Do you have any suggestions?

4
  • The [even odd rule] can create internal clips. Oct 30 '20 at 15:17
  • See also tex.stackexchange.com/questions/408245/… Oct 30 '20 at 15:24
  • Are the crossings in the original image really what you want? If it’s meant to depict a system of orbits in 3D (eg the Rutherford atom) then the crossings should be alternating so that the ellipses are “linked”, not just overlaid on each other as in the given image. Oct 31 '20 at 8:06
  • @PeterLeFanuLumsdaine Yes, that's true. It's just I want to use this icon in a really tiny size and it seems nicer with the crossings on it. To make the up- and down-structure more realistic seems to increase the drawing difficulty much much more.
    – Jinwen
    Oct 31 '20 at 8:15
13

I will leave the circles and the correct colors to you.

\documentclass[tikz, border=0.01cm]{standalone}
\begin{document}

\begin{tikzpicture}
\newcommand{\bgd}{(-0.5,-0.5) rectangle (0.5,0.5)}
\newcommand{\smallEll}{(-0.015,0.005) ellipse (0.17 and 0.46)}
\newcommand{\smallerEll}{(-0.015,0.005) ellipse (0.16 and 0.45)}
\newcommand{\largeEll}{(0,0) ellipse (0.2 and 0.5)};
\newcommand{\largerEll}{(0,0) ellipse (0.21 and 0.51)};

%test bgd
\shade[clip] \bgd;

%red
\fill[red, rotate=-10, even odd rule] \smallEll \largeEll;
    
%green
\begin{scope}
  \clip[rotate=-10] \smallerEll;
  \fill[green, rotate=50, even odd rule] \smallEll \largeEll;
\end{scope}
\begin{scope}
  \clip[rotate=-10] \bgd \largerEll;
  \fill[green, rotate=50, even odd rule] \smallEll \largeEll;
\end{scope}
    
%blue
\begin{scope}
  \clip[rotate=-10] \smallerEll;
  \clip[rotate=50] \smallerEll;
  \fill[blue, rotate=-70, even odd rule] \smallEll \largeEll; 
\end{scope}
\begin{scope}
  \clip[rotate=-10] \smallerEll;
  \clip[rotate=50] \bgd \largerEll;
  \fill[blue, rotate=-70, even odd rule] \smallEll \largeEll; 
\end{scope}
\begin{scope}
  \clip[rotate=-10] \bgd \largerEll;
  \clip[rotate=50] \smallerEll;
  \fill[blue, rotate=-70, even odd rule] \smallEll \largeEll; 
\end{scope}
\begin{scope}
  \clip[rotate=-10] \bgd \largerEll;
  \clip[rotate=50] \bgd \largerEll;
  \fill[blue, rotate=-70, even odd rule] \smallEll \largeEll; 
\end{scope}
   
\end{tikzpicture}
\end{document}

Red, green and blue ellipses with crossings


Edit: I just found, that I can make the clipping use even odd rule when in a scope and thereby fill the ellipses in one go. -making the code much simpler:

\documentclass[tikz, border=0.01cm]{standalone}
\begin{document}

\begin{tikzpicture}[even odd rule]
\newcommand{\bgd}{(-0.5,-0.5) rectangle (0.5,0.5)}
\newcommand{\smallEll}{(-0.015,0.005) ellipse (0.17 and 0.46)}
\newcommand{\smallerEll}{(-0.015,0.005) ellipse (0.16 and 0.45)}
\newcommand{\largeEll}{(0,0) ellipse (0.2 and 0.5)};
\newcommand{\largerEll}{(0,0) ellipse (0.21 and 0.51)};

%test bgd
\shade[clip] \bgd;

%red
\fill[red, rotate=-10] \smallEll \largeEll;
    
%green
\clip[rotate=-10] \smallerEll \largerEll \bgd;
\fill[green, rotate=50] \smallEll \largeEll;
   
%blue
\clip[rotate=50] \smallerEll \largerEll \bgd;
\fill[blue, rotate=-70] \smallEll \largeEll; 

\end{tikzpicture}
\end{document}
4
  • Could you add some explanation for how you achieved this?
    – Anush
    Oct 30 '20 at 19:24
  • 1
    The red ellipsis is drawn directly with even odd rule. The green ellipsis is draw first the part that is inside red(a bit smaller) and then what is outside(a bit larger) red. The blue is draw in four areas depending on whether it is inside/outside red/green. Oct 30 '20 at 19:29
  • @hpekristiansen, Thanks a lot! I wake up this morning seeing your longer version code and was happy then trying to understand it, and suddenly you edited it to a much much simpler version, such a surprise! It's very clear and it is exactly what I expected.
    – Jinwen
    Oct 31 '20 at 1:17
  • Very very nice.
    – Sebastiano
    Oct 31 '20 at 10:01
3

This is the finished code (thanks to @hpekristiansen):

\documentclass[tikz]{standalone}

\begin{document}

\color{orange}

\begin{tikzpicture}[even odd rule]
    \newcommand{\bgd}{(-0.5,-0.5) rectangle (0.5,0.5)}
    \newcommand{\smallEll}{(-0.015,0.005) ellipse (0.17 and 0.46)}
    \newcommand{\smallerEll}{(-0.015,0.005) ellipse (0.16 and 0.45)}
    \newcommand{\largeEll}{(0,0) ellipse (0.2 and 0.5)};
    \newcommand{\largerEll}{(0,0) ellipse (0.21 and 0.51)};
    
    %test bgd
    \clip \bgd;
    
    \begin{scope}[xshift=4,yshift=12.4]
        \fill (0,0) circle (0.05);
    \end{scope}
    
    \begin{scope}[xshift=10.5,yshift=-8.5]
        \fill (0,0) circle (0.05);
    \end{scope}
    
    \begin{scope}[xshift=-11.5,yshift=-5.5]
        \fill (0,0) circle (0.05);
    \end{scope}
    
    \clip[xshift=4,yshift=12.4] (0,0) circle (0.06) [insert path ={(-2,-2) rectangle (2,2)}];
    \clip[xshift=10.5,yshift=-8.5] (0,0) circle (0.06) [insert path ={(-2,-2) rectangle (2,2)}];
    \clip[xshift=-11.5,yshift=-5.5] (0,0) circle (0.06) [insert path ={(-2,-2) rectangle (2,2)}];
        
    \fill[rotate=-10] \smallEll \largeEll;
        
    \clip[rotate=-10] \smallerEll \largerEll \bgd;
    \fill[rotate=50] \smallEll \largeEll;
       
    \clip[rotate=50] \smallerEll \largerEll \bgd;
    \fill[rotate=-70] \smallEll \largeEll; 
    
    \fill (-0.02,0) circle (0.08);
\end{tikzpicture}

\end{document}

Here is the output: (thanks @projetmbc for this picture)

enter image description here

0

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.