%!PS-Adobe-2.0 %%BoundingBox: 0 0 612 792 %%Pages: 1 %%EndComments %%Page: 1 1 % udonge0.ps - Don Yang (uguu.org) % % 11/14/08 % Seed random number generator. Use a seed defined from command line % if available, otherwise use usertime. An external seed is % preferred, since PostScript built-ins like usertime and realtime are % fairly deterministic. systemdict /Seed known { Seed } { usertime } ifelse srand % Due to PostScript implementation, the first few random numbers tend % to be not so random (they tend to be small numbers), so throw them % away until we get enough randomness. 9 { rand pop } repeat % Page settings /Margin 54 def /Width 504 def /Height 684 def /PageScale Width Height lt {Width} {Height} ifelse def /SpriteSpacing 20 def /SpriteScale 0.08 def % Generate random number between 0 and 1 /Rand { rand 2 31 exp div } bind def % Initialize colors for HSB gradient. The colors here are chosen more % for psychedelic effect than for aesthetic reasons. Brightness is not % 1.0 to make the shapes more visible on white paper. /Hue1 0.7 Rand 0.3 mul sub def /Hue2 1.0 Rand 0.3 mul sub def /Brightness 0.6 def % Initialize parameters /StepCount 8 def /XPhase Rand 360 mul def /YPhase Rand 360 mul def /XPeriod Rand 240 mul 120 add PageScale div def /YPeriod Rand 240 mul 120 add PageScale div def % Draw a single sprite at origin /Zayaku { % Clipping path. Drawing all shapes with some overlap then % trimming it later with a clip avoids numerical artefacts (e.g. % thin color lines at shape boundaries) -100 50 moveto 40 50 lineto 100 0 lineto 40 -50 lineto -100 -50 lineto closepath clip newpath % Bottom layers Hue1 1.0 Brightness sethsbcolor -110 60 moveto 0 60 lineto 0 -60 lineto -110 -60 lineto closepath fill Hue2 1.0 Brightness sethsbcolor 0 60 moveto 110 60 lineto 110 -60 lineto 0 -60 lineto closepath fill % Gradient. This can be implemented with shfill instead, but it's % more straightforward to do it manually, especially for % interpolating across HSB space. Avoiding shfill also means we % can stay at LanguageLevel 2. 1 1 StepCount { StepCount div dup Hue2 Hue1 sub mul Hue1 add 1.0 Brightness sethsbcolor 100 mul -80 add dup 60 moveto 100 60 rlineto 0 -120 rlineto -60 lineto closepath fill } for % Top layer. Only half of the shape is drawn by default, since % that looks better when printed on white paper. false { % Full center shape 0.0 0.0 1.0 sethsbcolor -85 35 moveto 30 35 lineto 70 0 lineto 30 -35 lineto -85 -35 lineto closepath fill } { % Half center shape 0.0 0.0 1.0 sethsbcolor -85 35 moveto 30 35 lineto 70 0 lineto -85 0 lineto closepath fill } ifelse } bind def % Draw one row of sprites /XLoop { % y, sy /sy exch def /y exch def 0 SpriteSpacing Width { % x, sx = sin((x + XPhase) * XPeriod) dup XPhase add XPeriod mul sin % x, angle = 360 * ((sx + sy + 2) / 4) sy add 2 add 4 div 360 mul % Draw sprite gsave exch y translate Margin Margin translate rotate SpriteScale SpriteScale scale Zayaku grestore } for } bind def % Draw rows of sprites /YLoop { 0 SpriteSpacing Height { % y, sy = sin((y + YPhase) * YPeriod) dup YPhase add YPeriod mul sin XLoop } for } bind def YLoop showpage %%EOF