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.

Consider the following very nice TikZ drawing of the Sun--Earth--Moon system from Jubobs (see here):

Code

\documentclass{article}

\usepackage{lmodern}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[scale=2.5]
  \def\rS{0.3}                             % The Sun's radius.
  \def\Earthangle{30}                      % Angle with respect to horizontal.
  \def\rE{0.1}                             % The Earth's radius.
                                           % Major radius of the Earth's elliptical orbit = 1.
  \def\eE{0.25}                            % Excentricity of the Earth's elliptical orbit.
  \pgfmathsetmacro\bE{sqrt(1 - \eE^2)}     % Minor radius of the Earth's elliptical orbit.
  \def\Moonangle{-45}                      % Angle with respect to horizontal.
  \pgfmathsetmacro\rM{0.7*\rE}             % The Moon's radius.
  \pgfmathsetmacro\aM{2.5*\rE}             % Major radius of the Moon's elliptical orbit.
  \def\eM{0.4}                             % Excentricity of the Earth's elliptical orbit.
  \pgfmathsetmacro\bM{\aM*sqrt(1 - \eM^2)} % Minor radius of the Moon's elliptical orbit.
  \def\offsetM{30}                         % Angle offset between the major axes of the Earth's and the Moon's orbits.

  % This function computes the direction in which light hits the Earth.
  \pgfmathdeclarefunction{f}{1}{%
    \pgfmathparse{%
      (-\eE + cos(#1) <  0) * (180 + atan(\bE*sin(#1)/(-\eE + cos(#1))))
      +
      (-\eE + cos(#1) >= 0) * atan(\bE*sin(#1)/(-\eE + cos(#1)))
    }
  }

  % This function computes the distance between the Earth and the Sun,
  % which is used to calculate the varying radiation intensity on the Earth.
  \pgfmathdeclarefunction{d}{1}{%
    \pgfmathparse{sqrt((-\eE + cos(#1))^2 + (\bE*sin(#1))^2)}
  }

  % Draw the elliptical path of the Earth.
  \draw[thin,color=gray] (0, 0) ellipse (1 and \bE);

  % Draw the Sun at the right-hand-side focus.
  \shade[%
    top color=yellow!70,%
    bottom color=red!70,%
    shading angle={45},%
  ]({sqrt(1-\bE^2)}, 0) circle (\rS);

  % Draw the Earth at \Earthangle.
  \pgfmathsetmacro{\radiation}{100*(1 - \eE)/d(\Earthangle)^2}
  \colorlet{Earthlight}{yellow!\radiation!blue}
  \shade[%
    top color=Earthlight,%
    bottom color=blue,%
    shading angle={90 + f(\Earthangle)},%
  ]({cos(\Earthangle)}, {\bE*sin(\Earthangle)}) circle (\rE);
  %\draw ({cos(\Earthangle)}, {\bE*sin(\Earthangle) - \rE}) node[below] {Earth};

  % Draw the Moon's (circular) orbit and the Moon at \Moonangle.
  \draw[thin, color=gray, rotate around={{\offsetM}:({cos(\Earthangle)}, {\bE*sin(\Earthangle)})}]
    ({cos(\Earthangle)}, {\bE*sin(\Earthangle)}) ellipse ({\aM} and {\bM});
  \shade[%
    top color=black!70,%
    bottom color=black!30,%
    shading angle={45},%
  ]({cos(\Earthangle) + \aM*cos(\Moonangle)*cos(\offsetM) - \bM*sin(\Moonangle)*sin(\offsetM)},%
    {\bE*sin(\Earthangle) + \aM*cos(\Moonangle)*sin(\offsetM) + \bM*sin(\Moonangle)*cos(\offsetM)}) circle (\rM);
\end{tikzpicture}

\end{document}

Output

output

Question

I would very much like to have the shadow of the Moon (i.e., the darkest part of the Moon drawing) at the side opposite to the Sun no matter where the Earth and Moon is drawn relative to the Sun. Can anyone help me do that? (I don't know TikZ so it is a "please do it for me" question; sorry!)

Update

Here is Tom Bombadil's answer as an animation using the animate package.

\documentclass{article}

\usepackage[
  hmargin=2.4cm,
  vmargin=3cm
]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{lmodern}
\usepackage{animate}


\def\rS{0.3}                             % The Sun's radius.
\def\Earthangle{30}                      % Angle with respect to horizontal.
\def\rE{0.1}                             % The Earth's radius.
                                         % Major radius of the Earth's elliptical orbit = 1.
\def\eE{0.25}                            % Excentricity of the Earth's elliptical orbit.
\pgfmathsetmacro\bE{sqrt(1 - \eE^2)}     % Minor radius of the Earth's elliptical orbit.
\def\Moonangle{-45}                      % Angle with respect to horizontal.
\pgfmathsetmacro\rM{0.5*\rE}             % The Moon's radius.
\pgfmathsetmacro\aM{2.5*\rE}             % Major radius of the Moon's elliptical orbit.
\def\eM{0.4}                             % Excentricity of the Earth's elliptical orbit.
\pgfmathsetmacro\bM{\aM*sqrt(1 - \eM^2)} % Minor radius of the Moon's elliptical orbit.
\def\offsetM{30}                         % Angle offset between the major axes of the Earth's and the Moon's orbits.

% This function computes the direction in which light hits the Earth.
\pgfmathdeclarefunction{f}{1}{%
  \pgfmathparse{%
    (-\eE + cos(#1) <  0) * (180 + atan(\bE*sin(#1)/(-\eE + cos(#1))))
    +
    (-\eE + cos(#1) >= 0) * atan(\bE*sin(#1)/(-\eE + cos(#1)))
  }
}

% This function computes the distance between the Earth and the Sun,
% which is used to calculate the varying radiation intensity on the Earth.
\pgfmathdeclarefunction{d}{1}{%
  \pgfmathparse{sqrt((-\eE + cos(#1))^2 + (\bE*sin(#1))^2)}
}

\def\animation#1{%
\begin{tikzpicture}[scale=5]
   % Changing parameters for animation.
   \pgfmathsetmacro{\Earthangle}{\iA} 
   \pgfmathsetmacro{\Moonangle}{12*\iA} 

  % Draw the elliptical path of the Earth.
  \draw[thin, color=gray] (0, 0) ellipse (1 and \bE);

  % Draw the Sun at the right-hand-side focus.
  \shade[%
    inner color=yellow!70,%
    outer color=orange!70,%
  ]({sqrt(1 - \bE^2)}, 0) circle (\rS);

  % Draw the Earth at \Earthangle.
  \pgfmathsetmacro{\radiation}{100*(1 - \eE)/d(\Earthangle)^2}
  \colorlet{Earthlight}{yellow!\radiation!blue}
  \shade[%
    top color=Earthlight,%
    bottom color=blue!75!black,%
    shading angle={90 + f(\Earthangle)},%
  ]({cos(\Earthangle)}, {\bE*sin(\Earthangle)}) circle (\rE);
  %\draw ({cos(\Earthangle)}, {\bE*sin(\Earthangle) - \rE}) node[below] {Earth};

  % Draw the Moon's (circular) orbit and the Moon at \Moonangle.
  \draw[%
    thin,%
    color=gray,%
    rotate around={{\offsetM}:({cos(\Earthangle)}, {\bE*sin(\Earthangle)})}%
  ]({cos(\Earthangle)}, {\bE*sin(\Earthangle)}) ellipse ({\aM} and {\bM});

  % Makes a path (Moon)-(Sun), e.g., the vector pointing from the Sun to the Moon.
  \path ($({cos(\Earthangle) + \aM*cos(\Moonangle)*cos(\offsetM)
            - \bM*sin(\Moonangle)*sin(\offsetM)},%
           {\bE*sin(\Earthangle) + \aM*cos(\Moonangle)*sin(\offsetM)
            + \bM*sin(\Moonangle)*cos(\offsetM)}) - ({sqrt(1 - \bE^2)}, 0)$);
  % Get the components of that vector.
  \pgfgetlastxy{\myx}{\myy}
  % Computing the inclination angle.
  \pgfmathsetmacro{\moonshadinangleangle}{-90 + atan2(\myx, \myy)}

  \shade[%
    top color=black!90,%
    bottom color=black!10,%
    shading angle=\moonshadinangleangle,%
  ]({cos(\Earthangle) + \aM*cos(\Moonangle)*cos(\offsetM)
     - \bM*sin(\Moonangle)*sin(\offsetM)},%
    {\bE*sin(\Earthangle) + \aM*cos(\Moonangle)*sin(\offsetM)
     + \bM*sin(\Moonangle)*cos(\offsetM)}) circle (\rM);
\end{tikzpicture}
}

\pagestyle{empty}

\begin{document}

\begin{figure}[htbp]
\centering
 \begin{animateinline}[poster=first,controls,loop]{10}
  \multiframe{360}{iA=1+1}{\animation{\iA}}
 \end{animateinline}
\end{figure}

\end{document}
share|improve this question
    
Try for the moon shading angle={-90+f(\Earthangle)}, instead of shading angle={45}. Is that what you want? It is not 100% precise but its a diagram and not a celestial simulation after all. –  Alexander Jun 4 '13 at 16:15
    
@Alexander Thank you very much! I'm now exactly sure why this isn't 100 % precise---it looks great to me but if someone can come up with a more accurate shading, please let me know. :-) –  Svend Tveskæg Jun 4 '13 at 16:20
    
shading angle={-90+f(\Earthangle)} is good, but not 100% precise, because the moon is positioned at a slightly different angle than the the earth. –  Hans-Peter E. Kristiansen Jun 4 '13 at 17:39
    
@Hans-PeterE.Kristiansen Good point. Do you know how to draw the correct shading of the Moon? –  Svend Tveskæg Jun 4 '13 at 17:50
2  
The correct angle would probably be \path ($(moon)-(sun)$); \pgflastxy{\myx}{\myy} \pgfmathsetmacro{\correctangle}{atan2(\myx,\myy)} –  Tom Bombadil Jun 4 '13 at 20:24

1 Answer 1

up vote 3 down vote accepted

Basically answering this sent me back to my school days, doing a little vector algebra ;)

Code (animation ready)

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{calc}
\usepackage{lmodern}

\begin{document}

\def\rS{0.3}                             % The Sun's radius.
  \def\Earthangle{30}                      % Angle with respect to horizontal.
  \def\rE{0.1}                             % The Earth's radius.
                                           % Major radius of the Earth's elliptical orbit = 1.
  \def\eE{0.25}                            % Excentricity of the Earth's elliptical orbit.
  \pgfmathsetmacro\bE{sqrt(1 - \eE^2)}     % Minor radius of the Earth's elliptical orbit.
  \def\Moonangle{-45}                      % Angle with respect to horizontal.
  \pgfmathsetmacro\rM{0.7*\rE}             % The Moon's radius.
  \pgfmathsetmacro\aM{2.5*\rE}             % Major radius of the Moon's elliptical orbit.
  \def\eM{0.4}                             % Excentricity of the Earth's elliptical orbit.
  \pgfmathsetmacro\bM{\aM*sqrt(1 - \eM^2)} % Minor radius of the Moon's elliptical orbit.
  \def\offsetM{30}                         % Angle offset between the major axes of the Earth's and the Moon's orbits.

  % This function computes the direction in which light hits the Earth.
  \pgfmathdeclarefunction{f}{1}{%
    \pgfmathparse{%
      (-\eE + cos(#1) <  0) * (180 + atan(\bE*sin(#1)/(-\eE + cos(#1))))
      +
      (-\eE + cos(#1) >= 0) * atan(\bE*sin(#1)/(-\eE + cos(#1)))
    }
  }

  % This function computes the distance between the Earth and the Sun,
  % which is used to calculate the varying radiation intensity on the Earth.
  \pgfmathdeclarefunction{d}{1}{%
    \pgfmathparse{sqrt((-\eE + cos(#1))^2 + (\bE*sin(#1))^2)}
  }


%\foreach \x in {1,...,360}
%{
\begin{tikzpicture}[scale=2.5]
%   % changing parameters for animation
%   \pgfmathsetmacro{\Earthangle}{\x} 
%   \pgfmathsetmacro{\Moonangle}{12*\x} 

  % Draw the elliptical path of the Earth.
  \draw[thin,color=gray] (0, 0) ellipse (1 and \bE);

  % Draw the Sun at the right-hand-side focus.
  \shade[%
    inner color=yellow!70,%
    outer color=orange!70,%
    %shading angle={45},%
  ]({sqrt(1-\bE^2)}, 0) circle (\rS);

  % Draw the Earth at \Earthangle.
  \pgfmathsetmacro{\radiation}{100*(1 - \eE)/d(\Earthangle)^2}
  \colorlet{Earthlight}{yellow!\radiation!blue}
  \shade[%
    top color=Earthlight,%
    bottom color=blue!75!black,%
    shading angle={90 + f(\Earthangle)},%
  ]({cos(\Earthangle)}, {\bE*sin(\Earthangle)}) circle (\rE);
  %\draw ({cos(\Earthangle)}, {\bE*sin(\Earthangle) - \rE}) node[below] {Earth};

  % Draw the Moon's (circular) orbit and the Moon at \Moonangle.
  \draw[thin, color=gray, rotate around={{\offsetM}:({cos(\Earthangle)}, {\bE*sin(\Earthangle)})}]
    ({cos(\Earthangle)}, {\bE*sin(\Earthangle)}) ellipse ({\aM} and {\bM});

    % make a path (moon)-(sun), e.g. the vector pointing from sun to moon
      \path ($({cos(\Earthangle) + \aM*cos(\Moonangle)*cos(\offsetM) - \bM*sin(\Moonangle)*sin(\offsetM)},{\bE*sin(\Earthangle) + \aM*cos(\Moonangle)*sin(\offsetM) + \bM*sin(\Moonangle)*cos(\offsetM)})-({sqrt(1-\bE^2)}, 0)$);
      % get the components of that vector
      \pgfgetlastxy{\myx}{\myy}
      % compute the inclination angle
      \pgfmathsetmacro{\moonshadinangleangle}{-90+atan2(\myx,\myy)}

  \shade[%
    top color=black!90,%
    bottom color=black!10,%
    shading angle=\moonshadinangleangle,%
  ]({cos(\Earthangle) + \aM*cos(\Moonangle)*cos(\offsetM) - \bM*sin(\Moonangle)*sin(\offsetM)},%
    {\bE*sin(\Earthangle) + \aM*cos(\Moonangle)*sin(\offsetM) + \bM*sin(\Moonangle)*cos(\offsetM)}) circle (\rM);

%   %dummy path to keep the size constant for animation 
%   \path (-1.5,-1.5) rectangle (1.5,1.5);
\end{tikzpicture}
%}

\end{document}

Output

enter image description here

Animation

Link (~750kB)

share|improve this answer
    
Very nice! Could you include how you did the animation? –  Alexander Jun 5 '13 at 11:35
    
The animation can be created with ImageMagick's convert tool, e.g. convert -loop 0 -delay 5 -dispose previous -size 100x100 source.pdf target.gif –  Tom Bombadil Jun 5 '13 at 11:55
    
This is seriously cool. :-) Another way of making the animation, is with the animate package. –  Svend Tveskæg Jun 5 '13 at 13:29

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.