考虑以下代码(或多或少这):
\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 环境的简短说明:与 不同
pspicture
,tikzpicture
环境能够根据其包含的图形对象确定其大小。但是,这可能会导致序列的帧大小不同,具体取决于图形对象的大小和位置。因此,为了确保序列的所有帧在动画小部件中以相同的比例显示,帧应该共享一个公共边界框。可以通过不可见对象提供边界框rectangle
:begin={ \begin{tikzpicture} \useasboundingbox (... , ...) rectangle (... , ...); }, end={\end{tikzpicture}}
现在,我们可以根据所有变量来计算边界框的最小尺寸:地球的路径、月球的路径和月球的半径应该构成最小的边界框,但实际上可以从中减去一些东西,因为月球的路径是旋转的,并且太阳、地球和月球在动画中的关键点不一定在一条直线上。
我刚刚添加
\useasboundingbox (-1.3, -1.25) rectangle (1.3, 1.25);
我觉得它看起来不错。选项中使用的路径use as bounding box
可以是任何路径,您也可以绘制它(这样您就可以看到矩形的实际位置)。