コンピュータ基礎II 通信授業課題2C 参考ページ



5. 再帰呼び出し

ある関数(サブルーチン)が自分自身を呼び出すことを再帰呼び出しと言いますが、PostScriptではある手続きがその中で自分自身を呼び出すような処理になります。

○サンプル20

教科書p.191の問題6(解答の図はp.192の図5.15)をPostScriptでは以下のように記述することができます(他の方法もあります)。
下記では木を描く手続きとしてdrawTreeを定義して、その中で木の枝を描く方法を定義し、さらにdrawTree内からdrawTreeを呼び出すようにしています。

translateで座標を移動させながら原点に向かって線を描くことを繰り返します。

**********************************************************************

%!PS-Adobe-3.1 EPSF-3.0
%%BoundingBox: 0 0 800 600

/length 140 def
/depth 10 def

/drawTree{

    newpath 0 0 moveto 0 2 index translate 0 0 lineto 
    0 0 .5 setrgbcolor stroke
    
    dup 0 gt {

        1 sub exch .7 mul exch 2 copy 
        
        gsave
        30 rotate
        drawTree
        grestore
        
        gsave
        -30 rotate
        drawTree
        grestore
        
    }{
        pop pop
        
    } ifelse
    
} def

400 100 translate
length depth drawTree
showpage


**********************************************************************

PostScriptサンプル20



○サンプル21

再帰呼び出しに関しては、フラクタル図形などのプログラムがWeb上などで見つかるはずですが、参考となるでしょう。
サンプル21は1つの大きな円に対して4つの小さな円を描く処理を再帰呼び出して行っています。

**********************************************************************

%!PS-Adobe-3.1 EPSF-3.0
%%BoundingBox: 0 0 800 600

/x1_point 100 def
/x2_point 700 def
/y1_point 100 def
/y2_point 500 def

/radius 50 def
/scale_val .4 def

/tilt y2_point y1_point sub x2_point x1_point sub div def

/circle { newpath 0 0 radius 0 360 arc stroke} def

/drawSubOval {

        circle
            
    1 sub dup dup dup dup 0 gt {

        gsave
        radius -1 mul 0 translate
        scale_val dup scale
        drawSubOval
        grestore

        gsave
        0 radius translate
        scale_val dup scale
        drawSubOval
        grestore

        gsave
        radius 0 translate
        scale_val dup scale
        drawSubOval
        grestore

        gsave
        0 radius -1 mul translate
        scale_val dup scale
        drawSubOval
        grestore
    }{
        pop pop pop pop
    } ifelse
    
} def

/i 0 def

40 60 translate

11 {
    60 dup tilt mul translate

    gsave
    i 2 mod 1 eq {
        0 .7 .15 setrgbcolor
        1.5 setlinewidth
    }{ 
        1 0 .15 setrgbcolor
        3 setlinewidth
        .5 .5 scale
    }ifelse
    
    3 drawSubOval
    /i i 1 add def
    grestore
} repeat

showpage

**********************************************************************

PostScriptサンプル21



上記の図形は、初めの円の直径が100point、再帰時に円の大きさを40%に縮小、3回再帰を繰り返した例です。

初めの円の直径を80point(半径40point)、再帰時の円の大きさを70%に縮小と設定を変えると、以下のように趣の異なった描画となります。

PostScriptサンプル21