如何组合和简化以下 PostScript 运算符?

如何组合和简化以下 PostScript 运算符?

背景

\def\RR#1{(2^(#1/10))}
\def\TT#1{(#1)}

分别是半径和角度函数。

Christoph 定义 PS 运算AAA符如下

/AAA {AlgParser cvx exec exch AlgParser cvx exec exch RadtoDeg PtoC} def 

它可以用来翻译

\pscircle*[linecolor=red](!\RR{7*Pi/2} \TT{7*Pi/2} AAA){2pt}

从极中缀到极后缀。然而7*Pi/2,如果重复,它就违反了 DRY(不要重复自己)原则,并且无法使用,t如下所述。

我修改了Herbert 算子如下

/BBB {/TT ED TT AlgParser cvx /t ED  /RR ED RR AlgParser cvx /r ED r t RadtoDeg PtoC} def
/CCC { AlgParser cvx /t ED  AlgParser cvx exec t RadtoDeg PtoC} def

请允许我写如下两种风格。

\pscircle*[linecolor=green](!{(2^(t/10))} {(3*Pi/2)} BBB){2pt}
\pscircle*[linecolor=blue](!\RR{t} \TT{5*Pi/2} CCC){2pt}

第一个没有使用\RR\TT,最后一个使用了\RR\TT

完整代码

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}
\pstVerb
{
    /AAA {AlgParser cvx exec exch AlgParser cvx exec exch RadtoDeg PtoC} def 
    /BBB {/TT ED TT AlgParser cvx /t ED  /RR ED RR AlgParser cvx /r ED r t RadtoDeg PtoC} def
    /CCC { AlgParser cvx /t ED  AlgParser cvx exec t RadtoDeg PtoC} def
}


\def\RR#1{(2^(#1/10))}
\def\TT#1{(#1)}

\begin{document}
\begin{pspicture}[showgrid](-3,-3)(3,3)
  \psplot[algebraic,polarplot]{TwoPi}{TwoPi 2 mul}{\RR{x}}
    \pscircle*[linecolor=red](!\RR{7*Pi/2} \TT{7*Pi/2} AAA){2pt}
    \pscircle*[linecolor=green](!{(2^(t/10))} {(3*Pi/2)} BBB){2pt}
    \pscircle*[linecolor=blue](!\RR{t} \TT{5*Pi/2} CCC){2pt}
\end{pspicture}

\end{document}

问题

我可以将BBB和结合起来CCC创建DDD尽可能简单的AAA但它们仍然必须适用于以下内容吗?

\pscircle*[linecolor=green](!{(2^(t/10))} {(3*Pi/2)} DDD){2pt}
\pscircle*[linecolor=blue](!\RR{t} \TT{5*Pi/2} DDD){2pt}

附加问题:我还是不明白为什么 Herbert 只用了一个exec而 Christoph 用了两个exec?他exec到底做了什么?

答案1

简化

/AAA {AlgParser cvx exec exch AlgParser cvx exec exch RadtoDeg PtoC} def 
/BBB {exec AlgParser cvx /t ED  exec AlgParser cvx exec t RadtoDeg PtoC} def
/CCC {AlgParser cvx /t ED  AlgParser cvx exec t RadtoDeg PtoC} def

for /BBB:表达式{(2^(t/10))}被移至 PostScript括号是{...}我们首先需要一个用于删除它的原因是exec,或者,当然,/anyvar exch def anyvar或者/anyvar ED anyvar(保存它并将保存的数据推送到堆栈)将执行相同的操作。没有它就{...}无法工作TeX边。

对于您的示例,您只需要/BBB,它适用于所有人:

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}
\pstVerb{
  /A2P {exec AlgParser cvx /t ED  exec AlgParser cvx exec t RadtoDeg PtoC} def }

\def\RR#1{(2^(#1/10))}
\def\TT#1{(#1)}

\begin{document}
\begin{pspicture}[showgrid](-3,-3)(3,3)
  \psplot[algebraic,polarplot]{2 Pi mul neg}{4 Pi mul}{\RR{x}}
  \pscircle*[linecolor=red  ](!\RR{7*Pi/2} \TT{7*Pi/2} A2P){2pt}
  \pscircle*[linecolor=green](!{(2^(t/10))} {(3*Pi/2)} A2P){2pt}
  \pscircle*[linecolor=blue ](!\RR{t} \TT{5*Pi/2} A2P){2pt}
\end{pspicture}

\end{document}

答案2

仅关于以下问题的奖励答案exec

AlgParser解析字符串并在堆栈上(...)留下一个数组。表达式[...]

(2^(Pi/10)) AlgParser

计算数组

[tx@AddMathFunc begin 2.0 Pi 10.0 div exp end]

为了评估这一点,我们必须将其转化为可执行数组(或者程序) 与cvx,得到

{tx@AddMathFunc begin 2.0 Pi 10.0 div exp end}

现在您可以调用exec来执行堆栈上的这个过程(这是我做过两次的),也可以保存它并通过调用变量来执行它,即使用来/x exch def x执行它(这是 Herbert 做过一次的)。

因此以下语句是相等的

(2^(Pi/10)) AlgParser cvx exec

(2^(Pi/10)) AlgParser cvx /x exch def x

答案3

感谢 Christoph 在 上的回答exec,我设法DDD在两种情况下都进行了工作。这是 MWE(最小工作示例)。

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}
\pstVerb
{
    /AAA {AlgParser cvx exec exch AlgParser cvx exec exch RadtoDeg PtoC} def 
    /DDD {exec AlgParser cvx /t ED exec AlgParser cvx exec t RadtoDeg PtoC} def
}    

\def\RR#1{(2^(#1/10))}
\def\TT#1{(#1)}
\def\RT#1{\RR{#1} \TT{#1}}

\begin{document}
\begin{pspicture}[showgrid](-3,-3)(3,3)
  \psplot[algebraic,polarplot]{2 Pi mul neg}{4 Pi mul}{\RR{x}}
  \pscircle*[linecolor=red](!\RT{7*Pi/2} AAA){2pt}
  \pscircle*[linecolor=green](!{(2^(t/10))} {(3*Pi/2)} DDD){2pt}
  \pscircle*[linecolor=blue](!\RR{t} \TT{5*Pi/2} DDD){2pt}
\end{pspicture}
\end{document}

相关内容