动画中的帧大小错误

动画中的帧大小错误

考虑以下代码(或多或少):

\documentclass{article}

\usepackage{lmodern}
\usepackage[
  hmargin=2.4cm,
  vmargin=3cm
]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\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}

输出

当我运行动画时,地球绕太阳的轨道不是恒定的。我该如何解决这个问题?

更新

以下是我最终得到的结果:

\documentclass{article}

\usepackage{lmodern}
\usepackage[
  hmargin=2.4cm,
  vmargin=3cm
]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\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]
 \useasboundingbox (-1.28,-1.24) rectangle (1.30,1.28);
   % Changing parameters for animation.
   \pgfmathsetmacro{\Earthangle}{#1} 
   \pgfmathsetmacro{\Moonangle}{12*#1} 

  % 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}

答案1

问题是animate会将所有帧放在第一帧大小的框中。您需要在 TikZ 图片中建立一个包含所有帧的边界框。

这也已在animate手动的在第 8 页:

关于 tikzpicture 环境的简短说明:与 不同pspicturetikzpicture环境能够根据其包含的图形对象确定其大小。但是,这可能会导致序列的帧大小不同,具体取决于图形对象的大小和位置。因此,为了确保序列的所有帧在动画小部件中以相同的比例显示,帧应该共享一个公共边界框。可以通过不可见对象提供边界框rectangle

begin={
  \begin{tikzpicture}
  \useasboundingbox (... , ...) rectangle (... , ...);
},
end={\end{tikzpicture}}

现在,我们可以根据所有变量来计算边界框的最小尺寸:地球的路径、月球的路径和月球的半径应该构成最小的边界框,但实际上可以从中减去一些东西,因为月球的路径是旋转的,并且太阳、地球和月球在动画中的关键点不一定在一条直线上。

我刚刚添加

\useasboundingbox (-1.3, -1.25) rectangle (1.3, 1.25);

我觉得它看起来不错。选项中使用的路径use as bounding box可以是任何路径,您也可以绘制它(这样您就可以看到矩形的实际位置)。

相关内容