% - mkpath.inc ------------------------ /mkpath-loaded true def % For a simple currentpoint: /mkpathDict 8 dict def mkpathDict begin /pathcount { 0 {pop pop pop 1 exit} {pop pop pop 1 exit} {pop pop pop pop pop pop pop 1 exit} { pop 1 exit} pathforall } def /thereisacurrentpoint { pathcount 0 gt {true} {false} ifelse } def % - for debugging ----------------------------- /pwd 0.032 def /pixel { 2 copy newpath moveto pwd 2 div neg pwd 2 div neg rmoveto pwd 0 rlineto 0 pwd rlineto pwd neg 0 rlineto 0 pwd neg rlineto closepath fill } def end % --------------------------------------------- % stack: [parameters] /f t0 t1 N /mkpath { mkpathDict begin 12 dict begin /N exch def /t1 exch def /t exch def /f exch cvx def /pars exch def /h t1 t sub N div def /h3 h 0.333333 mul def pars t f aload pop /velocity exch def /position exch def position aload pop thereisacurrentpoint { lineto } { moveto } ifelse N { % x y = currentpoint % currentpoint pixel pop position 0 get velocity 0 get % x dx/dt h3 mul add position 1 get velocity 1 get % y dy/dt h3 mul add /t t h add def pars t f aload pop /velocity exch def /position exch def position 0 get velocity 0 get h3 mul sub position 1 get velocity 1 get h3 mul sub position 0 get position 1 get % pixel curveto } repeat end % local dict end % mkpath dict } def % stack: [parameters] /f t0 t1 N % where f takes pars + x and returns [y y'] /mkgraph { mkpathDict begin 12 dict begin /N exch def /t1 exch def /t0 exch def /f exch cvx def /pars exch def /h t1 t0 sub N div def /h3 h 0.333333 mul def /currenty pars t0 f def % currenty = [y0 v0] t0 currenty 0 get thereisacurrentpoint { lineto } { moveto } ifelse N { % x y = currentpoint % currentpoint pixel pop t0 h3 add % t0 currenty 0 get % t0 y0 currenty 1 get % t0 y0 v0 h3 mul add % t1 y1 /t0 t0 h add def /currenty pars t0 f def t0 h3 sub % t2 currenty 0 get currenty 1 get h3 mul sub % t2 y2 t0 currenty 0 get % t3 y3 % pixel curveto } repeat end % local dict end % mkpath dict } def % an addition to the 2D drawing: produces a polygonal path % with exactly the same call as mkpath - for debugging % when you suspect your derivative formula is incorrect /mkpolypath { mkpathDict begin 10 dict begin /N exch def /tf exch def /ti exch def /f exch cvx def /pars exch def /h tf ti sub N div def pars ti f % [[x y][x' y']] 0 get aload pop thereisacurrentpoint { lineto } { moveto } ifelse /t ti h add def N { pars t f 0 get aload pop lineto /t t h add def } repeat end % local dict end % mkpath dict } def % pars /f ti tf N => a polygon of (N+1) points /parametrization-to-polygon { 8 dict begin /N exch def /tf exch def /ti exch def /f exch cvx def /pars exch def /h tf ti sub N div def /t ti def [ N 1 add { pars t f % [[x y][x' y']] 0 get % [x y] /t t h add def } repeat ] end } def % a dpolygon is an array of pairs [[x y][(dt/3)x' (dt/3)y']] % pars /f ti tf N => the dpolygon of length (N+1) /parametrization-to-dpolygon { 8 dict begin /N exch def /tf exch def /t exch def /f exch cvx def /pars exch def /h tf t sub N div def /h3 h 3 div def % h = dt [ N 1 add { /u pars t f % [[x y][x' y']] def u 1 get % [x' y'] 0 2 copy % [x' y'] 0 [x' y'] 0 get h3 mul % [x' y'] 0 hx' put % u = [hx' y'] u 1 get % [hx' y'] 1 2 copy % [hx' y'] 1 [hx' y'] 1 get h3 mul % [hx' y'] 1 hy' put % u = [hx' hy'] u /t t h add def } repeat ] end } def % pars /f ti tf N => an array [[x0 y0] + N sets [x1 y1 x2 y2 x3 y3]] /parametrization-to-bezier { 8 dict begin /N exch def /tf exch def /ti exch def /f exch cvx def /pars exch def /h tf ti sub N div def /h3 h 3 div def /t ti def [ /F pars t f def % [[x y][x' y']] F 0 get N { [ F 0 get 0 get F 1 get 0 get h3 mul add F 0 get 1 get F 1 get 1 get h3 mul add /t t h add def /F pars t f def % [[x y][x' y']] F 0 get 0 get F 1 get 0 get h3 mul sub F 0 get 1 get F 1 get 1 get h3 mul sub F 0 get 0 get F 0 get 1 get ] } repeat ] end } def % [p0 [. . . . . .] ... ] /bezier-to-path { mkpathDict begin 4 dict begin /p exch def /N p length 1 sub def p 0 get aload pop thereisacurrentpoint { lineto } { moveto } ifelse 1 1 N { /i exch def p i get aload pop curveto } for end % local dict end % mkpath dict } def % [[x y] ... ] % must be of length > 0 /polygon-to-path { mkpathDict begin 4 dict begin /p exch def /N p length def p 0 get aload pop thereisacurrentpoint { lineto } { moveto } ifelse 1 1 N { /i exch def p i get aload pop lineto } for end % local dict end % mkpath dict } def % [[[x y][x' y']] ... ] /dpolygon-to-path { mkpathDict begin 6 dict begin /p exch def /N p length 1 sub def p 0 get dup /x exch 0 get def /t exch 1 get def x aload pop thereisacurrentpoint { lineto } { moveto } ifelse 1 1 N { /i exch def x 0 get t 0 get add x 1 get t 1 get add p i get dup /x exch 0 get def /t exch 1 get def x 0 get t 0 get sub x 1 get t 1 get sub x 0 get x 1 get curveto } for end % local dict end % mkpath dict } def