%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Metapost -*- %%%%%%%%%%%%%%%%%%%%%%%%%%% %% aamisc.mp -- Misc MetaPost macros. %% %% Author : Anders Andersen %% Created On : Wed Feb 17 15:14:19 1999 %% Last Modified By: Anders Andersen %% Last Modified On: Tue Dec 11 18:56:14 2001 %% Status : Unknown, Use with caution! %% %% Unless other notices are present in any part of this file explicitly %% claiming copyrights for other people and/or organisations, the contents %% of this file is fully copyright (C) 1999 Anders Andersen, all rights %% reserved. %% %% Permission is granted to make and distribute verbatim copies of this %% document provided that the copyright notice and this permission notice %% are preserved on all copies. %% %% Permission is granted to copy and distribute modified versions of this %% document under the conditions for verbatim copying, provided that the %% entire resulting derived work is distributed under the terms of a %% permission notice identical to this one. %% %% If any other present copyright notices interfere with the copyright %% claims above, these claims may be partially overruled by those notices. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Help values and functions % Calculate the angle between apos and bpos vardef anglebetween(expr apos, bpos) = save v; numeric v; if apos=bpos: v:=0; else: v:=angle((xpart bpos)-(xpart apos),(ypart bpos)-(ypart apos)); fi v enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Fillings % Fill a path with color in suffix vardef fillpath(expr p, col) = save q; picture q; q:=nullpicture; addto q contour p withcolor col; q enddef; % Draw a path and optionally fill it (if suffix is not empty) vardef pathwithfill@#(expr p) = save q; if str @# <> "": picture q; q:=fillpath(p, @#); addto q doublepath p withpen currentpen; q else: p fi enddef; % Fill with changing color vardef fillcolor(expr p, nc, astart, astop, bstart, bstop, cstart, cstop) = save da, db, ac; pair da, db; path ac; da:=(((xpart astop)-(xpart astart))/nc,((ypart astop)-(ypart astart))/nc); db:=(((xpart bstop)-(xpart bstart))/nc,((ypart bstop)-(ypart bstart))/nc); ac:=buildcycle(p, (astart+0.01*da)--(bstart+0.01*db)); fill ac withcolor (0/nc)[cstart,cstop]; for i=1 upto nc-1: ac:=buildcycle(p, (astart+i*da)--(bstart+i*db)); fill ac withcolor (i/nc)[cstart,cstop]; endfor ac:=buildcycle(p, (astart+(nc-0.01)*da)--(bstart+(nc-0.01)*db)); fill ac withcolor (nc/nc)[cstart,cstop]; enddef; % For debugging of fillcolor vardef fillxcolor(expr p, nc, astart, astop, bstart, bstop, cstart, cstop) = save da, db, ac; pair da, db; path ac; draw p; draw astart--astop; draw bstart--bstop; da:=(((xpart astop)-(xpart astart))/nc,((ypart astop)-(ypart astart))/nc); db:=(((xpart bstop)-(xpart bstart))/nc,((ypart bstop)-(ypart bstart))/nc); for i=0 upto nc: draw (astart+i*da)--(bstart+i*db) withcolor red; endfor enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % A rectangle: pos = lower-left corner, x = width, y = height (suffix = color) % Path vardef therectangle(expr pos, x, y) = pos--pos+(0,y)--pos+(x,y)--pos+(x,0)--cycle enddef; % Fill vardef fillrectangle(expr pos, x, y, col) = fillpath(therectangle(pos, x, y), col) enddef; % Path and optional fill vardef rectangle@#(expr pos, x, y) = pathwithfill@#(therectangle(pos, x, y)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % A center rectangle: pos = center, x = width, y = height (suffix = color) % Path vardef thecrectangle(expr pos, x, y) = therectangle(pos-(.5x,.5y), x, y) enddef; % Fill vardef fillcrectangle(expr pos, x, y, col) = fillpath(thecrectangle(pos, x, y), col) enddef; % Path and optional fill vardef crectangle@#(expr pos, x, y) = pathwithfill@#(thecrectangle(pos, x, y)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % A rectangle with round corners % Path vardef theroundrec(expr pos, x, y, d) = pos+(d,0){left}..{up}pos+(0,d)--pos+(0,y-d){up}..{right}pos+(d,y)-- pos+(x-d,y){right}..{down}pos+(x,y-d)--pos+(x,d){down}..{left}pos+(x-d,0)-- cycle enddef; % Fill vardef fillroundrec(expr pos, x, y, d, col) = fillpath(theroundrec(pos, x, y, d), col) enddef; % Path and optional fill vardef roundrec@#(expr pos, x, y, d) = pathwithfill@#(theroundrec(pos, x, y, d)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % A center rectangle with round corners % Path vardef thecroundrec(expr pos, x, y, d) = theroundrec(pos-(.5x,.5y), x, y, d) enddef; % Fill vardef fillcroundrec(expr pos, x, y, d, col) = fillpath(thecroundrec(pos, x, y, d), col) enddef; % Path and optional fill vardef croundrec@#(expr pos, x, y, d) = pathwithfill@#(thecroundrec(pos, x, y, d)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Methods and attributes vardef method@#(expr name, pos, x, ny, dy) = save q, i; picture q; numeric i; q:=pathwithfill@#(therectangle(pos, x, ny*dy)); if picture name: addto q also thelabel.top(name, pos+(.5x, ny*dy-.5mm)); elseif name <> "": addto q also thelabel.top(name, pos+(.5x, ny*dy-.5mm)); fi for i=1 upto (ny-1): addto q doublepath pos+(1mm,i*dy)--pos+(x-1mm,i*dy) withpen currentpen; endfor; q enddef; vardef cmethod@#(expr name, pos, x, ny, dy) = method@#(name, pos-(x/2,(ny*dy)/2), x, ny, dy) enddef; vardef attr@#(expr name, pos, rad) = save q; picture q; q:=pathwithfill@#(fullcircle scaled 2rad shifted pos); if picture name: addto q also thelabel.top(name, pos+(0,rad-.5mm)); elseif name <> "": addto q also thelabel.top(name, pos+(0,rad-.5mm)); fi q enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Buffers and threads vardef buffers@#(expr name, pos, x, ny, dy) = save q, i; picture q; numeric i; q:=nullpicture; for i=0 upto (ny-1): addto q also pathwithfill@#(therectangle(pos+(0,i*(5/3)*dy), x, dy)); endfor; if picture name: addto q also thelabel.top(name, pos+(.5x, ny*dy+(ny-1)*(2/3)*dy-.5mm)); elseif name <> "": addto q also thelabel.top(name, pos+(.5x, ny*dy+(ny-1)*(2/3)*dy-.5mm)); fi q enddef; vardef thethread(expr pos, len, d) = pos+(.3d,len){dir 180}.. pos+(-.3d,.85len).. pos+(.2d,.70len).. pos+(-.2d,.55len).. pos+(.2d,.4len).. pos+(-.2d,.25len).. pos+(.1d,.1len).. pos+(-.1d,0) enddef; vardef threads@#(expr name, pos, nx, dx, y) = save q, i; picture q; numeric i; q:=roundrec@#(pos, (nx+1)*dx, y, .125y); for i=1 upto nx: addto q doublepath thethread(pos+(i*dx,.125y), .75y, dx) withpen currentpen; endfor; if picture name: addto q also thelabel.top(name, pos+((nx+1)*.5dx, y-.5mm)); elseif name <> "": addto q also thelabel.top(name, pos+((nx+1)*.5dx, y-.5mm)); fi q enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Que vardef que@#(expr name, pos, nx, dx, y) = save q, i; picture q; numeric i; q:=nullpicture; for i=0 upto (nx-1): addto q also rectangle@#(pos+(i*dx,0), dx, y); endfor; addto q doublepath pos+((nx+1)*dx,0)--pos--pos+(0,y)--pos+((nx+1)*dx,y) withpen currentpen; if picture name: addto q also thelabel.top(name, pos+((nx+1)*.5dx, y-.5mm)); elseif name <> "": addto q also thelabel.top(name, pos+((nx+1)*.5dx, y-.5mm)); fi q enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Lines and arrows vardef dirline(expr apos, adir, bdir, bpos) = apos{dir adir}..{dir bdir}bpos enddef; vardef ddirline(expr apos, adir, bdir, bpos, d) = save a, b; pair a, b; a:=(apos+(d,0)) rotatedaround(apos, adir); b:=(bpos+(d,0)) rotatedaround(bpos, bdir-180); dirline(a, adir, bdir, b) enddef; vardef arrow@#(expr p) = save q; picture q; q:=nullpicture; addto q doublepath p withpen currentpen; if str @# <> "": addto q also pathwithfill@#(arrowhead(p)); else: addto q also pathwithfill.black(arrowhead(p)); fi q enddef; vardef darrow@#(expr apos, bpos, d) = save v; numeric v; v:=anglebetween(apos, bpos); arrow@#(ddirline(apos, v, v, bpos, d)) enddef; vardef dirarrow@#(expr apos, adir, bdir, bpos) = arrow@#(dirline(apos, adir, bdir, bpos)) enddef; vardef ddirarrow@#(expr apos, adir, bdir, bpos, d) = arrow@#(ddirline(apos, adir, bdir, bpos, d)) enddef; vardef dblarrow@#(expr p) = save q; picture q; q:=nullpicture; addto q doublepath p withpen currentpen; if str @# <> "": addto q also pathwithfill@#(arrowhead(p)); addto q also pathwithfill@#(arrowhead(reverse p)); else: addto q also pathwithfill.black(arrowhead(p)); addto q also pathwithfill.black(arrowhead(reverse p)); fi q enddef; vardef ddblarrow@#(expr apos, bpos, d) = save v; numeric v; v:=anglebetween(apos, bpos); dblarrow@#(ddirline(apos, v, v, bpos, d)) enddef; vardef dirdblarrow@#(expr apos, adir, bdir, bpos) = dblarrow@#(dirline(apos, adir, bdir, bpos)) enddef; vardef ddirdblarrow@#(expr apos, adir, bdir, bpos, d) = dblarrow@#(ddirline(apos, adir, bdir, bpos, d)) enddef; vardef lengthmarker@#(expr name, apos, bpos) = save l, v, d, p; numeric l, v, d; l:=arclength(apos--bpos); v:=anglebetween(apos, bpos); d:=.1l; if d > 1mm: d:=1mm; elseif d < .5mm: d:=.5mm; fi if str @# = "inv": d:=-d; fi picture q; q:=nullpicture; addto q doublepath apos+(0,-d)--apos+(0,-2d)--apos+(l,-2d)--apos+(l,-d) withpen pencircle scaled 0.2pt; if picture name or (name <> ""): if str @# = "inv": addto q also thelabel.top(name, apos+(.5l,-2d)); else: addto q also thelabel.bot(name, apos+(.5l,-2d)); fi fi q rotatedaround(apos, v) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Loop and timed loop vardef loop(expr pos, rad) = save spos; pair spos; spos:=pos+(rad,0); arrow((spos rotatedaround(pos, 22.5)){dir 112.5}.. (spos rotatedaround(pos, 90)){dir 180}.. (spos rotatedaround(pos, 180)){dir 270}.. (spos rotatedaround(pos, 270)){dir 0}.. {dir 70}(spos rotatedaround(pos, 340))) enddef; vardef timedloop(expr pos, rad) = save q; picture q; q:=loop(pos, rad); addto q also attr.black("", pos, .2rad); addto q doublepath pos--((pos+(.8rad,0)) rotatedaround(pos, 135)) withpen currentpen; q enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Resources and managers vardef theresource(expr pos, size) = save s; numeric s; s:=.5size; pos+(-s,-s)--pos+(-2s,0)--pos+(-s,s)--pos+(s,s)--pos+(2s,0)--pos+(s,-s)--cycle enddef; vardef fillresource(expr pos, size, col) = fillpath(theresource(pos, size), col) enddef; vardef resource@#(expr pos, size) = pathwithfill@#(theresource(pos, size)) enddef; vardef themanager(expr pos, width, height) = thecroundrec(pos, width, height, .2height) enddef; vardef fillmanager(expr pos, widt, height, col) = fillpath(themanager(pos, width, height), col) enddef; vardef manager@#(expr pos, width, height) = pathwithfill@#(themanager(pos, width, height)) enddef; vardef provides@#(expr from, to, fsiz, tsiz) = save x, fy, ty; numeric x, fy, ty; x:=(xpart to)+3tsiz/8; fy:=(ypart from)+.5fsiz; ty:=(ypart to)-.5tsiz; arrow@#((x,fy)--(x,ty)) enddef; vardef providedby@#(expr from, to, fsiz, tsiz) = save x, fy, ty; numeric x, fy, ty; x:=(xpart from)-3tsiz/8; fy:=(ypart from)-.5fsiz; ty:=(ypart to)+.5tsiz; arrow@#((x,fy)--(x,ty)) enddef; vardef manages@#(expr from, to, fsiz, tsiz) = save x, fy, ty; numeric x, fy, ty; x:=(xpart to)-3tsiz/8; fy:=(ypart from)-.5fsiz; ty:=(ypart to)+.5tsiz; arrow@#((x,fy)--(x,ty)) enddef; vardef managedby@#(expr from, to, fsiz, tsiz) = save x, fy, ty; numeric x, fy, ty; x:=(xpart from)+3fsiz/8; fy:=(ypart from)+.5fsiz; ty:=(ypart to)-.5tsiz; arrow@#((x,fy)--(x,ty)) enddef;