考虑以下动画:
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage{pst-eucl}
\usepackage{animate}
\usepackage{siunitx}
% LaTeX 3 syntax
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
\def\sundial#1{%
% constants
\def\length{16 }
\def\north{#1 }
% helping constants
\def\northB{\calc{90-\north}}
\def\lengthB{\calc{\length*sin(\northB*pi/180)}}
\def\lengthC{\calc{\length*sin(\north* pi/180)}}
\def\coorx{\calc{\lengthB*sin(\northB*pi/180)}}
\def\coory{\calc{\lengthC*cos(\north* pi/180)}}
\def\maxxA{\calc{\length+0.45}}
\def\maxxB{\calc{1/4*\length*(sin(2*\north*pi/180)+cos(2*\north*pi/180)+3)}}
\def\maxx{\calc{max(\maxxA,\maxxB)}}
\def\maxyA{\calc{1/2*\lengthC*(sin(\north*pi/180)+cos(\north*pi/180))}}
\def\maxyB{\calc{\coory+0.6}}
\def\maxy{\calc{max(\maxyA,\maxyB)}}
% settings
\psset{unit=0.8}
\sisetup{round-mode=places,round-precision=1}
% picture
\fbox{%
\begin{pspicture}(-0.6,-0.15)(\maxx,\maxy)
\pnodes{P}(0,0)(\coorx,\coory)(\length,0)
\pspolygon(P0)(P1)(P2)
\pstMarkAngle{P2}{P0}{P1}{\SI{\north}{\degree}}
\pstRightAngle{P0}{P1}{P2}
\pstMarkAngle{P1}{P2}{P0}{\SI{\northB}{\degree}}
\uput[180](P0){$A$}
\uput[90](P1){$C$}
\uput[0](P2){$B$}
\pstMediatorAB[
PointSymbol=none,
PointNameA=none,
PointNameB=none,
CodeFig=true,
CodeFigColor=black
]{P1}{P2}{M}{MN}
\psset{offset=-9pt,linestyle=none,nrot=:U}
\pcline(P0)(P1)
\ncput*{\SI{\lengthB}{\cm}}
\pcline(P1)(P2)
\ncput*{\SI{\lengthC}{\cm}}
\pcline[offset=9pt](P0)(P2)
\ncput*{\SI{\length}{\cm}}
\end{pspicture}%
}
}
\begin{document}
\begin{animateinline}[poster=first,controls,palindrome]{5}
\multiframe{51}{iA=20+1}{\sundial{\iA}}
\end{animateinline}
\end{document}
(注:\fbox
仅用于说明框架的大小pspicture
。)
当我运行动画(从 Adobe Reader 中)时,框架的宽度和高度没有改变;相反,图形被拉伸了。我该如何解决这个问题?
PS 当我没有动画并选择单个(不同)值时\north
,框架会按照我预期的方式进行调整。
更新
我最终使用了下面的方法,但是AlexG 的方法更好(因为计算是自动完成的):
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage{pst-eucl}
\usepackage{animate}
\usepackage{siunitx}
% LaTeX 3 syntax
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
% helping constants
\def\northB{\calc{90-\north}}
\def\lengthB{\calc{\length*sin(\northB*pi/180)}}
\def\lengthC{\calc{\length*sin(\north* pi/180)}}
\def\coorx{\calc{\lengthB*sin(\northB*pi/180)}}
\def\coory{\calc{\lengthC*cos(\north* pi/180)}}
\def\maxx{\calc{(3+2^(1/2))/4*\length-0.2}}% <-- global maximum for the width (minus adjustment)
\def\maxy{\calc{(1+2^(1/2))/4*\length}}% <-- global maximum for the height
% settings
\psset{unit=0.8}
\sisetup{round-mode=places,round-precision=1}
% sundial
\def\sundial#1{%
% constants
\def\length{16}
\def\north{#1}
% picture
\begin{pspicture}(-0.5,-0.15)(\maxx,\maxy)
\pnodes{P}(0,0)(\coorx,\coory)(\length,0)
\pspolygon(P0)(P1)(P2)
\pstMarkAngle{P2}{P0}{P1}{\small\SI{\north}{\degree}}
\pstRightAngle{P0}{P1}{P2}
\pstMarkAngle{P1}{P2}{P0}{\small\SI{\northB}{\degree}}
\uput[180](P0){$A$}
\uput[90](P1){$C$}
\uput[0](P2){$B$}
\pstMediatorAB[
PointSymbol=none,
PointNameA=none,
PointNameB=none,
CodeFig=true,
CodeFigColor=black
]{P1}{P2}{M}{MN}
\psset{offset=-9pt,linestyle=none,nrot=:U}
\pcline(P0)(P1)
\ncput*{\SI{\lengthB}{\cm}}
\pcline(P1)(P2)
\ncput*{\SI{\lengthC}{\cm}}
\pcline[offset=9pt](P0)(P2)
\ncput*{\SI{\length}{\cm}}
\end{pspicture}
}
\begin{document}
\begin{animateinline}[poster=first,controls,palindrome]{5}
\multiframe{61}{iA=15+1}{\sundial{\iA}}
\end{animateinline}
\end{document}
答案1
动画的所有帧必须具有相同的大小。第一帧决定了动画小部件的尺寸。后续帧将变形缩放至此尺寸。因此,如果 pspicture 尺寸是动态的,则除第一帧之外的所有帧都可能被拉伸或收缩。
\documentclass{article}
\usepackage[margin=2cm]{geometry}
\usepackage{pst-eucl}
\usepackage{animate}
\usepackage{siunitx}
% LaTeX 3 syntax
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
% constants
\def\length{16 }
% helper macros
\def\northB{\calc{90-\north}}
\def\lengthB{\calc{\length*sin(\northB*pi/180)}}
\def\lengthC{\calc{\length*sin(\north* pi/180)}}
\def\coorx{\calc{\lengthB*sin(\northB*pi/180)}}
\def\coory{\calc{\lengthC*cos(\north* pi/180)}}
%parameterized pspicture
\def\sundial#1{%
\def\north{#1 }
% settings
\psset{unit=0.8}
\sisetup{round-mode=places,round-precision=1}
% picture
\fbox{\begin{pspicture}(-0.6,-0.15)(\maxx,\maxy)
\pnodes{P}(0,0)(\coorx,\coory)(\length,0)
\pspolygon(P0)(P1)(P2)
\pstMarkAngle{P2}{P0}{P1}{\SI{\north}{\degree}}
\pstRightAngle{P0}{P1}{P2}
\pstMarkAngle{P1}{P2}{P0}{\SI{\northB}{\degree}}
\uput[180](P0){$A$}
\uput[90](P1){$C$}
\uput[0](P2){$B$}
\pstMediatorAB[
PointSymbol=none,
PointNameA=none,
PointNameB=none,
CodeFig=true,
CodeFigColor=black
]{P1}{P2}{M}{MN}
\psset{offset=-9pt,linestyle=none,nrot=:U}
\pcline(P0)(P1)
\ncput*{\SI{\lengthB}{\cm}}
\pcline(P1)(P2)
\ncput*{\SI{\lengthC}{\cm}}
\pcline[offset=9pt](P0)(P2)
\ncput*{\SI{\length}{\cm}}
\end{pspicture}}%
}
%find max pspicture dims
\def\maxx{0}\def\maxy{0}
\multido{\iA=20+1}{51}{
\def\north{\iA }
\def\maxxA{\calc{\length+0.45}}
\def\maxxB{\calc{1/4*\length*(sin(2*\north*pi/180)+cos(2*\north*pi/180)+3)}}
\xdef\maxx{\calc{max(\maxx,\maxxA,\maxxB)}}
\def\maxyA{\calc{1/2*\lengthC*(sin(\north*pi/180)+cos(\north*pi/180))}}
\def\maxyB{\calc{\coory+0.6}}
\xdef\maxy{\calc{max(\maxy,\maxyA,\maxyB)}}
}
\begin{document}
\begin{animateinline}[poster=first,controls,palindrome]{5}
\multiframe{51}{iA=20+1}{\sundial{\iA}}
\end{animateinline}
\end{document}