\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\pstVerb
{
/updateCP {2 copy CPy add /CPy ED CPx add /CPx ED} bind def
/updateA {1 sub sqrt 1 exch atan Angles add /Angles ED} bind def
}
\def\Atom{%
\pstVerb{/Angles 0 def /CPx 1 def /CPy 0 def}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{3}{\xdef\points{\points(!1 \ii\space updateA Angles PtoC updateCP)}}%
\expandafter\psrline\points}
\begin{document}
% one instance
\begin{pspicture}[showgrid](-3,-3)(3,3)
\Atom
\end{pspicture}
% two instances
\begin{pspicture}[showgrid](-3,-3)(3,3)
\Atom
\Atom
\end{pspicture}
\end{document}
一个实例
两个例子
问题
为什么单个实例\Atom
产生正确结果,而两个相同的实例却\Atom
产生错误结果?
真实场景
我想模仿
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
\psset{linecolor=blue}
\pstVerb{/Angles 0 def}
\psStartPoint(0,0)
\psVector[arrows=-](1,0)
\multido{\i=1+1}{15}
{% why is % needed here?
\pstVerb{Angles 1 \i\space 1 sub sqrt atan add /Angles exch def}
\psVector[arrows=-](!1 Angles PtoC)
\psline(!cp.X cp.Y)
}
\end{pspicture}
\end{document}
但会产生错误的输出。
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\psset{linecolor=red}
\pstVerb
{
/updateCP {2 copy CPy add /CPy ED CPx add /CPx ED} bind def %
/updateA {1 sub sqrt 1 exch atan Angles add /Angles ED} bind def %
}
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\io=1+1}{15}{%
\pstVerb{/Angles 0 def /CPx 1 def /CPy 0 def}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{\io}{\xdef\points{\points(!1 \ii\space updateA Angles PtoC updateCP)}}%
\expandafter\psrline\points
\psline(!CPx CPy)%
}
\end{pspicture}
\end{document}
答案1
问题在于您使用不同的 Postscript 词典。
“重置”部分是在一本字典中完成的(我不确定在哪一本),而节点内容的评估是在tx@Dict
字典内部完成的。
通常,当您调用 Postscript 运算符或变量时,解释器首先在当前字典中查找,然后在父字典中查找,并向上遍历字典堆栈,直到找到所请求名称的第一个定义。对于 的第一次调用\Atom
, 中没有Angles
定义tx@Dict
,因此使用父字典的值(其中Angles
定义为0
)。当\Atom
第二次调用 时, 中有一个Angles
定义tx@Dict
,即第一次\Atom
调用的最后一个值。
要解决这个问题,您必须执行字典中的“重置”部分tx@Dict
:
\pstVerb{tx@Dict begin /Angles 0 def /CPx 1 def /CPy 0 def end }% reset
因此脚本
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\psset{linecolor=red}
\pstVerb
{
/updateCP {2 copy CPy add /CPy ED CPx add /CPx ED} bind def %
/updateA {1 sub sqrt 1 exch atan Angles add /Angles ED} bind def %
}
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\io=1+1}{15}{%
\pstVerb{tx@Dict begin /Angles 0 def /CPx 1 def /CPy 0 def end}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{\io}{\xdef\points{\points(!1 \ii\space updateA Angles PtoC updateCP)}}%
\expandafter\psrline\points
\psline(!CPx CPy)%
}
\end{pspicture}
\end{document}
工作正常并给出:
答案2
赫伯特的建议
\pst@Verb
而不是\pstVerb
自动确定范围。因此不需要定义用户词典。
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\psset{linecolor=red}
\pstVerb
{
/updateCP {2 copy CPy add /CPy ED CPx add /CPx ED} bind def %
/updateA {1 sub sqrt 1 exch atan Angles add /Angles ED} bind def %
}
\begin{document}
\makeatletter
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\io=1+1}{15}{%
\pst@Verb{/Angles 0 def /CPx 1 def /CPy 0 def}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{\io}{\xdef\points{\points(!1 \ii\space updateA Angles PtoC updateCP)}}%
\expandafter\psrline\points
\psline(!CPx CPy)%
}
\end{pspicture}
\makeatother
\end{document}
更多的击键已被保存!