%! (ps3d.inc) run /page-begin { gsave 72 dup scale 1 72 div setlinewidth 4 5 translate } def /page-end { grestore showpage } def [0 0 8 1] set-eye /light [-1 0 1 0 ] normalized def /A 0 def /dA 10 def % lists the vertices of the square /P [ [ -0.5 -0.5 0] [ 0.5 -0.5 0] [ 0.5 0.5 0] [ -0.5 0.5 0] ] def % holds the faces of the square % a face is points + visibility function /square [ % one face [ [ P 0 get P 1 get P 2 get P 3 get ] [0 0 1 0]] % one face [ [ P 3 get P 2 get P 1 get P 0 get ] [0 0 -1 0]] ] def { page-begin gsave3d gsave 1 0 0 setrgbcolor newpath 0 -1 0 moveto3d 0 2 0 lineto3d stroke grestore 0.5 0 0 translate3d [0 1 0] A rotate3d /Tinv ctm3d 1 get def /E get-eye def /O E Tinv transform3d def /L light Tinv transform3d def gsave 0 1 0 setrgbcolor newpath 0 -1 0 moveto3d 0 2 0 lineto3d stroke grestore /colour [ [1 0 0] [0 1 0] ] def /S [ 0 1 3 div 2 3 div 1 ] def 0 1 square length 1 sub { /i exch def /f square i get def % f = [ point-array visibility ] /v f 1 get def v O dot-product 0 ge { /p f 0 get def /n p length def newpath p n 1 sub get aload pop moveto3d p { aload pop lineto3d } forall gsave /s S L v dot-product shade def colour i get 0 get s mul colour i get 1 get s mul colour i get 2 get s mul setrgbcolor fill grestore stroke } if } for page-end grestore3d /A A dA add def } loop