背景
让
\def\RR#1{(2^(#1/10))}
\def\TT#1{(#1)}
分别是半径和角度函数。
/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}