%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Metapost -*- %%%%%%%%%%%%%%%%%%%%%%%%%%% %% aaobj.mp -- Draw objects, bindings, interfaces and such in MetaPost %% %% Author : Anders Andersen %% Created On : Fri Feb 27 23:34:01 1998 %% Last Modified By: Anders Andersen %% Last Modified On: Sun Jan 6 00:35:45 2002 %% 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 % Lengths and withs relative to rad vardef iflength = .75 enddef; % Length of interfaces vardef ifwidth = 1.1 enddef; % Width of interfaces vardef ifspace = .3 enddef; % Space between two connected interfaces vardef odistance = 2 + 2iflength + ifspace enddef; % Distance b. objects % Used to draw bindings (and objects): '+a b+` vardef halfbinding@#(expr apos, bpos, rad) = save v, pos; numeric v; pair pos[]; v:=anglebetween(apos, bpos); if str @# = "inv": v:=v+180; fi pos0:=(apos+(-rad,0)) rotatedaround(apos, v); pos1:=(apos+(0,rad)) rotatedaround(apos, v); pos2:=(bpos+(0,rad)) rotatedaround(bpos, v); pos3:=(bpos+(rad,0)) rotatedaround(bpos, v); pos0{dir (90+v)}..pos1{dir v}--pos2{dir v}..pos3{dir (270+v)} enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Interfaces: pos = apos = position of object, bpos = position of other object, % rad = radius of object (suffix = direction of interface, default top) % An interface path: (+)-| vardef theif@#(expr pos, rad) = save T; transform T; if str @# = "ulft": T = identity rotatedaround(pos, 45); elseif str @# = "lft": T = identity rotatedaround(pos, 90); elseif str @# = "llft": T = identity rotatedaround(pos, 135); elseif str @# = "bot": T = identity rotatedaround(pos, 180); elseif str @# = "lrt": T = identity rotatedaround(pos, 225); elseif str @# = "rt": T = identity rotatedaround(pos, 270); elseif str @# = "urt": T = identity rotatedaround(pos, 315); else: T = identity; fi (pos+(0,rad)--pos+(0,rad+iflength*rad)-- pos+(-.5ifwidth*rad,rad+iflength*rad)-- pos+(.5ifwidth*rad,rad+iflength*rad)-- pos+(0,rad+iflength*rad)--pos+(0,rad)) transformed T enddef; % An interface from-to path: (+)-| + vardef theiffromto(expr apos, bpos, rad) = theif.rt(apos, rad) rotatedaround(apos, anglebetween(apos, bpos)) enddef; % An interface: (+)-| vardef anif@#(expr pos, rad) = save T, q; transform T; picture q; if str @# = "ulft": T = identity rotatedaround(pos, 45); elseif str @# = "lft": T = identity rotatedaround(pos, 90); elseif str @# = "llft": T = identity rotatedaround(pos, 135); elseif str @# = "bot": T = identity rotatedaround(pos, 180); elseif str @# = "lrt": T = identity rotatedaround(pos, 225); elseif str @# = "rt": T = identity rotatedaround(pos, 270); elseif str @# = "urt": T = identity rotatedaround(pos, 315); else: T = identity; fi q:=nullpicture; addto q doublepath pos+(0,rad)--pos+(0,rad+iflength*rad) withpen currentpen; addto q doublepath pos+(-.5ifwidth*rad,rad+iflength*rad)-- pos+(.5ifwidth*rad,rad+iflength*rad) withpen currentpen; q transformed T enddef; % An interface from-to: (+)-| + vardef aniffromto(expr apos, bpos, rad) = anif.rt(apos, rad) rotatedaround(apos, anglebetween(apos, bpos)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Binding from-to (+a b+): apos = start of binding, bpos = end of binding, % rad = radius (suffix = color) % Path vardef thebindingfromto(expr apos, bpos, rad) = if apos=bpos: halfbinding(apos, bpos, rad)--halfbinding.inv(bpos, apos, rad)--cycle else: halfbinding(apos, bpos, rad)--halfbinding(bpos, apos, rad)--cycle fi enddef; % Fill vardef fillbindingfromto(expr apos, bpos, rad, col) = fillpath(thebindingfromto(apos, bpos, rad), col) enddef; % vardef bindingfromto@#(expr apos, bpos, rad) = pathwithfill@#(thebindingfromto(apos, bpos, rad)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Binding ( + ): pos = center of binding, rad = radius, length = length of % binding (suffix = color) % Path vardef thebinding(expr pos, rad, length) = thebindingfromto(pos-(.5length-rad,0), pos+(.5length-rad,0), rad) enddef; % Fill vardef fillbinding(expr pos, rad, length, col) = fillpath(thebinding(pos, rad, length), col) enddef; % Path and optional fill vardef binding@#(expr pos, rad, length) = pathwithfill@#(thebinding(pos, rad, length)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Binding between a+ |-( )-| +b: apos = object connected to, bpos = object % connected to, rad = radius (suffix = color) % Path vardef thebindingbetween(expr apos, bpos, rad) = save a, b, v; numeric v; pair a, b; v:=anglebetween(apos, bpos); a:=(apos+(2rad+2iflength*rad+ifspace*rad,0)) rotatedaround(apos, v); b:=(bpos-(2rad+2iflength*rad+ifspace*rad,0)) rotatedaround(bpos, v); if a=b: (theif.lft(a, rad) rotatedaround(a, v))--halfbinding(a, b, rad)-- (theif.rt(b, rad) rotatedaround(b, v))--halfbinding.inv(b, a, rad)--cycle else: (theif.lft(a, rad) rotatedaround(a, v))--halfbinding(a, b, rad)-- (theif.rt(b, rad) rotatedaround(b, v))--halfbinding(b, a, rad)--cycle fi enddef; % Fill vardef fillbindingbetween(expr apos, bpos, rad, col) = fillpath(thebindingbetween(apos, bpos, rad), col) enddef; % Path and optional fill vardef bindingbetween@#(expr apos, bpos, rad) = save a, b, v, q; numeric v; pair a, b; picture q; v:=anglebetween(apos, bpos); a:=(apos+(2rad+2iflength*rad+ifspace*rad,0)) rotatedaround(apos, v); b:=(bpos-(2rad+2iflength*rad+ifspace*rad,0)) rotatedaround(bpos, v); if str @# <> "": q:=fillbindingbetween(apos, bpos, rad, @#); else: q:=nullpicture; fi if a=b: addto q doublepath halfbinding(a, b, rad)-- halfbinding.inv(b, a, rad)--cycle withpen currentpen; addto q also (anif.lft(a, rad) rotatedaround(a, v)); addto q also (anif.rt(b, rad) rotatedaround(b, v)); else: addto q doublepath halfbinding(a, b, rad)-- halfbinding(b, a, rad)--cycle withpen currentpen; addto q also (anif.lft(a, rad) rotatedaround(a, v)); addto q also (anif.rt(b, rad) rotatedaround(b, v)); fi q enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Implicit bindings: vardef theimpbindingfromto(expr apos, bpos, rad) = save v; numeric v; v:=anglebetween(apos, bpos); (theif.lft(apos, rad) rotatedaround(apos,v))-- (theif.rt(bpos, rad) rotatedaround(bpos,v)) enddef; vardef theimpbinding(expr pos, rad, length) = theimpbindingfromto(pos-(.5length-rad,0), pos+(.5length-rad,0), rad) enddef; % make picture version of this: animpbindingbetween!!! vardef theimpbindingbetween(expr apos, bpos, rad) = save a, b, v; numeric v; pair a, b; v:=anglebetween(apos, bpos); a:=(apos+(2rad+2iflength*rad+ifspace*rad,0)) rotatedaround(apos, v); b:=(bpos-(2rad+2iflength*rad+ifspace*rad,0)) rotatedaround(bpos, v); (theif.lft(a, rad) rotatedaround(a,v))--(theif.rt(b, rad) rotatedaround(b,v)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % An object (+): pos = position of object, rad = radius of object % Path vardef theobject(expr pos, rad) = halfbinding(pos, pos, rad)--halfbinding.inv(pos, pos, rad)--cycle enddef; % Fill vardef fillobject(expr pos, rad, col) = fillpath(theobject(pos, rad), col) enddef; % Path and optional fill vardef object@#(expr pos, rad) = pathwithfill@#(theobject(pos, rad)) enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Binding marks (types) % An operational binding mark vardef opbindingmark@#(expr pos, rad) = save v, q; numeric v; picture q; if str @# <> "": v:=@#; else: v:=0; fi q:= arrow((pos+(-.5rad,.25rad)--pos+(.5rad,.25rad)) rotatedaround(pos, v)); addto q also arrow((pos+(.5rad,-.25rad)--pos+(-.5rad,-.25rad)) rotatedaround(pos, v)); q enddef; vardef invopbindingmark@#(expr pos, rad) = save v, q; numeric v; picture q; if str @# <> "": v:=@#; else: v:=0; fi q:= arrow((pos+(.5rad,.25rad)--pos+(-.5rad,.25rad)) rotatedaround(pos, v)); addto q also arrow((pos+(-.5rad,-.25rad)--pos+(.5rad,-.25rad)) rotatedaround(pos, v)); q enddef; % An signal binding mark vardef sigbindingmark@#(expr pos, rad) = save v; numeric v; if str @# <> "": v:=@#; else: v:=0; fi arrow((pos+(-.5rad,-.1rad)--pos+(-.2rad,.2rad)-- pos+(.2rad,-.2rad)--pos+(.6rad,.2rad)) rotatedaround(pos, v)) enddef; vardef invsigbindingmark@#(expr pos, rad) = save v; numeric v; if str @# <> "": v:=@#; else: v:=0; fi arrow((pos+(.5rad,-.1rad)--pos+(.2rad,.2rad)-- pos+(-.2rad,-.2rad)--pos+(-.6rad,.2rad)) rotatedaround(pos, v)) enddef; % An stream binding mark vardef streambindingmark@#(expr pos, rad) = save v; numeric v; if str @# <> "": v:=@#; else: v:=0; fi arrow((pos+(-.5rad,-.1rad){up}..pos+(-.2rad,.2rad).. pos+(.2rad,-.2rad)..{up}pos+(.6rad,.2rad)) rotatedaround(pos, v)) enddef; vardef invstreambindingmark@#(expr pos, rad) = save v; numeric v; if str @# <> "": v:=@#; else: v:=0; fi arrow((pos+(.5rad,-.1rad){up}..pos+(.2rad,.2rad).. pos+(-.2rad,-.2rad)..{up}pos+(-.6rad,.2rad)) rotatedaround(pos, v)) enddef;