在多次调用的过程中更新变量

Updating a variable in a procedure called multiple tmies

我正在尝试通过重复调用块绘图过程来生成后记 "bitmap"。

我不想在每次调用时定义块的位置,而是希望程序根据已知的(比如说)100 像素的块大小自动更新起始位置,如下所示:

% starting position
/px { 72 } def
/py { 720 } def

% block-drawing procedure, input= r-g-b
/block {
    setrgbcolor
    px py moveto
    0 100 rlineto
    100 0 rlineto
    0 100 neg rlineto
    fill
    % NOW ADJUST PX AND PY BY 100 AND -100, AHEAD OF NEXT CALL 
} def

% draw three increasingly lighter boxes, automatically shifted 
0 0 0 box 
.25 .25 .25 box
.5 .5 .5 box
% etc...

有没有简单的方法可以做到这一点?

是的,改变 px 和 py 的值。

请注意,您的代码将 px 和 py 定义为可执行数组,它们在执行时会在操作数堆栈上留下一个值。没必要那么做,这个:

/px 72 def
/py 720 def

同样有效。

我认为您忽略了一个事实,即“def”在当前字典中关联了一个键和一个值。由于您还没有启动新词典,因此您使用默认词典,即 userdict。如果您再次使用“def”,它会将新值与字典中的相同键相关联。

所以如果你这样做:

% starting position
/px 72 def
/py 720 def

% block-drawing procedure, input= r-g-b
/block {
    setrgbcolor
    px py moveto
    0 100 rlineto
    100 0 rlineto
    0 100 neg rlineto
    fill
    % NOW ADJUST PX AND PY BY 100 AND -100, AHEAD OF NEXT CALL 
    px 100 add /px exch def
    py 100 sub /py exch def
} def

% draw three increasingly lighter boxes, automatically shifted 
0 0 0 box 
.25 .25 .25 box
.5 .5 .5 box
% etc...

这将如您所愿。

Ken 已经回答了你关于定义和使用定义的问题,但我想展示一种不同的方法,这对于 postscript 来说可能更自然。

如果您想要自动定位自己的绘图程序,您可以将每个程序视为字体中的一个字形。我的意思是您使用图形状态中的 currentpoint 作为您的 变量 。它将两个坐标很好地结合在一起。每个绘图过程然后执行rmoveto 为下一个过程定位点。

下面是我将如何编写您的块绘图过程:

72 720  % starting position

% r g b  block  -    [expects currentpoint and adjusts currentpoint]
% draws a block
/block {
    setrgbcolor
    0 100 rlineto
    100 0 rlineto
    0 100 neg rlineto
    closepath
    currentpoint fill moveto
    % NOW ADJUST PX AND PY BY 100 AND -100, AHEAD OF NEXT CALL 
    100 -100 rmoveto
} def

% draw three increasingly lighter boxes, automatically shifted 
moveto  % starting position from above
0 0 0 block
.25 .25 .25 block
.5 .5 .5 block

由于fill破坏了路径,我们必须将它与currentpoint夹在中间......moveto以保留点。

此外,看看我们如何梳理边长的新参数而不进行新定义。这个想法是我们可以在堆栈上安排数据,然后调用它上面的所有操作符。所以如果参数是 100,我们只需要让堆栈看起来像 0 -100 100 0 0 100 然后调用 rlineto rlineto rlineto 甚至 3{rlineto}repeat。请记住,所有数据都进入堆栈,然后可用 自上而下

因此反向构建数据,然后直接执行运算符。

0 -100
     100 0
          0 100
          rlineto
     rlineto
rlineto

建立数据只是简单的堆栈操作和算术。

72 720  % starting position

% N r g b  block  -    [expects currentpoint and adjusts currentpoint]
% draws a block colored (r,g,b) of side-length N
/block {
    setrgbcolor  % N
    0 exch dup neg exch 0 0 2 index % 0 -N  N 0  0 N
    3 {rlineto} repeat
    closepath
    currentpoint fill moveto
    % NOW ADJUST PX AND PY BY 100 AND -100, AHEAD OF NEXT CALL 
    100 -100 rmoveto
} def

% draw three increasingly lighter boxes, automatically shifted 
moveto  % starting position from above
0 0 0 block
.25 .25 .25 block
.5 .5 .5 block