根据pstricks-add 手册位于最后一页附近,dup
用于复制前一个堆栈的值。复制可以简化 RPN 表达式。
为简单起见,我们考虑以下示例。首先绘制一条长度为 3 个单位、坡度为 30 度的线。该线的终点(不在原点)将用一个点标记。我为该点写了 4 种可能的 RPN 符号,如下所示:
\documentclass{article}
\usepackage{pstricks-add}
\usepackage{enumerate}
\def\theta{30}
\def\radius{3}
\parskip=40pt
\parindent=0pt
\begin{document}
\begin{enumerate}[a.]
\item\verb|\theta\space dup cos \radius\space mul sin \radius\space mul|\\[20pt]
\begin{pspicture}[showgrid](3,2)
\psline(\radius;\theta)
\psdot[linecolor=red](!\theta\space dup cos \radius\space mul sin \radius\space mul)
\end{pspicture}\\[20pt]
\item\verb|\radius\space dup \theta\space cos mul \theta\space sin mul|\\[20pt]
\begin{pspicture}[showgrid](3,2)
\psline(\radius;\theta)
\psdot[linecolor=green](!\radius\space dup \theta\space cos mul \theta\space sin mul)
\end{pspicture}\\[20pt]
\item\verb|\radius\space \theta\space cos mul \radius\space \theta\space sin mul|\\[20pt]
\begin{pspicture}[showgrid](3,2)
\psline(\radius;\theta)
\psdot[linecolor=blue](!\radius\space \theta\space cos mul \radius\space \theta\space sin mul)
\end{pspicture}\\[20pt]
\item\verb|\theta\space cos \radius\space mul \theta\space sin \radius\space mul|\\[20pt]
\begin{pspicture}[showgrid](3,2)
\psline(\radius;\theta)
\psdot(!\theta\space cos \radius\space mul \theta\space sin \radius\space mul)
\end{pspicture}\\[20pt]
\end{enumerate}
\end{document}
在前两个例子中,我画错了点。但后两个例子中,点画得正确。如何使用关键字dup
?
答案1
每个 PostScript 运算符都会从操作数堆栈顶部弹出所需的操作数,并将结果推回。对于第一个表达式,我们得到(右侧显示=>
从下到上的操作数堆栈):
THETA dup => THETA THETA
cos => THETA cos(THETA)
RADIUS mul => THETA cos(THETA)*RADIUS
sin => THETA sin(cos(THETA)*RADIUS)
RADIUS mul => THETA sin(cos(THETA)*RADIUS)*RADIUS
这显然不是您想要的结果,因为sin
运算符采用先前应用的运算的结果cos
。为了将值 THETA(位于堆栈底部)移动到顶部,请exch
在第一次乘法后插入。它交换两个最顶部的堆栈元素:
THETA dup => THETA THETA
cos => THETA cos(THETA)
RADIUS mul => THETA cos(THETA)*RADIUS
exch => cos(THETA)*RADIUS THETA
sin => cos(THETA)*RADIUS sin(THETA)
RADIUS mul => cos(THETA)*RADIUS sin(THETA)*RADIUS
因此,您的第一个变体应该如下所示才能获得所需的结果:
\psdot[linecolor=red](!\theta\space dup cos \radius\space mul exch sin \radius\space mul)
第二个表达式的计算方式如下:
RADIUS dup => RADIUS RADIUS
THETA cos => RADIUS RADIUS cos(THETA)
mul => RADIUS RADIUS*cos(THETA)
THETA sin => RADIUS RADIUS*cos(THETA) sin(THETA)
mul => RADIUS RADIUS*cos(THETA)*sin(THETA)
为了解决这个问题,需要在应用第二次乘法之前将 RADIUS 值从底部移到顶部。这可以通过roll
循环移动给定数量堆栈元素的运算符来实现。3 2 roll
循环将三个最顶部的元素“向上”移动两次:
RADIUS dup => RADIUS RADIUS
THETA cos => RADIUS RADIUS cos(THETA)
mul => RADIUS RADIUS*cos(THETA)
THETA sin => RADIUS RADIUS*cos(THETA) sin(THETA)
3 2 roll => RADIUS*cos(THETA) sin(THETA) RADIUS
mul => RADIUS*cos(THETA) sin(THETA)*RADIUS
这导致了以下 PSTricks 声明:
\psdot(!\radius\space dup \theta\space cos mul \theta\space sin 3 2 roll mul)
然而,这些表达式不必要地复杂,因此问题中给出的第 3 或第 4 种变体是更好的选择。:)