PostScript TUTORIAL and COOKBOOKの51ページに星の形を描くプログラムがあります。文字列を表示する print とスタックを表示する pstack を使って動作する様子を追いかけてみます。
- Chapter 6: MORE GRAPHICS (Saving the Graphics State)
/starside { 72 0 lineto % 右へ72ポイント線を引くためのパスを追加 % 実際に線を引くのは stroke のとき % 塗りつぶすのにも同じパスを使っている。 currentpoint % 現在位置の座標をスタックに積む translate % ユーザ空間座標をスタックの位置に移動 -144 rotate } def % ユーザ空間座標を-144回転 /star %stack: x y { moveto % スタックの座標に移動 currentpoint % 現在位置の座標をスタックに積む translate % ユーザ空間座標をスタックの位置に移動 4 {starside} repeat % starside を4回実行する closepath % 描いたパスをmovetoのへ連結して閉じる。 gsave % 塗りつぶすとパスが消えてしまうので % グラフィック環境をスタックへ保存 .5 setgray % 0:白 1.0 黒 0.5の中間色設定 fill % 塗りつぶす grestore % パス等の描写情報をリストア stroke } def % 星形の線を引く % x:200 y:200 をスタックに積んでstar手続きを呼びます。 200 200 star showpage
要するに手で★を描くときと同じ方法です。
- まず、 x:200 y:200 に移動します。
- 72ポイントの横線を引く
- 線を引いた先に基準点を移動させる(ここが 0 0 になる)
- -144度座標を回転させる
これを4回繰り返します。
- 最後に始点を結ぶと言う動作で星を描いています。
print、 pstackを入れまくって動作する様子を表示してみます。
/starside { (== starsider ==\n) print pstack % 全部スタック表示 (== 72 0 lineto ==\n) print 72 0 lineto % 水平に右方向へ72ポイントの線を引く currentpoint % 線を引いた終点の座標をスタックに積む (== currentpoint ==\n) print pstack % 全部スタック表示 (== translate ==\n) print translate % ユーザ空間をスタックに積んだ値に移動 (== -144 rotate ==\n) print -144 rotate % -144 座標系回転 } def %rotate coord. sys. /star %stack: x y { (== Call Star ==\n) print pstack % 全部スタック表示 (== moveto ==\n) print moveto (== currentpoint ==\n) print currentpoint % 線を引いた終点の座標をスタックに積む pstack % 全部スタック表示 (== translate ==\n) print translate % ユーザ空間をスタックに積んだ値に移動 4 {starside} repeat (== closepath ==\n) print closepath gsave .5 setgray fill grestore stroke } def 200 200 star showpage
- print、 pstack の入った star.ps を ps2pdf で pdf に変換します。
> ps2pdf star.ps star.pdf == Call Star == 200 200 == moveto == % x:200 y:200 に移動。 == currentpoint == % 現在位置を取得しスタックへ。 200.0 200.0 == translate == % ユーザ座標をスタックの位置へ。 == starsider == % starsider が呼ばれた。 == 72 0 lineto == % 右へ72ポイントのパス == currentpoint == % 現在位置を取得しスタックへ。 0.0 72.0 == translate == % ユーザ座標をスタックの位置へ。 == -144 rotate == % -144 度ユーザ座標を回転 == starsider == % starsider が呼ばれた。 % 以下同様 == 72 0 lineto == == currentpoint == 0.0 72.0000076 == translate == == -144 rotate == == starsider == == 72 0 lineto == == currentpoint == 0.0 72.0000076 == translate == == -144 rotate == == starsider == == 72 0 lineto == == currentpoint == 1.14440918e-05 72.0000076 == translate == == -144 rotate ==
% Regular polygon /polygonside { 72 0 lineto % 水平に右方向へ72ポイントの線を引く currentpoint % 線を引いた終点の座標をスタックに積む translate % ユーザ空間をスタックに積んだ値に移動 -72 rotate % 座標系回転 正七角形(-51.42857 rotate ) } def /polygon { currentpoint % 線を引いた終点の座標をスタックに積む translate % ユーザ空間をスタックに積んだ値に移動 4{polygonside} repeat % 正七角形(6{polygonside} repeat) closepath gsave .5 setgray fill grestore stroke } def 200 200 moveto polygon showpage
外角の和は360度ですので、以下の値にすると正七角形になります。
- -51.42857 rotate % 座標系回転 360 / 7
- 6{polygonside} repeat % 7 -1