

図形を球面に投影したような変換をします。
参考書籍をもとに変換式をPostScriptコードにしました。
変換式は
L:円の半径
z=sqr(x2+y2)
z1=L*sin(2*atan(z/L))
x1=x*z1/z
y1=y*z1/z
円の方程式 x2+y2を使い、円の内側か外側かを判断し、円外ならそのまま描画し、円内なら球面変換します。


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | %!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 240 240 %%Title:球面変換 /L 80 def % 変換する円の大きさ 2 setlinecap % 線の先端スクエア /sw 0 def % 始点スイッチ /kyumen { % 球面変換プロシージャ x 2 exp y 2 exp add L 2 exp gt { % 円の外側は変換しない /x1 x def /y1 y def } { /z x 2 exp y 2 exp add sqrt def % 領域内を変換する。円の中心との距離 z 0 eq { /x1 x def /y1 y def } { % 分母は0にできないので変換しない /z1 L 2 z L atan mul sin mul def % 以下球面変換式 /x1 x z1 mul z div def /y1 y z1 mul z div def } ifelse } ifelse sw 0 eq { x1 y1 moveto /sw 1 def } % swが0なら始点へ移動 { x1 y1 lineto } ifelse % 始点と終点の間にパスを引く } def 0 setgray 0 0 240 240 rectstroke % 黒枠 120 120 translate % 座標の原点を中央に移動 newpath % 水平線 -100 5 100 { /y exch def -100 1 100 { /x exch def kyumen % 球面変換プロシージャ呼び出し } for /sw 0 def % 始点スイッチのリセット } for % 垂直線 -100 5 100 { /x exch def -100 1 100 { /y exch def kyumen } for /sw 0 def } for stroke % 線を描画 |

ヴィクトル・バザルリの絵画のような図形。
enプロシージャで円の座標を得て、kyumenプロシージャを呼び出し球面変換します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | %!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 240 240 %%Title:球面変換 /L 100 def % 変換する円の大きさ /sw 0 def % 始点スイッチ /kyumen { % 球面変換プロシージャ x 2 exp y 2 exp add L L mul gt { % 円の外は変換しない /x1 x def /y1 y def } { /z x 2 exp y 2 exp add sqrt def % 領域内を変換する 円の中心との距離 z 0 eq { /x1 x def /y1 y def } { % 0では割れないので変換しない /z1 L 2 z L atan mul sin mul def /x1 x z1 mul z div def /y1 y z1 mul z div def } ifelse } ifelse sw 0 eq { x1 y1 moveto /sw 1 def } % 始点へ移動 { x1 y1 lineto } ifelse % 始点と終点の間にパスを引く } def % ===== 円 ===== /r 5 def % 円の半径 % dx dy 円の移動量 /en { 0 1 360 { /th exch def /x r th cos mul dx add def /y r th sin mul dy add def kyumen % 球面変換呼び出し } for } def 0 .5 1 setrgbcolor 0 0 240 240 rectfill % ブルーの四角形 120 120 translate % 座標の原点を中央に移動 -120 12 120 { % 縦横に円を描く /dy exch def -120 12 120 { /dx exch def en % enプロシージャ呼び出し /sw 0 def % 始点リセット } for /sw 0 def } for 1 .5 0 setrgbcolor fill % オレンジ色で塗りつぶす |

コメント