%!PS-Adobe-2.0 %%BoundingBox: 0 0 160 160 (../../ps/ps3d.inc) run % R longitude latitude -> [ [x y z] [a b c d]] /P { 6 dict begin /B exch def /A exch def /R exch def /x A cos B cos mul def /y A sin B cos mul def /z B sin def % (x y z) lies on the unit sphere [ [ x R mul y R mul z R mul] % location [x y z x dup mul y dup mul add z dup mul add R neg mul ] % visibility function ] end } def % latitudes in columns /sphere-vertex { 1 dict begin /N exch def /dA 360 N div 2 div def /dB 180 N div def [ /A 0 def % A = longitude 2 N mul 1 add { [ /B -90 def % B = latitude N 1 add { [ 1 A B P aload pop ] /B B dB add def } repeat ] /A A dA add def } repeat ] end } def /N 16 def /S N sphere-vertex def /sphere [ 0 1 2 N mul 1 sub { /i exch def 0 1 N 1 sub { /j exch def /P S i get j get def /Q S i 1 add get j get def /R S i 1 add get j 1 add get def /n [ P 0 get Q 0 get R 0 get ] normal-function def n length 0 ne { [ P Q R n ] } if /P S i get j get def /Q S i 1 add get j 1 add get def /R S i get j 1 add get def /n [ P 0 get Q 0 get R 0 get ] normal-function def n length 0 ne { [ P Q R n ] } if } for } for ] def % so now sphere is an array of triangles % -------------------------------- /page-begin { gsave 80 80 translate 72 dup scale 1 72 div setlinewidth } def /page-end { grestore showpage } def [0 0 4 1] set-eye /light-source [-0.25 1 0.25 0] normalized def currentlinewidth 4 div setlinewidth % { page-begin [1 0 0 ] 10 rotate3d /E get-eye ctm3d 1 get transform3d def /L light-source ctm3d 1 get transform3d def /CTM ctm3d 0 get def sphere { aload pop /f exch def % f = visibility function /R exch def /Q exch def /P exch def % P etc = [ pt + normal + * * * ] f E dot-product 0 ge { newpath /sP L P 1 get dot-product 1 add 2 div def /sQ L Q 1 get dot-product 1 add 2 div def /sR L R 1 get dot-product 1 add 2 div def /ds [ 0 [ P 0 get aload pop 1 ] CTM transform3d render sP 0 [ Q 0 get aload pop 1 ] CTM transform3d render sQ 0 [ R 0 get aload pop 1 ] CTM transform3d render sR ] def newpath << /ShadingType 4 /ColorSpace [ /DeviceGray ] /DataSource ds >> shfill } if } forall page-end % } loop