%! (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 ] dup normal-function ] % one face [ [ P 3 get P 2 get P 1 get P 0 get ] dup normal-function ] ] def { page-begin gsave3d gsave 1 0 0 setrgbcolor newpath 0 -1 0 moveto3d 0 2 0 lineto3d % stroke grestore gsave3d 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 grestore3d gsave3d % projects onto plane y=-1 from direction [0 1 -1] [0 1 0 1] [0 1 -1 0] plane-project 0.5 0 0 translate3d [0 1 0] A rotate3d 0 1 square length 1 sub { /i exch def /f square i get def /p f 0 get def /n p length def newpath p n 1 sub get aload pop moveto3d p { aload pop lineto3d } forall gsave 0.8 setgray fill } for grestore3d page-end grestore3d /A A dA add def } loop