%%Creator: Aubrey Jaffer %%For: Voluntocracy %%Copyright: 2018, 2019 Aubrey Jaffer %%Creator: Aubrey Jaffer %%For: Voluntocracy %%CreationDate: 2019-01-23 /plotdict 100 dict def plotdict begin /URL (http://people.csail.mit.edu/jaffer/Marbling) def /pi 3.141592653589793 def /e 2.718281828459045 def /e^-1 1 e div def /m4o3 -4 3.0 div def % dps define max, if not already defined systemdict /max known not { /max { /arg1 exch def/arg2 exch def arg1 arg2 gt {arg1}{arg2}ifelse } def /min { /arg1 exch def/arg2 exch def arg1 arg2 lt {arg1}{arg2}ifelse } def } if % dps asin definition from mst-math.pro used here systemdict /arcsin known not { /arcsin {neg dup dup mul neg 1 add sqrt neg atan 180 sub} bind def } if /numeric? % x --> bool { type dup /realtype eq exch /integertype eq or } bind def % negative viscosity for (raster) reverse-marbling /marble % nu (viscosity) { dup /nu exch 1e-6 mul abs def /reverse-rendering? exch 0 lt def % 0 setlinewidth reverse-rendering? { matrix currentmatrix aload pop 6 {round 6 1 roll} repeat matrix astore setmatrix newpath } if % clippath pathbbox /hiy exch round cvi def /hix exch round cvi def % /loy exch round cvi def /lox exch round cvi def reverse-rendering? not {background aload pop setrgbcolor fill} if /scl hiy loy sub hix lox sub max def % /orgx hix lox add 2 div def % /orgy hiy loy add 2 div def /acnt actions length def % set background field of each /drop 0 1 acnt -1 add { /sdx exch def actions sdx get aload pop /ct exch def ct /drop eq { pop pop pop /cy exch .001 mul def /cx exch .001 mul def cx cy sdx find-drop-background /bgc exch def actions sdx get 3 bgc put } { ct /vortex eq {pop pop pop pop} { ct /stroke eq ct /rake eq or {pop pop pop pop pop} { ct /stir eq {pop pop pop pop pop pop} { ct /wiggle eq {numeric? {pop pop} if pop} { ct /offset eq {pop pop} {(unrecognized token) = ct =} ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } for reverse-rendering? { do-raster } { % orgx orgy translate scl 1.0 div dup scale do-drops } ifelse } bind def /ct-dispatch { ct /rake eq {rake-deformation} { ct /stroke eq {stroke-deformation} { ct /stir eq {stir-deformation} { ct /vortex eq {vortex-deformation} { ct /wiggle eq {wiggle-deformation} { ct /offset eq {offset-deformation} {(unrecognized token) = ct =} ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } bind def %% Given x, y coordinates and index of /drop on stack, returns the rgb %% vector of the drop immediately surrounding that drop. /find-drop-background { /cdx exch -1 add def { cdx 0 lt {pop pop background exit} if actions cdx get aload pop /ct exch def ct /drop eq % movement due to drop. { % px py cx cy rad rgb /rgb exch def pop % /bgc exch def /rad^2 exch .001 mul dup mul def /cy exch .001 mul def /cx exch .001 mul def /py exch def /px exch def /a^2 px cx sub dup mul py cy sub dup mul add def a^2 1e-10 lt {0.} {1. rad^2 a^2 div sub} ifelse /disc exch def disc 0. le {rgb exit} { /a disc sqrt def px cx sub a mul cx add py cy sub a mul cy add } ifelse } {ct-dispatch} ifelse /cdx cdx -1 add def } loop } bind def /offset-deformation % px py dx dy --> px py { /dy exch .001 mul def /dx exch .001 mul def dy reverse-rendering? {neg} if add exch dx reverse-rendering? {neg} if add exch } bind def /wiggle-deformation % px py angle period ofst depth --> px py { dup numeric? { /depth exch def /ofst exch def /period exch def /ang exch def /dy ang cos def /dx ang sin def /py exch def /px exch def /a py dx mul px dy mul sub 1000 360 div period mul mul ofst add sin depth mul 1e-3 mul reverse-rendering? {neg} if def } { % old-style: px py ang {func} --> px py /func exch def /ang exch def /dy ang cos def /dx ang sin def /py exch def /px exch def /a py dx mul px dy mul sub 1000 mul func exec 1e-3 mul reverse-rendering? {neg} if def } ifelse px dx a mul add py dy a mul add } bind def /tines % cnt spacing ofst { /ofst exch def /spacing exch def /cnt exch def /hint cnt 1 sub -2 div cvi def hint 1 cnt 1 sub hint add { spacing mul ofst add } for } bind def /stroke-deformation % px py bx by ex ey V D --> px py { /D exch .001 mul def /V exch .001 mul abs def reverse-rendering? { 4 2 roll } if /ey exch .001 mul def /ex exch .001 mul def /by exch .001 mul def /bx exch .001 mul def /py exch def /px exch def /tU ex bx sub dup mul ey by sub dup mul add sqrt def /L V D dup mul mul nu div def 1e-6 tU le { /nx ex bx sub tU div def /ny ey by sub tU div def /rpts tU L div ceiling cvi def /stpx ex bx sub rpts div def /stpy ey by sub rpts div def /ex bx stpx add def /ey by stpy add def /tU tU rpts div def /inx 0 def /iny 0 def 1 1 rpts { pop /dxB bx px sub def /dyB by py sub def /dxE ex px sub def /dyE ey py sub def /r dxB dup mul dyB dup mul add sqrt 1e-9 add def /s dxE dup mul dyE dup mul add sqrt 1e-9 add def /txB dxB nx mul dyB ny mul add def /txE dxE nx mul dyE ny mul add def /ty dxB ny mul dyB nx mul sub def /denr e r L div exp r mul L mul 2 mul def /dens e s L div exp s mul L mul 2 mul def /inx r L mul ty dup mul sub tU mul denr div s L mul ty dup mul sub tU mul dens div add def /iny txB ty mul tU mul denr div txE ty mul tU mul dens div add def /px px inx nx mul iny ny mul add add def /py py inx ny mul iny nx mul sub add def /bx ex def /by ey def /ex ex stpx add def /ey ey stpy add def } for } if px py } bind def /rake-deformation % [ ang [ rs ] V tU D /rake ] { /D exch .001 mul def /tU exch .001 mul def /V exch .001 mul abs def /rs exch def /ang exch def /py exch def /px exch def /dy ang cos def /dx ang sin def /L^-1 nu V D dup mul mul div def /a 0 def rs { /r exch .001 mul def /bx dy r mul def /by dx r mul neg def px bx sub dy mul py by sub dx mul sub abs L^-1 mul e^-1 exch exp tU mul a add /a exch def } forall /a a reverse-rendering? {neg} if def px dx a mul add py dy a mul add } bind def /stir-deformation % [ cx cy [ rs ] w th D /stir ] { /D exch .001 mul def /th exch def /w exch abs def /rs exch def /cy exch .001 mul def /cx exch .001 mul def /py exch def /px exch def /p-c px cx sub dup mul py cy sub dup mul add sqrt def /a 0 def 1e-6 p-c lt {rs { /r exch .001 mul def /L^-1 nu w pi 180 div mul r abs mul D dup mul mul div def /a p-c r abs sub abs L^-1 mul e^-1 exch exp th mul r 0 lt {neg} if a add def } forall /a a reverse-rendering? {neg} if def } if px cx sub py cy sub [ a dup cos exch sin 2 copy neg exch cx cy ] transform } bind def % An irrotational vortex. circ is circulation; t is time in seconds /vortex-deformation % px py cx cy circ t --> px py { /t exch def /circ exch 1e-6 mul def /cy exch .001 mul def /cx exch .001 mul def /py exch def /px exch def /p-c^2 px cx sub dup mul py cy sub dup mul add def /a p-c^2 1e-6 lt {0} { nu 4 mul .75 exp p-c^2 2 pi mul mul t div .75 exp add m4o3 exp 180 pi div mul circ mul reverse-rendering? {neg} if } ifelse def px cx sub py cy sub [ a dup cos exch sin 2 copy neg exch cx cy ] transform } bind def %% Functions used for forward rendering: % movement due to drop. /spread % px py cx cy rad --> px py { /rad exch .001 mul def /cy exch .001 mul def /cx exch .001 mul def /py exch def /px exch def /p-c^2 px cx sub dup mul py cy sub dup mul add def /a rad dup mul p-c^2 div 1 add sqrt def py cy sub px cx sub a mul cx add exch a mul cy add } bind def %% Given x, y coordinates on stack, calculates movement due to %% subsequent operations. /composite-map { idx 1 add 1 acnt -1 add { actions exch get aload pop /ct exch def ct /drop eq {pop pop spread} % pop rgb-vectors {ct-dispatch} ifelse } for } bind def % Given x, y coordinates on stack and eps < 2, leaves x, y on stack % for next point on the circle centered at origin. /Minsky-circle { dup 3 1 roll eps mul sub dup eps mul 3 2 roll add } bind def % Draws and fills circle as distorted by composite-map /do-action { Ir Cx add Cy composite-map moveto Ir 0 { dup /oy exch def Minsky-circle 2 copy exch Cx add exch Cy add % shift center of drop composite-map lineto dup 0 gt oy 0 lt and {exit} if } loop pop pop closepath Contours } bind def % Fills (distorted) circles. /do-drops % acnt = index of last action + 1 { 0 1 acnt -1 add { /idx exch def actions idx get aload pop /act exch def /drop act eq { aload pop setrgbcolor pop /Ir exch .001 mul def /Cy exch .001 mul def /Cx exch .001 mul def /eps 0.005 scl sqrt Ir mul acnt idx sub 1 add log mul div def do-action } if } for } bind def %% Functions used for reverse-rendering: /Vmap1 % v1 proc { /proc exch def /v1 exch def [ v1 {proc exec} forall ] } bind def /Vmap2 % v1 v2 proc { /proc exch def /v2 exch def /idx 0 def /res v2 length array def { res exch idx exch v2 idx get proc exec put /idx idx 1 add def } forall res } bind def /shade % v[3] pwr { /pwr exch def {dup 1e-30 lt {} {pwr exp} ifelse} Vmap1 } bind def /sharpen % 0<=x<=1 { .5 sub dup abs 1e-8 lt {} {dup abs .66 exp div .63 mul} ifelse .5 add } bind def %% Given x, y coordinates on stack, calculates the rgb vector %% acnt is index +1 of last operation. /actions2rgb { /cdx acnt -1 add def { actions cdx get aload pop /ct exch def ct /drop eq % movement due to drop. { % px py cx cy rad^2 rgb /rgb exch def /bgc exch def /rad^2 exch .001 mul dup mul def /cy exch .001 mul def /cx exch .001 mul def /py exch def /px exch def /a^2 px cx sub dup mul py cy sub dup mul add def a^2 1e-10 lt {0.} {1. rad^2 a^2 div sub} ifelse /disc exch def disc 0. le { disc -0.001 le {rgb} { /a disc neg sqrt sharpen def rgb bgc {1 a sub mul exch a mul add} Vmap2} ifelse exit } { /a disc sqrt def px cx sub a mul cx add py cy sub a mul cy add } ifelse } {ct-dispatch} ifelse /cdx cdx -1 add def cdx 0 lt {pop pop background exit} if } loop } bind def /do-raster { loy 1 hiy { /iy exch def /fy iy orgy sub scl div 1.0 mul def lox 1 hix { /ix exch def /fx ix orgx sub scl div 1.0 mul def fx fy actions2rgb % color modifications % fy dup mul fx dup mul add sqrt dup % riplim lt % {180. ripple div mul sin abs .75 mul 1 exch sub shade} % {pop} % ifelse % end color modifications aload pop setrgbcolor ix iy 1 1 rectfill } for } for } bind def % [ cx cy radinc [ bgc ] [ rgb ] /drop ] % [ cx cy [ r ] w th D /stir ] % [ cx cy circ t /vortex ] % [ bx by ex ey V D /stroke ] % [ angle [ r ] V tU D /rake ] % [ angle period ofst depth /wiggle ] % [ dx dy /offset ] /concatstrings % (a) (b) -> (ab) { exch dup length 2 index length add string dup dup 4 2 roll copy length 4 -1 roll putinterval } bind def /color-norm % rgb { /rgb exch def rgb type /integertype eq { /rgb [ rgb ] def } if rgb type /stringtype eq { /rgb (16#) rgb concatstrings cvi def /rgb [ rgb 65536 idiv 255 div rgb 256 idiv 256 mod 255 div rgb 256 mod 255 div ] def } if rgb length 1 eq { /rgb rgb aload pop def [ rgb 65536 idiv 255 div rgb 256 idiv 256 mod 255 div rgb 256 mod 255 div ] } { rgb {1 gt} forall or or { [ rgb {255 div} forall ] } { rgb } ifelse } ifelse } bind def /drop % cx cy radinc rgb { /rgb exch def /radinc exch def /cy exch def /cx exch def [ cx cy radinc -1 rgb color-norm /drop ] } bind def /stir % cx cy [ r ] w th D { /stir 7 array astore } bind def /vortex % cx cy circ t { /vortex 5 array astore } bind def /stroke % bx by ex ey V D { /stroke 7 array astore } bind def /rake % angle [ r ] V tU D { /rake 6 array astore } bind def /wiggle % angle period ofst depth { dup numeric? { /wiggle 5 array astore } { /wiggle 3 array astore } ifelse } bind def /shift % angle r { /r exch def /th exch def [ th sin r mul th cos r mul /offset ] } bind def /concentric-rings % xc yc thick [ color ] count { /cnt exch def /clra exch def /rinc exch def /yc exch def /xc exch def /nclr clra length def cnt 1 sub -1 0 { /cnt exch def cnt 0 le { xc yc rinc clra 0 get drop } { xc yc cnt 2 mul 1 add sqrt rinc mul clra cnt nclr mod get drop } ifelse } for } bind def /coil-drops % xc yc r ang-strt arcinc rinc [ rgb ] cnt drad { /drad exch def /cnt exch def /clra exch def /rinc exch def /arcinc exch def /th exch def /r exch def /yc exch def /xc exch def clra 0 get type /arraytype ne { /clra [ clra ] def } if /nclr clra length def /cdx 0 def cnt { th sin r mul xc add th cos r mul yc add drad clra cdx nclr mod get drop /th th arcinc r div -1 max 1 min arcsin add def /r r rinc add def /cdx cdx 1 add def } repeat } bind def /line-drops % xc yc ang [ r ] [ rgb ] drad { /drad exch def /clra exch def /rs exch def /th exch def /yc exch def /xc exch def clra 0 get type /arraytype ne { /clra [ clra ] def } if /nclr clra length def /cdx 0 def rs { /r exch def th sin r mul xc add th cos r mul yc add drad clra cdx nclr mod get drop /cdx cdx 1 add def } forall } bind def % Copyright (C) 1996-1998 Geoffrey Keating. % This file may be freely distributed with or without modifications, % so long as modified versions are marked as such and copyright % notices are not removed. % Modified for PRNG use by Aubrey Jaffer 2019. % An implementation of an algorithm compatible with the RSA Data Security % Inc. RC4 stream encryption algorithm. % rc4setkey /rc4setkey { 6 dict begin /k exch def /a 256 string def 0 1 255 { a exch dup put } for /l k length def /j 0 def 0 1 255 { /i exch def /j a i get k i l mod get add j add 255 and def a i a j get a j a i get put put } for 3 dict dup begin /a a def /x 0 def /y 0 def end end } bind def % rc4 /rc4 { 1 index begin dup dup length 1 sub 0 exch 1 exch { /x x 1 add 255 and def /y a x get y add 255 and def a x a y get a y a x get put put % stack: string string index 2 copy get a dup x get a y get add 255 and get xor put dup } for pop end } bind def % Returns number between 0. and 1. /random:uniform { /str 7 string def 0 1 str length -1 add { str exch 0 put } for seed str rc4 exch pop 0 exch {add 256. div} forall } bind def % Returns pair of normally distributed numbers. /random:normal2 { /rnt random:uniform 360 mul def /rnr random:uniform log -2 mul e log div sqrt def rnt cos rnr mul rnt sin rnr mul } bind def /Gaussian-drops % xc yc r angle eccentricity [ rgb ] cnt drad { /drad exch def /cnt exch def /clra exch def /eccentricity exch sqrt def /angle exch def /r exch 2 sqrt div def /yc exch def /xc exch def clra 0 get type /arraytype ne { /clra [ clra ] def } if /nclr clra length def /cdx 0 def cnt { random:normal2 eccentricity div r mul exch eccentricity mul r mul [ angle dup cos exch sin 2 copy neg exch xc yc ] transform drad clra cdx nclr mod get drop /cdx cdx 1 add def } repeat } bind def /uniform-drops % xc yc xsid ysid angle [ rgb ] cnt drad { /drad exch def /cnt exch def /clra exch def /angle exch def /ysid exch def /xsid exch def /yc exch def /xc exch def clra 0 get type /arraytype ne { /clra [ clra ] def } if /nclr clra length def /cdx 0 def cnt { random:uniform 0.5 sub xsid mul random:uniform 0.5 sub ysid mul [ angle dup cos exch sin 2 copy neg exch xc yc ] transform drad clra cdx nclr mod get drop /cdx cdx 1 add def } repeat } bind def end % Local Variables: % mode: PS % End: