Koch 曲線

正月はフラクタルという風習があるそうなので、xterm の Tektronix モードを利用してコッホ曲線を描いてみました。

使い方

xterm を起動する。

% xterm -t

xterm でコマンドを打つ。

% gs -dNODISPLAY -dBATCH koch.ps

Teraterm にも Tek 端末エミュレーション機能があるようなので、Windows な方はそちらでお試し下さい。私は試していません。

結果

中身

ゴルフとか難読化とかはしていません。

%!PS
gsave
/erase-screen{
    % file -
    <1b 0c> writestring
}def
/line-mode{
    % file -
    <1d> writestring
}def
/text-mode{
    % file -
    <1f> writestring
}def
/tek-move{
    % x y file -
    4 dict begin
        /term exch def
        /y exch def
        /x exch def
        /buf (  ) def

        buf 0 y -5 bitshift 31 and 32 or put
        buf 1 y 31 and 96 or put
        term buf writestring

        buf 0 x -5 bitshift 31 and 32 or put
        buf 1 x 31 and 64 or put
        term buf writestring
    end
}def
/tek-line{
    % x1 y1 x2 y2 file -
    1 dict begin
        /term exch def
        4 2 roll term tek-move
        term tek-move
    end
}def
/ps-line{
    % x1 y1 x2 y2 -
    newpath
    4 2 roll moveto
    lineto
    stroke
}def

/koch{
    % x1 y1 x2 y2 eps file -
    3 dict begin
        /term exch def
        /eps exch def
        /koch-rec{
            % x1 y1 x2 y2 -
            10 dict begin
                /y2 exch def
                /x2 exch def
                /y1 exch def
                /x1 exch def

                x1 x2 sub dup mul
                y1 y2 sub dup mul add sqrt eps lt{
                    term line-mode
                    x1 cvi y1 cvi x2 cvi y2 cvi term tek-line
                    x1 y1 x2 y2 ps-line
                }{
                    /x3 x1 2 mul x2 add 3 div def
                    /y3 y1 2 mul y2 add 3 div def
                    /x5 x1 x2 2 mul add 3 div def
                    /y5 y1 y2 2 mul add 3 div def
                    % x4=(x5-x3)*cos(60)-(y5-y3)*sin(60)+x3
                    /x4 x5 x3 sub 60 cos mul
                    y5 y3 sub 60 sin mul sub x3 add cvi def
                    % y4=(x5-x3)*sin(60)+(y5-y3)*cos(60)+y3
                    /y4 x5 x3 sub 60 sin mul
                    y5 y3 sub 60 cos mul add y3 add cvi def

                    x1 y1 x3 y3 koch-rec
                    x3 y3 x4 y4 koch-rec
                    x4 y4 x5 y5 koch-rec
                    x5 y5 x2 y2 koch-rec
                }ifelse
            end
        }def
        koch-rec
    end
}def

/term (%stdout) (w) file def
term erase-screen
term line-mode
10 300 500 300 4 term koch
term text-mode
term (\n) writestring
term closefile
grestore

反省

本当は xterm の起動も PostScript からやりたかったのですが、うまくいきませんでした。