Recursion 理解Postscript中的递归Koch雪花函数
我在后记中有一个很难理解的程序Recursion 理解Postscript中的递归Koch雪花函数,recursion,postscript,fractals,Recursion,Postscript,Fractals,我在后记中有一个很难理解的程序 /kochR { 2 copy ge {dup 0 rlineto} { 3 div 2 copy kochR 60 rotate 2 copy kochR -120 rotate 2 copy kochR 60 rotate 2 copy kochR } ifelse pop pop } def 0 0
/kochR
{
2 copy ge {dup 0 rlineto}
{
3 div
2 copy kochR
60 rotate
2 copy kochR
-120 rotate
2 copy kochR
60 rotate
2 copy kochR
} ifelse
pop pop
} def
0 0 moveto
27 81 kochR
0 27 moveto
9 81 kochR
0 54 moveto
3 81 kochR
0 81 moveto
1 81 kochR
stroke
我对上述计划的问题如下:
2 copy ge{dup 0 rlineto}
是什么意思ifelse
在这里是如何工作的?条件是什么3div
在这里做什么2 copy KochR
语句在这里执行什么操作您似乎在基本的PostScript概念和操作方面遇到了一些问题,您有PostScript语言参考手册吗
if
或ifelse
操作符的THEN子句,它表示“if(stack(top-1)>stack(top))绘制水平线((current_x,current_y)->(current_x+stack(top),current_y)。过程体{dup 0 rlineto}
是递归的结束:该部分决定何时停止以及如何代替递归。rlineto
绘制了一条相对线。相对于当前点,即当前点是最后一个路径构造操作符所在的位置(如moveto
,lineto
,但不是rotate
,也不是stroke
)离开了它
ifelse
始终以相同的方式工作:booleantype过程体过程体ifelse:如果布尔值为true,则执行第一个过程体,否则执行第二个过程体。该条件是应用于堆栈上2个数字的gt
运算符的布尔值结果。由于gt
使用其参数,因此请预先ding2 copy
表示执行此操作时数据不会丢失
What does 3 div do here?
由于第二个参数(堆栈顶部)控制图形的总体大小,因此它还控制由所有子调用的组合绘图命令表示的部分图形的“大小”。3div
表示在每个递归级别,图形的“大小”小于“大小”"在叶调用中,条件a>=b保持不变,b用作组成图像的各个线段的长度。这意味着a本身不是线段长度,而是一个阈值。只要b下降到b/3、b/9、b/27、b/81时满足或超过阈值a,则关闭t的时间就到了他发明了一台克隆机,让每个人都拿起铅笔
What does the 2 copy KochR statement perform here?
此行使用与传递到当前调用的两个参数相同的阈值和减小的大小,执行对kochR过程的递归调用。使用2 copy
表示这两个值在堆栈上持续存在,直到pop
进一步向下
这里是C语言的粗略翻译,假设有一个实现Adobe图像模型(也称为模具蒙版,或路径绘制模型)的可用图形库。参数似乎分别是线段的大小和图形的总体大小。因此,最大递归级别由方程式a>=b*(1/3)^R间接控制 因此,您应该能够从中看到,所有的
2拷贝
内容都意味着postscript必须“保持活力”2个未命名变量。每行对应一个过程调用,该过程调用使用堆栈中的2个变量。如果您还忽略了上一个“过程调用”中的最终2 copy
,您应该能够看到最终pop
将是不必要的从postscript编程的角度来看,这些都是非常基本的东西。但是递归的边界是非常复杂的
顺便说一句,如果你喜欢这种分形(我喜欢),你一定要看看。它太神奇了
实现Adobe图像模型的一个流行的C库是,但我将把创建工作程序的任务留给读者作为练习:2 copy gecopies
KochR
的2个参数(我假设它是一个坐标对)然后,ifelse
根据该真值决定是否执行{dup 0 rlineto}
或另一个块中的语句。3div
将坐标对的y值分为三,使该点沿该轴更靠近原点。2copy KochR
创建坐标对的副本(该坐标对具有三分之一的y剖切或其位置旋转),然后递归使用它们对它们执行相同的操作
我对函数所做的最好估计是,它从当前点沿传递到
KochR
的点的方向绘制一个渐变之字形,将点列表留在操作数堆栈上。程序将几个这样的之字形附加到当前路径,每个都是自己的子路径,然后将它们全部笔划,留下整个路径堆栈上的点列表(一个可能的问题)。从上面的程序透视什么是“2拷贝ge{dup 0 rlineto}”正在做什么?实际上我正在尝试将这个程序转换为C?我不是一个常规的post脚本程序员。这里是什么2?如果其他人只是好奇,第一个大写的K是一个错误,应该都是小写的。在修复代码后绘制了一个科赫曲线分形图案(对于这样一个小程序来说很酷)
What does 3 div do here?
What does the 2 copy KochR statement perform here?
void kochR(double a, double b) {
if (a >= b) {
// line from currentpoint to currentpoint+(b,0)
// ie. line of length b along current x-axis
rlineto(b, 0);
} else {
b /= 3;
kochR(a, b); // recurse with reduced length
rotate(60); // rotate x-axis CCW by 60 degrees
kochR(a, b);
rotate(-120); // rotate x-axis CW by 120 degrees
kochR(a, b);
rotate(60);
kochR(a, b);
}
}
int main(void) {
moveto(0,0);
kochR(27, 81);
moveto(0, 27);
kochR(9, 81);
moveto(0, 54);
kochR(3, 81);
moveto(0, 81);
kochR(1, 81);
stroke();
}