如何使用 PostScript RPN 关键字之一 dup?

如何使用 PostScript RPN 关键字之一 dup?

根据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 种变体是更好的选择。:)

相关内容