在多次调用的过程中更新变量
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
我正在尝试通过重复调用块绘图过程来生成后记 "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