#!/usr/NeWS/bin/psh /poly { % edges => poly 10 dict begin /edges exch def currentdict end } def systemdict /Item known not { (NeWS/liteitem.ps) run } if %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /points [ [0 0 0] [0.476364 0 0.602182] [0.405091 0 0.202182] [0.242182 0 0.111273] [0.0727273 0 0.100364] [0.0610909 0 -0.249455] [0.310545 0 -0.297455] [0.316364 0 -0.374545] [0 0 -0.362909] [0.385386 -0.28 0.602182] [0.327725 -0.238106 0.202182] [0.195929 -0.142351 0.111273] [0.0588376 -0.042748 0.100364] [0.0494236 -0.0359083 -0.249455] [0.251237 -0.182534 -0.297455] [0.255944 -0.185954 -0.374545] [0 0 -0.362909] [0.147204 -0.453049 0.602182] [0.12518 -0.385264 0.202182] [0.0748383 -0.230329 0.111273] [0.022474 -0.0691678 0.100364] [0.0188781 -0.0581009 -0.249455] [0.0959638 -0.295346 -0.297455] [0.0977617 -0.30088 -0.374545] [0 0 -0.362909] [-0.147204 -0.453049 0.602182] [-0.12518 -0.385264 0.202182] [-0.0748383 -0.230329 0.111273] [-0.022474 -0.0691677 0.100364] [-0.0188781 -0.0581009 -0.249455] [-0.0959638 -0.295346 -0.297455] [-0.0977618 -0.30088 -0.374545] [0 0 -0.362909] [-0.385386 -0.279999 0.602182] [-0.327725 -0.238106 0.202182] [-0.195929 -0.142351 0.111273] [-0.0588376 -0.042748 0.100364] [-0.0494236 -0.0359083 -0.249455] [-0.251237 -0.182534 -0.297455] [-0.255944 -0.185954 -0.374545] [0 0 -0.362909] [-0.476364 4.1645e-08 0.602182] [-0.405091 3.54142e-08 0.202182] [-0.242182 2.11722e-08 0.111273] [-0.0727273 6.35802e-09 0.100364] [-0.0610909 5.34074e-09 -0.249455] [-0.310545 2.71487e-08 -0.297455] [-0.316364 2.76574e-08 -0.374545] [0 0 -0.362909] [-0.385386 0.28 0.602182] [-0.327725 0.238107 0.202182] [-0.195929 0.142351 0.111273] [-0.0588376 0.042748 0.100364] [-0.0494236 0.0359083 -0.249455] [-0.251237 0.182534 -0.297455] [-0.255944 0.185954 -0.374545] [0 0 -0.362909] [-0.147204 0.453049 0.602182] [-0.12518 0.385264 0.202182] [-0.0748382 0.230329 0.111273] [-0.0224739 0.0691678 0.100364] [-0.0188781 0.0581009 -0.249455] [-0.0959637 0.295346 -0.297455] [-0.0977616 0.30088 -0.374545] [0 0 -0.362909] [0.147205 0.453049 0.602182] [0.12518 0.385264 0.202182] [0.0748384 0.230329 0.111273] [0.022474 0.0691677 0.100364] [0.0188782 0.0581009 -0.249455] [0.095964 0.295346 -0.297455] [0.0977619 0.30088 -0.374545] [0 0 -0.362909] [0.385387 0.279999 0.602182] [0.327726 0.238106 0.202182] [0.195929 0.142351 0.111273] [0.0588376 0.042748 0.100364] [0.0494236 0.0359083 -0.249455] [0.251237 0.182534 -0.297455] [0.255944 0.185954 -0.374545] [0 0 -0.362909] ] def /polygons [ [ 1 2 10 9 ] poly [ 2 3 11 10 ] poly [ 3 4 12 11 ] poly [ 4 5 13 12 ] poly [ 5 6 14 13 ] poly [ 6 7 15 14 ] poly [ 7 8 15 ] poly [ 9 10 18 17 ] poly [ 10 11 19 18 ] poly [ 11 12 20 19 ] poly [ 12 13 21 20 ] poly [ 13 14 22 21 ] poly [ 14 15 23 22 ] poly [ 15 8 23 ] poly [ 17 18 26 25 ] poly [ 18 19 27 26 ] poly [ 19 20 28 27 ] poly [ 20 21 29 28 ] poly [ 21 22 30 29 ] poly [ 22 23 31 30 ] poly [ 23 8 31 ] poly [ 25 26 34 33 ] poly [ 26 27 35 34 ] poly [ 27 28 36 35 ] poly [ 28 29 37 36 ] poly [ 29 30 38 37 ] poly [ 30 31 39 38 ] poly [ 31 8 39 ] poly [ 33 34 42 41 ] poly [ 34 35 43 42 ] poly [ 35 36 44 43 ] poly [ 36 37 45 44 ] poly [ 37 38 46 45 ] poly [ 38 39 47 46 ] poly [ 39 8 47 ] poly [ 41 42 50 49 ] poly [ 42 43 51 50 ] poly [ 43 44 52 51 ] poly [ 44 45 53 52 ] poly [ 45 46 54 53 ] poly [ 46 47 55 54 ] poly [ 47 8 55 ] poly [ 49 50 58 57 ] poly [ 50 51 59 58 ] poly [ 51 52 60 59 ] poly [ 52 53 61 60 ] poly [ 53 54 62 61 ] poly [ 54 55 63 62 ] poly [ 55 8 63 ] poly [ 57 58 66 65 ] poly [ 58 59 67 66 ] poly [ 59 60 68 67 ] poly [ 60 61 69 68 ] poly [ 61 62 70 69 ] poly [ 62 63 71 70 ] poly [ 63 8 71 ] poly [ 65 66 74 73 ] poly [ 66 67 75 74 ] poly [ 67 68 76 75 ] poly [ 68 69 77 76 ] poly [ 69 70 78 77 ] poly [ 70 71 79 78 ] poly [ 71 8 79 ] poly [ 73 74 2 1 ] poly [ 74 75 3 2 ] poly [ 75 76 4 3 ] poly [ 76 77 5 4 ] poly [ 77 78 6 5 ] poly [ 78 79 7 6 ] poly [ 79 8 7 ] poly [ 1 9 17 25 33 41 49 57 65 73 ] poly ] def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /screen_dist 2 def /perspective { % x y z => X Y % myctm xform % x' y' z' dup 4 -1 roll % y' z' z' x' exch div % y' z' X screen_dist mul 3 1 roll % X y' z' div screen_dist mul } def /move3 { % x y z => - pause pop moveto } def /draw3 { % x y z => - pause pop lineto } def /vect3 { % x1 y1 z1 x2 y2 z2 => - move3 draw3 } def % Return a 4x4 homogeneous matrix that rotates alpha degrees around % an axis (/x, /y, or /z, or [u1 u2 u3]). /rotmat { % degrees axis => matrix 20 dict begin /axis exch def /alpha exch def /sn alpha sin def /cs alpha cos def axis { /x { % Rotate around x [ 1 0 0 0 0 cs sn neg 0 0 sn cs 0 0 0 0 1 ] } /y { % Rotate around y [ cs 0 sn 0 0 1 0 0 sn neg 0 cs 0 0 0 0 1 ] } /z { % Rotate around z [ cs sn neg 0 0 sn cs 0 0 0 0 1 0 0 0 0 1 ] } /Default { % Rotate around an arbitrary vector /cm 1 cs sub def /len 0 axis {dup mul add} forall sqrt def /u3 /u2 /u1 axis {len div def} forall /x1 u1 u2 mul cm mul def /y1 u3 sn mul def /x2 u1 u3 mul cm mul def /y2 u2 sn mul def /x3 u2 u3 mul cm mul def /y3 u1 sn mul def [ u1 dup mul cm mul cs add x1 y1 sub x2 y2 add 0 x1 y1 add u2 dup mul cm mul cs add x3 y3 sub 0 x2 y2 sub x3 y3 add u3 dup mul cm mul cs add 0 0 0 0 1 ] } } case end } def % Return a 4x4 homogeneous matrix that translates by offset [u1 u2 u3]. /transmat { % offset => matrix [ 1 0 0 0 0 1 0 0 0 0 1 0 14 -1 roll aload pop 1 ] } def /settrans { % matrix trans => - 12 exch putinterval } def /screen_size 1 def /screen_front 1 def /screen_back 10 def % Return a 4x4 homogeneus matrix that peforms the perspective transformation % from world to screen coordinates. /perspmat { % => matrix [ 1 0 0 0 0 1 0 0 0 0 screen_size 1 screen_back screen_front div sub screen_back mul div screen_size screen_back div 0 0 screen_size neg 1 screen_back screen_front div sub div 0 ] } def %/perspmat { % => matrix % [ .5 0 .5 0 % 0 .5 0 0 % 0 0 1 1 screen_spread sub div % screen_spread neg 1 screen_spread sub div % 0 0 1 0 ] %} def % Return the number of degrees and axis of rotation of a rotation matrix. /decomposerotate { % matrix => degrees axis 10 dict begin /mat exch def /u [ mat 9 get mat 6 get sub 2 div mat 2 get mat 8 get sub 2 div mat 4 get mat 1 get sub 2 div ] def /sn u 0 get dup mul u 1 get dup mul u 2 get dup mul add add sqrt def /cs mat 0 get mat 5 get mat 10 get add add 1 sub 2 div def /theta sn cs atan def /len sn def { len 0 eq { cs 0 gt { 0 u stop } if 0 1 2 { /i exch def mat i 4 mul i add get -1 gt {exit} if } for /u mat i 4 mul 3 getinterval def u dup i get 1 add dup 2 mul sqrt /len exch def i exch put } if theta [u {len div} forall] } stopped pop end } def /concat4 { % matrix1 matrix2 => matrix3 10 dict begin /m2 exch def /m1 exch def [ 0 1 3 { /j exch def 0 1 3 { /i exch def 0 0 1 3 { /n exch def m1 j 4 mul n add get m2 i n 4 mul add get mul add } for } for } for ] end } def /xformdict 10 dict def /xform { % x y z matrix => x' y' z' 1 index 0 eq { 4 {pop} repeat 0 0 0 } { xformdict begin /m1 exch def /z exch def /y exch def /x exch def /w m1 3 get m1 7 get m1 11 get m1 15 get add add add def m1 0 get x mul m1 4 get y mul m1 8 get z mul m1 12 get add add add w div m1 1 get x mul m1 5 get y mul m1 9 get z mul m1 13 get add add add w div m1 2 get x mul m1 6 get y mul m1 10 get z mul m1 14 get add add add w div end } ifelse } def /xformedpoints null def /myxt 0 def /myyt 0 def /myzt 5 def /myxr 1 def /myyr 0 def /myzr 0 def /mytr 25 def /myctm null def /setmyctm { /myctm mytr [myxr myyr myzr] rotmat dup [myxt 20 div myyt 20 div myzt] settrans perspmat concat4 store /xformedpoints [ points { pause aload pop myctm xform 3 array astore } forall ] store } def setmyctm /pt { % n ==> x y z % points exch get aload pop xformedpoints exch get aload pop } def /drawpolys { polygons { /edges get newpath dup dup length 1 sub get pt move3 {pt draw3} forall stroke } forall } def /drawit { gsave camcan setcanvas clippath pathbbox scale pop pop .5 .5 translate .5 .5 scale 1 fillcanvas 0 setgray drawpolys grestore } def /notify? true def /notify { notify? {(Notify: Value=%) [ItemValue] /printf messages send} if } def /FillColor .75 def /drawcam { notify setmyctm drawit } def /setsize { notify ItemValue 100 div /screen_size exch store } def /setxtrans { notify ItemValue /myxt exch store } def /setytrans { notify ItemValue /myyt exch store } def /setztrans { notify ItemValue /myzt exch store } def /setxrot { notify ItemValue /myxr exch store } def /setyrot { notify ItemValue /myyr exch store } def /setzrot { notify ItemValue /myzr exch store } def /settrot { notify ItemValue /mytr exch store } def /createitems { /items 50 dict dup begin /drawitbutton (Draw!) /drawcam can 100 0 /new ButtonItem send dup /ItemBorderColor .5 .5 .5 rgbcolor put 20 220 /move 3 index send def /sizeslider (Viewing size:) [1 300 100] /Right /setsize can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 180 /move 3 index send def /xtslider (Translate x:) [-20 20 myxt] /Right /setxtrans can 220 20 /new SliderItem send dup /ItemFrame 1 put 300 140 /move 3 index send def /ytslider (Translate y:) [-20 20 myyt] /Right /setytrans can 220 20 /new SliderItem send dup /ItemFrame 1 put 300 100 /move 3 index send def /ztslider (Translate z:) [-20 20 myzt] /Right /setztrans can 220 20 /new SliderItem send dup /ItemFrame 1 put 300 60 /move 3 index send def /xrslider (Rotate x:) [-10 10 myxr] /Right /setxrot can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 140 /move 3 index send def /yrslider (Rotate y:) [-10 10 myyr] /Right /setyrot can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 100 /move 3 index send def /zrslider (Rotate z:) [-10 10 myzr] /Right /setzrot can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 60 /move 3 index send def /trslider (Rotate degrees:) [0 359 mytr] /Right /settrot can 220 20 /new SliderItem send dup /ItemFrame 1 put 20 20 /move 3 index send def /messages /panel_button () /Right {} can 500 0 /new MessageItem send dup begin /ItemFrame 1 def /ItemBorder 4 def end 20 260 /move 3 index send def end def /messages items /messages get def } def /slideitem { % items fillcolor item => - gsave dup 4 1 roll % item items fillcolor item /moveinteractive exch send % item /bbox exch send % x y w h (Item: x=%, y=%, w=%, h=% Canvas: w=%, h=%) [ 6 2 roll win begin FrameWidth FrameHeight end ] /printf messages send grestore } def /main { % Create and size a window. The size is chosen to accommodate the % items we are creating. Right before we map the window, we ask the % user to reshape the window. This is atypical, but gets the items % positioned the way we want them. /win framebuffer /new DefaultWindow send def % Create a window { /PaintClient {FillColor fillcanvas items paintitems} def /FrameLabel (ItemClass for Play!) def /IconImage /galaxy def /ClientMenu [ (White Background) {/FillColor 1 store /paintclient win send} (Light Background) {/FillColor .75 store /paintclient win send} (Medium Background) {/FillColor .50 store /paintclient win send} (Dark Background) {/FillColor .25 store /paintclient win send} (Black Background) {/FillColor 0 store /paintclient win send} (Flip Verbose) {/notify? notify? not store} ] /new DefaultMenu send def } win send % Install my stuff. 200 200 600 340 /reshape win send % Shape it. /can win /ClientCanvas get def % Get the window canvas % Create all the items. createitems % Create event manager to slide around the items. % Create a bunch of interests to move the items. % Note we actually create toe call-back proc to have the arguments we need. % The proc looks like: {items color "thisitem" slideitem}. % We could also have used the interest's clientdata dict. /slidemgr [ % items { % key value % MiddleMouseButton {slideitem} % key item but proc % 1 dict dup DownTransition 5 index put % key item but proc dict % 5 -2 roll exch pop % but proc dict item % /ItemCanvas get eventmgrinterest % } forall items { % key item exch pop dup /ItemCanvas get % item can MiddleMouseButton [items FillColor % item can name mark dict color 6 -1 roll /slideitem cvx] cvx % can name proc DownTransition % can name proc action 4 -1 roll eventmgrinterest % interest } forall ] forkeventmgr def % Now let the user specify the window's size and position. Then map % the window. (See above) Then activate the items. % /ptr /ptr_m framebuffer setstandardcursor /reshapefromuser win send % Reshape from user. /map win send % Map the window & install window event manager. % (Damage causes PaintClient to be called) /itemmgr items forkitems def % create camera window /camwin framebuffer /new DefaultWindow send def % Create a window { /PaintClient {1 fillcanvas} def /FrameLabel (Camera) def /IconImage /galaxy def /ClientMenu [ (Flip Verbose) {/notify? notify? not store} (Draw) {drawit} ] /new DefaultMenu send def } camwin send % Install my stuff. /reshapefromuser camwin send % Shape it. /map camwin send /camcan camwin /ClientCanvas get def % Get the window canvas } def main