%!PS-Adobe-2.0 %%BoundingBox: 0 0 200 200 % (../../ps/colours.inc) run /cx 104 def /cy 96 def (../../../ps/ps3d.inc) run (bsp.inc) run % --- surface construction -------------------------------------------- % R = big radius, r = small one % t -> R + r [ cos t, 0, sin t ] rotated by s around the z-axis % or [ cos s(R + r cos t), sin s(R + r cos t), r sin t ] % Jacobian = -sin s(R + r cos t) cos s (R + r cos t) 0 % cos s(-r sin t) sin s(-r sin t) r cos t % normal vector = ... % R, r are global variables % returns [ x y z normal ] /torus { 1 dict begin /t exch def /s exch def % both in degrees /cs s cos def /ss s sin def /rct t cos r mul def /rst t sin r mul def /x R rct add cs mul def /y R rct add ss mul def [ x y rst [ x rct mul y rct mul R rct add rst mul 0 ] normalized ] end } def /R 2 def /r 1 def /M 24 def /N 8 def % implicitly s0, s1, t0 s1 % explicitly M, N, torus are global variables here /ds 360 M div def /dt 360 N div def /vertex [ 0 1 M { /i exch def [ 0 1 N { /j exch def % s = i*ds, t = j*dt i ds mul j dt mul torus } for ] } for ] def % vertex is a global variable here % this defines the array of plates % - of rectangular plates in this case /plates [ 0 1 M 1 sub { /i exch def 0 1 N 1 sub { /j exch def /vij vertex i get j get def /vIj vertex i 1 add get j get def /vIJ vertex i 1 add get j 1 add get def /viJ vertex i get j 1 add get def [ [ vij vIj vIJ viJ ] [ [ vij aload pop pop ] [ vIj aload pop pop ] [ vIJ aload pop pop ] ] normal-function ] } for } for ] def % build the BSP tree % the interpolation routine is used % to construct a normal vector interpolated when a segment is split /b plates /smooth-interp bsp-tree def % --- specify how fragments are drawn ------------------------------------ % E, L, CTM are global variables in this procedure % E = virtual eye, L = virtual light source, CTM = current 3D ctm % This is the routine called on in the traverse of the BSP tree % when drawing the surface fragment that is its argument % one argument: the face to be drawn /gouraud-draw { /face exch def /N face 1 get def /T face 0 get def /ell T length def % T is an array of vertices N E dot-product 0 ge { % break T up into triangles and shade them /V [ T { % [ x y z n ] [ [ 3 2 roll aload pop /nf exch def 1 ] % [ x y z 1 ] CTM transform3d render % X Y L nf dot-product 1 add 2 div 0.76 mul 0.24 add 0 0 % [ X Y shade ] } forall ] def % V now = array of [ X Y s ] /ds [ 1 1 ell 2 sub { /i exch def 0 V 0 get aload pop 0 V i get aload pop 0 V i 1 add get aload pop } for ] def newpath << /ShadingType 4 /ColorSpace [ /DeviceRGB ] /DataSource ds >> shfill } if } def % --- logistics --------------------------------------------------------- /page-begin { gsave cx cy translate 32 dup scale 1 32 div setlinewidth 1 setlinecap 1 setlinejoin } def /page-end { grestore showpage } def % --- the actual drawing ------------------------------------------------ [0 0 16 1] set-eye page-begin [1 1 0 ] 50 rotate3d 1 0 0 setrgbcolor /E get-eye cim3d transform3d def /L [-0.25 1 -0.25 0 ] normalized cim3d transform3d def /CTM ctm3d def b /gouraud-draw traverse page-end