340 lines
8.9 KiB
Text
340 lines
8.9 KiB
Text
|
% solarized color scheme
|
||
|
color baseZeroThree, baseZeroTwo, baseZeroOne, baseZeroZero
|
||
|
, baseZero, baseOne, baseTwo, baseThree, yellow, orange
|
||
|
, red, magenta, violet, blue, cyan, green;
|
||
|
baseZeroThree :=(0.0 ,0.168627450980392,0.211764705882353);
|
||
|
baseZeroTwo :=(0.0274509803921569,0.211764705882353,0.258823529411765);
|
||
|
baseZeroOne :=(0.345098039215686 ,0.431372549019608,0.458823529411765);
|
||
|
baseZeroZero :=(0.396078431372549 ,0.482352941176471,0.513725490196078);
|
||
|
baseZero :=(0.513725490196078 ,0.580392156862745,0.588235294117647);
|
||
|
baseOne :=(0.576470588235294 ,0.631372549019608,0.631372549019608);
|
||
|
baseTwo :=(0.933333333333333 ,0.909803921568627,0.835294117647059);
|
||
|
baseThree :=(0.992156862745098 ,0.964705882352941,0.890196078431372);
|
||
|
yellow :=(0.709803921568627 ,0.537254901960784,0.0);
|
||
|
orange :=(0.796078431372549 ,0.294117647058824,0.0862745098039216);
|
||
|
red :=(0.862745098039216 ,0.196078431372549,0.184313725490196);
|
||
|
magenta :=(0.827450980392157 ,0.211764705882353,0.509803921568627);
|
||
|
violet :=(0.423529411764706 ,0.443137254901961,0.768627450980392);
|
||
|
blue :=(0.149019607843137 ,0.545098039215686,0.823529411764706);
|
||
|
cyan :=(0.164705882352941 ,0.631372549019608,0.596078431372549);
|
||
|
green :=(0.52156862745098 ,0.6 ,0.0);
|
||
|
|
||
|
|
||
|
%%%%%%%%%%%%%%%%%%%%
|
||
|
% Automata drawing %
|
||
|
%%%%%%%%%%%%%%%%%%%%
|
||
|
u:=.5cm; % unity
|
||
|
gu:=5u; % distance between states
|
||
|
nodesize := u; %size of a node
|
||
|
nodespace := u+.1cm; %size of a node
|
||
|
|
||
|
def resize(expr nu)=
|
||
|
u:=nu;
|
||
|
gu:=5u; % distance between states
|
||
|
nodesize := u; %size of a node
|
||
|
nodespace := u+.1cm; %size of a node
|
||
|
enddef;
|
||
|
|
||
|
% return the middle of a path
|
||
|
vardef midpoint(expr p)=
|
||
|
save r; pair r;
|
||
|
r:=point 1/2length(p) of p;
|
||
|
r
|
||
|
enddef;
|
||
|
|
||
|
% shorten a path of length d at the beginning and the end
|
||
|
vardef shorten(expr p,d) =
|
||
|
save q,bcirc,ecirc;
|
||
|
path q,bcirc,ecirc;
|
||
|
bcirc := fullcircle scaled d shifted point 0 of p;
|
||
|
ecirc := fullcircle scaled d shifted point length(p) of p;
|
||
|
q := p cutbefore bcirc cutafter ecirc;
|
||
|
q
|
||
|
enddef;
|
||
|
|
||
|
% Return a rounded box around top left and bottom right point.
|
||
|
vardef block(expr tl,br) =
|
||
|
save p;
|
||
|
save d,shift;
|
||
|
save topleft,bottomright;
|
||
|
save tll,tlt,trt,trr,brr,brb,blb,bll;
|
||
|
path p;
|
||
|
numeric d,shift;
|
||
|
d := 1/3u;
|
||
|
shift := 1.2u;
|
||
|
pair topleft,bottomright;
|
||
|
topleft := tl shifted (-shift,2shift);
|
||
|
bottomright := br shifted (shift,-.5shift);
|
||
|
pair tll,tlt,trt,trr,brr,brb,blb,bll;
|
||
|
tll := topleft shifted (-d,0);
|
||
|
tlt := topleft shifted (0,d);
|
||
|
trt := (xpart bottomright, ypart topleft) shifted (0,d);
|
||
|
trr := (xpart bottomright, ypart topleft) shifted (d,0);
|
||
|
brr := bottomright shifted (d,0);
|
||
|
brb := bottomright shifted (0,-d);
|
||
|
blb := (xpart topleft, ypart bottomright) shifted (0,-d);
|
||
|
bll := (xpart topleft, ypart bottomright) shifted (-d,0);
|
||
|
p:=tlt---trt..trr---brr..brb---blb..bll---tll..cycle;
|
||
|
p
|
||
|
enddef;
|
||
|
|
||
|
% b being the path of the block
|
||
|
vardef blockLabelPosition(expr b)=
|
||
|
save pos;
|
||
|
pair pos;
|
||
|
pos := point 0.5 of b;
|
||
|
pos
|
||
|
enddef;
|
||
|
|
||
|
% draw a block with the right math-mode tex label on top of it
|
||
|
def drawblock(expr topleftpoint, bottomrightpoint, l)=
|
||
|
save b,pos;
|
||
|
path b;
|
||
|
b:=block(topleftpoint,bottomrightpoint);
|
||
|
pair pos;
|
||
|
pos := blockLabelPosition(b);
|
||
|
draw b withcolor base01;
|
||
|
label.top(TEX("$"&l&"$"),pos);
|
||
|
enddef;
|
||
|
|
||
|
% -- Generic private functions
|
||
|
|
||
|
% return the edge between points A and B.
|
||
|
% out angle from A is inan
|
||
|
% in angle to B is outan
|
||
|
% nodesize is the size of the node
|
||
|
vardef edgeFull(expr posA,posB,inan,outan) =
|
||
|
save sub,s;
|
||
|
path sub,s;
|
||
|
s := posA {dir inan} .. {dir outan} posB ;
|
||
|
sub := shorten(s,nodespace);
|
||
|
sub
|
||
|
enddef;
|
||
|
|
||
|
% return a picture of the label l for edge e
|
||
|
vardef edgeLabel(expr e,l) =
|
||
|
save ret,mid,an,lab,height,width;
|
||
|
picture ret;
|
||
|
pair mid;
|
||
|
mid := midpoint(e);
|
||
|
numeric an;
|
||
|
an := angle (direction 1/2length(e) of e);
|
||
|
picture lab;
|
||
|
pair height,width;
|
||
|
lab:=thelabel(TEX("$"&l&"$"),origin);
|
||
|
height:=(0,ypart (ulcorner lab - llcorner lab));
|
||
|
width:=(xpart (urcorner lab - ulcorner lab),0);
|
||
|
if (an>-35) and (an<35):
|
||
|
ret:=lab shifted height rotated an shifted mid;
|
||
|
elseif (an>145) or (an<-145):
|
||
|
ret:=lab shifted height rotated (an+180) shifted mid;
|
||
|
elseif (an>75) and (an<120):
|
||
|
ret:=lab shifted mid shifted -width;
|
||
|
elseif (an>-120) and (an<-75):
|
||
|
ret:=lab shifted mid shifted width;
|
||
|
else:
|
||
|
ret:=lab shifted mid shifted height;
|
||
|
fi;
|
||
|
ret
|
||
|
enddef;
|
||
|
|
||
|
|
||
|
|
||
|
% --- LABELED GRAPHS ---
|
||
|
% return the edge between points A and B.
|
||
|
% out angle from A is an + angle from A to B
|
||
|
vardef edgeAngle(expr posA,posB,an) =
|
||
|
save res,d;
|
||
|
path res;
|
||
|
numeric d;
|
||
|
d := angle(posB-posA);
|
||
|
res := edgeFull(posA,posB,d+an,d-an);
|
||
|
res
|
||
|
enddef;
|
||
|
|
||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
%% %%
|
||
|
%% LOOPS %%
|
||
|
%% %%
|
||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
vardef dist(expr a,b)=
|
||
|
save width,height,res;
|
||
|
numeric width,height,res;
|
||
|
width:=xpart b - xpart a;
|
||
|
height:=ypart b - ypart a;
|
||
|
res:=sqrt(width*width + height*height);
|
||
|
enddef;
|
||
|
% return a loop
|
||
|
vardef loopFull(expr a,b,an) =
|
||
|
save ba,ea;
|
||
|
save circ,p,s;
|
||
|
pair ba,ea;
|
||
|
path circ,p,s;
|
||
|
p:=a{1,1}..b..{1,-1}cycle;
|
||
|
circ:= fullcircle scaled nodespace shifted a;
|
||
|
ba = circ intersectionpoint (subpath (0,1) of p);
|
||
|
ea = circ intersectionpoint (subpath (1,2) of p);
|
||
|
s:= ba{1,1}..b..{1,-1}ea;
|
||
|
s shifted -a rotated an shifted a
|
||
|
enddef;
|
||
|
|
||
|
vardef loopPoint(expr a,b) =
|
||
|
loopFull(a,b,0)
|
||
|
enddef;
|
||
|
|
||
|
vardef loopAngle(expr a,an) =
|
||
|
loopFull(a,a shifted (0,nodesize),an)
|
||
|
enddef;
|
||
|
|
||
|
vardef loop(expr a) =
|
||
|
loopFull(a,a shifted (0,nodesize),0)
|
||
|
enddef;
|
||
|
|
||
|
% return the direct edge between A and B
|
||
|
vardef edge(expr posA,posB) =
|
||
|
save an;
|
||
|
save sub;
|
||
|
numeric an;
|
||
|
path sub;
|
||
|
if (posA = posB):
|
||
|
sub := loop(posA);
|
||
|
else:
|
||
|
an := angle(posB-posA);
|
||
|
sub := edgeFull(posA,posB,an,an);
|
||
|
fi
|
||
|
sub
|
||
|
enddef;
|
||
|
|
||
|
def drawLoopPoint(expr a,b,l) =
|
||
|
begingroup;
|
||
|
save s;
|
||
|
path s;
|
||
|
s:=loopPoint(a,b);
|
||
|
drawarrow s;
|
||
|
label.top(TEX("$"&l&"$"),midpoint(s));
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
def drawLoop(expr a,l) =
|
||
|
begingroup;
|
||
|
save s;
|
||
|
path s;
|
||
|
s:=loop(a);
|
||
|
drawarrow s;
|
||
|
label.top(TEX("$"&l&"$"),midpoint(s));
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
|
||
|
def drawstate(expr pos) =
|
||
|
draw pos withpen pencircle scaled 4bp;
|
||
|
enddef;
|
||
|
|
||
|
% draw some state with some label insize
|
||
|
def drawState(expr pos,l) =
|
||
|
begingroup;
|
||
|
save lab,reslab;
|
||
|
save height,width;
|
||
|
save size;
|
||
|
% Draw the circle
|
||
|
draw fullcircle scaled nodesize shifted pos;
|
||
|
|
||
|
% Draw the label with the right size
|
||
|
picture lab,reslab;
|
||
|
numeric height,width;
|
||
|
numeric size;
|
||
|
lab=thelabel(TEX("$"&l&"$"),origin);
|
||
|
height:=ypart (ulcorner lab - llcorner lab);
|
||
|
width :=xpart (urcorner lab - ulcorner lab);
|
||
|
size := sqrt(height*height + width*width);
|
||
|
if size>.9nodesize:
|
||
|
reslab:=lab scaled (.9nodesize/size) shifted pos;
|
||
|
else:
|
||
|
reslab:=lab shifted pos;
|
||
|
fi
|
||
|
% help for debug to draw boundaries
|
||
|
% draw ulcorner reslab -- urcorner reslab -- lrcorner reslab -- llcorner reslab -- cycle;
|
||
|
draw reslab;
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
|
||
|
% draw an edge
|
||
|
def drawEdgeFull(expr posA,posB,l,inan,outan) =
|
||
|
begingroup;
|
||
|
save sub;
|
||
|
path sub;
|
||
|
sub := edgeFull(posA,posB,inan,outan);
|
||
|
drawarrow sub;
|
||
|
draw edgeLabel(sub,l);
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
|
||
|
def drawEdgeAngle(expr posA,posB,l,inan) =
|
||
|
begingroup;
|
||
|
save sub;
|
||
|
path sub;
|
||
|
sub := edgeAngle(posA,posB,inan);
|
||
|
drawarrow sub;
|
||
|
draw edgeLabel(sub,l);
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
|
||
|
def drawEdge(expr posA,posB,l) =
|
||
|
begingroup;
|
||
|
save sub;
|
||
|
path sub;
|
||
|
sub := edge(posA,posB);
|
||
|
drawarrow sub;
|
||
|
draw edgeLabel(sub,l);
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
|
||
|
vardef box(expr posA) =
|
||
|
save b,size;
|
||
|
path b;
|
||
|
numeric size;
|
||
|
size:=2nodesize;
|
||
|
b := unitsquare scaled size shifted posA shifted (-.5size,-.5size);
|
||
|
b
|
||
|
enddef;
|
||
|
|
||
|
def drawbox(expr posA,l) =
|
||
|
begingroup;
|
||
|
save b,pos;
|
||
|
path b;
|
||
|
pair pos;
|
||
|
b:=box(posA);
|
||
|
draw b;
|
||
|
pos=point 3 of b;
|
||
|
label.lrt(TEX("$"&l&"$"),pos);
|
||
|
endgroup;
|
||
|
enddef;
|
||
|
|
||
|
prologues:=3;
|
||
|
|
||
|
verbatimtex
|
||
|
%&latex
|
||
|
\documentclass{minimal}
|
||
|
\begin{document}
|
||
|
etex
|
||
|
|
||
|
% TEX macro is short enough to be copied
|
||
|
string preverbatimtex_, postverbatimtex_;
|
||
|
|
||
|
vardef TEXPRE text s = preverbatimtex_ := s; enddef;
|
||
|
|
||
|
vardef TEXPOST text s = postverbatimtex_ := s; enddef;
|
||
|
|
||
|
vardef TEX primary s =
|
||
|
if known preverbatimtex_:
|
||
|
write "verbatimtex "&preverbatimtex_&" etex" to "mptextmp.mp";
|
||
|
fi
|
||
|
write "btex "&s&" etex" to "mptextmp.mp";
|
||
|
if known postverbatimtex_:
|
||
|
write "verbatimtex "&postverbatimtex_&" etex" to "mptextmp.mp";
|
||
|
fi
|
||
|
write EOF to "mptextmp.mp";
|
||
|
scantokens "input mptextmp"
|
||
|
enddef;
|
||
|
|
||
|
TEXPRE("\documentclass{minimal}\begin{document}");
|
||
|
TEXPOST("\end{document}");
|