summaryrefslogtreecommitdiff
path: root/graphics/metapost/contrib/macros/mptrees/mptrees.mp
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-04-09 03:01:12 +0000
committerNorbert Preining <norbert@preining.info>2024-04-09 03:01:12 +0000
commiteb49829734b61c8d5a80ff94393e6c28739ee969 (patch)
tree87679f1aec0811b1c50b768171e55e75d5e15def /graphics/metapost/contrib/macros/mptrees/mptrees.mp
parent23803b0f35b5b0020c2c03924a79ed79654b130f (diff)
CTAN sync 202404090301
Diffstat (limited to 'graphics/metapost/contrib/macros/mptrees/mptrees.mp')
-rw-r--r--graphics/metapost/contrib/macros/mptrees/mptrees.mp442
1 files changed, 270 insertions, 172 deletions
diff --git a/graphics/metapost/contrib/macros/mptrees/mptrees.mp b/graphics/metapost/contrib/macros/mptrees/mptrees.mp
index f31080b61c..eba564d665 100644
--- a/graphics/metapost/contrib/macros/mptrees/mptrees.mp
+++ b/graphics/metapost/contrib/macros/mptrees/mptrees.mp
@@ -2,10 +2,10 @@
%% mptrees.mp %%
%% Probability trees with MetaPost %%
%% o.peault@posteo.net %%
-%% Version 24.02 (February 2024) %%
+%% Version 24.04 (April 2024) %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string mptreesversion;
-mptreesversion:="24.02";
+mptreesversion:="24.04";
%
% This work may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, either version 1.3 of this license
@@ -13,6 +13,7 @@ mptreesversion:="24.02";
% license is in http://www.latex-project.org/lppl.txt
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
message "mptrees version " & mptreesversion;
if not known mplib: input latexmp fi;
@@ -41,7 +42,6 @@ numeric mpt_tmpdirtree;
% à la fin de begintree, on exécute deux fois mpt_tree
extra_endfig:="if mpt_begtr: mpt_tree currentpicture:=nullpicture; mpt_passe:=2; AdjustNodes; mpt_tree; mpt_begtr:=false;mpt_passe:=1 fi;" & extra_endfig;
-%extra_endfig:="if mpt_begtr: mpt_tree drawoptions(withcolor blue); mpt_passe:=2; AdjustNodes; mpt_tree; mpt_begtr:=false;mpt_passe:=1 fi;" & extra_endfig;
numeric posprob; % position de l'étiquette sur la branche
@@ -73,7 +73,7 @@ color linecolor;
linecolor:=black;
numeric nodelinewidth; % épaisseur de la ligne autour des noeuds
-nodelinewidth:=0.5bp;
+nodelinewidth:=-1; % change pour tree et graph
pair Orig_arbre[][]; % sommet de l'arbre i,j
Orig_arbre[1][1]:=origin;
@@ -166,7 +166,6 @@ vardef labelarbres(expr s)=
save p; picture p;
if picture s: p=s
elseif path s: p=image(draw s)
-% elseif string s: p=scantokens("btex" & s & "etex");
else: p=textext(s)
fi;
p
@@ -219,7 +218,7 @@ vardef superellipsebox(expr p)=
c=0.5[ulcorner l,llcorner l];
d=0.5[llcorner l,lrcorner l];
if (mpt_isgraph and (not naturalwidth) and (not mpt_isprob)):
- l:=superellipse(1/2 right, 1/2 up, 1/2 left, 1/2 down, .8);
+ l:=superellipse(1/2 right, 1/2 up, 1/2 left, 1/2 down, superellipseparam);
l:=l scaled nodewidth
elseif naturalwidth:
l:=superellipse(a,b,c,d,superellipseparam);
@@ -230,13 +229,6 @@ vardef superellipsebox(expr p)=
l
enddef;
-vardef supellformat(expr p,cl,cb,cf)=
-image(%
- if (cb<>white) or (mpt_bgc): fill superellipsebox(p) withcolor cb mpt_opbg_ fi;
- draw superellipsebox(p) withcolor cl withpen pencircle scaled nodelinewidth mpt_po_ ;
- if arbrebool or mpt_isprob: draw p withcolor cf mpt_po_ fi;
-)
-enddef;
% Circle
vardef circlebox(expr p)=
@@ -247,27 +239,13 @@ vardef circlebox(expr p)=
c:=0.5[a,b];
if (mpt_isgraph and (not naturalwidth) and (not mpt_isprob)):
fullcircle scaled nodewidth
- elseif naturalwidth:
+ elseif naturalwidth and (not mpt_isprob):
fullcircle scaled (abs(b-a)-2)
else:
fullcircle scaled (abs(b-a)-2) shifted c
fi
enddef;
-vardef circleformat(expr p,cl,cb,cf)=
-image(%
- if (cb<>white) or (mpt_isprobover) or (mpt_bgc): fill circlebox(p) withcolor cb mpt_opbg_ fi;
- draw circlebox(p) withcolor cl withpen pencircle scaled nodelinewidth mpt_po_;
- if arbrebool or mpt_isprob: draw p withcolor cf mpt_po_ fi;
-)
-enddef;
-
-vardef circleprobformat(expr p,cf)=
-image(%
- fill circlebox(p) withcolor background;
- draw p withcolor cf mpt_po_;
-)
-enddef;
% square
vardef squarebox(expr p)=
@@ -285,20 +263,45 @@ vardef squarebox(expr p)=
fi
enddef;
-vardef squareformat(expr p,cl,cb,cf)=
+
+
+
+
+
+vardef circleprobformat(expr p,cf)=
+image(%
+ myfill circlebox(p) withcolor background;
+ draw p withcolor cf _op_ mpt_po_;
+)
+enddef;
+
+
+
+
+
+vardef formatprobbox(expr p,cl,cb,cf)=
+image(%
+ if (cb<>white) or (mpt_isprobover) or (mpt_bgc): myfill probshape(p) withcolor cb mpt_opbg_ fi;
+ draw probshape(p) withcolor cl withpen pencircle scaled nodelinewidth mpt_po_;
+ if arbrebool or mpt_isprob: draw p withcolor cf mpt_po_ fi;
+)
+enddef;
+
+vardef formatnodebox(expr p,cl,cb,cf)=
+save pp;path pp;
+if mpt_isgraph: pp:= mpt_nodepath[num] shifted -mpt_nodecoord[num] else: pp:=nodeshape(p) fi;
image(%
- if (cb<>white) or (mpt_bgc): fill squarebox(p) withcolor cb mpt_opbg_ fi;
- draw squarebox(p) withcolor cl withpen pencircle scaled nodelinewidth mpt_po_;
- if arbrebool or mpt_isprob: draw p withcolor cf mpt_po_ fi;
+ if (cb<>white) or (mpt_isprobover) or (mpt_bgc): fill pp withcolor cb mpt_opbg_ fi;
+ draw pp withcolor cl withpen pencircle scaled nodelinewidth mpt_po_;
+ if arbrebool or mpt_isprob: draw p shifted (center pp-center p) withcolor cf mpt_po_ fi;
)
enddef;
-% bbox
-vardef bboxformat(expr p,cl,cb,cf)=
+vardef formatleavebox(expr p,cl,cb,cf)=
image(%
- if (cb<>white) or (mpt_bgc): fill bbox p withcolor cb mpt_opbg_ fi;
- draw bbox p withcolor cl withpen pencircle scaled nodelinewidth mpt_po_;
- if arbrebool or mpt_isprob: draw p withcolor cf mpt_po_ fi;
+ if (cb<>white) or (mpt_isprobover) or (mpt_bgc): fill leaveshape(p) withcolor cb mpt_opbg_ fi;
+ draw leaveshape(p) withcolor cl withpen pencircle scaled nodelinewidth mpt_po_;
+ if arbrebool or mpt_isprob: draw p withcolor cf mpt_po_ fi;
)
enddef;
@@ -312,69 +315,61 @@ probformat:="";
-
vardef formatprob(expr p)=
+save pp;path pp;
+pp:=probshape(p);
save cl,cb,cf;
color cl,cb,cf;
cl:=problinecolor;
cb:=probbgcolor;
cf:=probfgcolor;
- if probformat="superellipse":
- supellformat(p,cl,cb,cf)
- elseif probformat="circle":
- circleformat(p,cl,cb,cf)
- elseif probformat="square":
- squareformat(p,cl,cb,cf)
- elseif probformat="bbox":
- bboxformat(p,cl,cb,cf)
- elseif mpt_isprobover and (probformat=""):
- circleprobformat(p,cf)
- else:
+ if mpt_isprobover and (probformat="") and mpt_probsh_ori:
+ circleprobformat(p,cf)
+ elseif (probformat="") and mpt_probsh_ori:
image (draw p withcolor cf mpt_po_)
+ else:
+ formatprobbox(p,cl,cb,cf)
fi
enddef;
vardef formatnodeev(expr p)=
+save pp;path pp;
+pp:=nodeshape(p);
save cl,cb,cf;
color cl,cb,cf;
cl:=nodelinecolor;
cb:=nodebgcolor;
cf:=nodefgcolor;
- if nodeformat="superellipse":
- supellformat(p,cl,cb,cf)
- elseif nodeformat="circle":
- circleformat(p,cl,cb,cf)
- elseif (mpt_isgraph) and (nodeformat=""):
- circleformat(p,cl,cb,cf)
- elseif nodeformat="square":
- squareformat(p,cl,cb,cf)
- elseif nodeformat="bbox":
- bboxformat(p,cl,cb,cf)
- else:
+ if nodelinewidth=-1:
+ nodelinewidth:= if mpt_isgraph: 1 else: 0.5 fi
+ fi;
+ if (not mpt_isgraph) and (nodeformat="") and mpt_nodesh_ori:
image (draw p withcolor cf mpt_po_)
+ else:
+ formatnodebox(p,cl,cb,cf)
fi
enddef;
+
+
vardef formatnodeleave(expr p)=
save cl,cb,cf;
color cl,cb,cf;
cl:=leavelinecolor;
cb:=leavebgcolor;
cf:=leavefgcolor;
- if leaveformat="superellipse":
- supellformat(p,cl,cb,cf)
- elseif leaveformat="circle":
- circleformat(p,cl,cb,cf)
- elseif leaveformat="bbox":
- bboxformat(p,cl,cb,cf)
- elseif leaveformat="none":
+ if leaveformat="none":
image (draw p withcolor cf)
- else:
+ elseif leaveformat="":
formatnodeev(p)
+ else:
+ formatleavebox(p,cl,cb,cf)
fi
enddef;
+
+
vardef formatnode(expr p)=
if known exist.arbre[colonne_cour+1][counttmp]:
formatnodeev(p)
@@ -384,12 +379,63 @@ vardef formatnode(expr p)=
enddef;
+boolean mpt_nodesh_ori,mpt_probsh_ori;
+mpt_nodesh_ori:=false;
+mpt_probsh_ori:=false;
+
+
+% Forme du chemin autour de la oproba
+vardef probshape(expr p)=
+ mpt_probsh_ori:=true;
+ if probformat="superellipse":
+ superellipsebox(p)
+ elseif probformat="circle":
+ circlebox(p)
+ elseif probformat="square":
+ squarebox(p)
+ else:
+ bbox p %shifted -center bbox p
+ fi
+enddef;
+
+% Forme du chemin autour du noeud
+vardef nodeshape(expr p)=
+ mpt_nodesh_ori:=true;
+ if nodeformat="superellipse":
+ superellipsebox(p)
+ elseif (nodeformat="circle") or (nodeformat=""):
+ circlebox(p)
+ elseif nodeformat="square":
+ squarebox(p)
+ else:
+ bbox p %shifted -center bbox p
+ fi
+enddef;
+
+vardef leaveshape(expr p)=
+ if leaveformat="superellipse":
+ superellipsebox(p)
+ elseif (leaveformat="circle"):
+ circlebox(p)
+ elseif leaveformat="square":
+ squarebox(p)
+ else:
+ bbox p %shifted -center bbox p
+ fi
+enddef;
+
+
+
+
+
+vardef formatnodepath(expr p)=
+ nodeshape(p)
+enddef;
+
%%% Prints events
vardef theevlabel(expr s,z,inc)=
save d; numeric d;
-% save p;picture p;
-% p:=formatnode(s);
d=0.5*longdir(s,inc);
s shifted (z - center s + (d+labeloffset)*dir(inc))
enddef;
@@ -491,9 +537,32 @@ enddef;
%%%%%%%% Dessin de la branche
+
vardef dessinbranche(expr Ori,Fin)=
+ edgeshape(Ori,Fin)
+enddef;
+
+
+vardef dessinarete(expr Ori,Fin)=
+ save an,dec;
+ numeric an;pair decdeb,decfin;
+ an:=angle(Fin-Ori);
+ if edgeshift<>0:
+ startedgeshift:=edgeshift;endedgeshift:=edgeshift
+ fi;
+ decdeb:=(0,startedgeshift) rotated an;
+ decfin:=(0,endedgeshift) rotated an;
+ edgeshape(Ori+decdeb,Fin+decfin)
+enddef;
+
+
+
+vardef edgeshape(expr Ori,Fin)=
+ save an;
+ numeric an;
if mpt_isgraph:
- mpt_tmp_branche
+ an:=angle(Fin-Ori);
+ (Ori){dir (an+edgeangleaa[0])}..{dir (an-edgeangleaa[1])}(Fin)
elseif branchtype="segment":
Ori--Fin
elseif branchtype="curve":
@@ -1175,92 +1244,23 @@ enddef;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Outils
-vardef isdigit primary d =
- ("0"<=d)and(d<="9")
-enddef ;
-
-% Convertit un suffixe en chaine avec les chiffres en indice
-vardef _chaine(suffix s)=
- save c,d;
- string c,d;
- d:= str s;
- if length(d)=1:
- c:=d
- elseif isdigit (substring (1,2) of d):
- c:= (substring (0,1) of d) & "_{" & substring (1,infinity) of d & "}"
- else: c:=str s
- fi;
- c
-enddef;
-
-vardef _chainec(expr d)=
- save c;
- string c;
- if length(d)=1:
- c:=d
- elseif isdigit (substring (1,2) of d):
- c:= (substring (0,1) of d) & "_{" & substring (1,infinity) of d & "}"
- elseif isdigit (substring (2,3) of d):
- c:= (substring (0,2) of d) & "_{" & substring (2,infinity) of d & "}"
- else:
- c:=d
- fi;
- c
-enddef;
-
-% longueur d'un paramètre text
-vardef long_texte(text t)=
- save i;
- numeric i;
- i:=0;
- for n=t: i:=i+1; endfor
- i
-enddef;
-
-
-% Placement fin des étiquettes
-vardef thelabelang@#(expr s,z)=
- save tmpang,tmpfig,tmppt,tmppath,tmpstr;
- string tmpstr;
- numeric tmpang;
- pair tmppt;
- path tmppath;
- save p; picture p;
- tmpstr := str @#;
- if picture s: p=s
- else: p = textext(s)
- fi;
- tmppath := llcorner p -- lrcorner p -- urcorner p -- ulcorner p -- cycle;
- if ASCII tmpstr = 91:
- tmpang := scantokens substring(1,length(tmpstr)-1) of tmpstr
- else:
- tmpang := scantokens tmpstr
- fi;
- tmppt := tmppath intersectionpoint ((0.5urcorner p+0.5llcorner p)-- (0.5urcorner p +0.5llcorner p+ 100 * (dir (180+tmpang))));
- p shifted (-tmppt + z + labeloffset*(cosd(tmpang),sind(tmpang)) )
-enddef;
-
-def labelang = draw thelabelang enddef;
-
-
%%%%%%
%% Paramètres
%%%%%
-numeric nodewidth,edgelinewidth,edgearrowpos;
+numeric nodewidth,edgelinewidth,edgearrowpos,edgeshift,startegdeshift;
nodewidth:=0.6cm;
edgelinewidth:=1;
-nodelinewidth:=1;
edgearrowpos:=1;
+edgeshift:=0;
+startedgeshift:=0;
boolean naturalwidth;
naturalwidth:=false;
numeric nodelabeloffset, nodeedgeoffset; % pour la position des étiquettes
nodelabeloffset:=2;
-%nodeedgeoffset:=nodelinewidth/2+edgelinewidth/2;
nodeedgeoffset:=-101;
@@ -1357,7 +1357,7 @@ enddef;
def defnode(suffix ptA)(expr A)=
save tmpchcomp,tmpchlet,tmpchnum;
string tmpchcomp,tmpchlet,tmpchnum;
- mpt_isgraph:=true;
+ mpt_isgraph:=true;arbrebool:=false;
tmpchcomp:= str ptA;
tmpchlet:=mptlpart(str ptA);
tmpchnum:=mptnumpart(str ptA);
@@ -1379,7 +1379,7 @@ enddef;
def defnodestr(expr ptA)(expr A)= % Quand le premier paramètre est une chaine simple
save tmpchcomp,tmpchlet,tmpchnum;
string tmpchcomp,tmpchlet,tmpchnum;
- mpt_isgraph:=true;
+ mpt_isgraph:=true;arbrebool:=false;
tmpchcomp:= ptA;
tmpchlet:=ptA;
tmpchnum:="";
@@ -1394,6 +1394,7 @@ enddef;
def defnodes(text t)= % Pour définir plusieurs noeuds à la fois
+ mpt_isgraph:=true;arbrebool:=false;
if (nodename="array") or (nodename="arabic"):
for i=t:
mpt_numtotal:=mpt_numtotal+1;
@@ -1448,18 +1449,6 @@ vardef nodepath(suffix ptA)=
mpt_nodepath[nn]
enddef;
-% Forme du chemin autour du noeud
-vardef formatnodepath(expr p)=
- if nodeformat="superellipse":
- superellipsebox(p)
- elseif (nodeformat="circle") or (nodeformat=""):
- circlebox(p)
- elseif nodeformat="square":
- squarebox(p)
- else:
- bbox p shifted -center bbox p
- fi
-enddef;
% Dessin du noeud
@@ -1483,8 +1472,9 @@ vardef thenodenum@#(text t)=
pair tmp_pt;
string ch,latch;
picture dess;
- mpt_isgraph:=true;
- interim labeloffset:=nodelabeloffset+nodewidth/2;
+ mpt_isgraph:=true;arbrebool:=false;
+% interim labeloffset:=nodelabeloffset+nodewidth/2;
+ interim labeloffset:=nodelabeloffset;
if ((ASCII str @# < 58) or (ASCII str @# = 91)) and (str @#<>""):
def mylabel = labelang enddef
else:
@@ -1496,9 +1486,9 @@ vardef thenodenum@#(text t)=
ch:="$" & _chainec(mpt_nodename[num]) & "$";
if nodename="arabic": ch := "$" & decimal(num) & "$" fi;
mpt_nodepath[num]:=formatnodepath(labelarbres(ch) scaled scaleev) shifted mpt_nodecoord[num];
- label(formatnodeev(labelarbres(ch) scaled scaleev),mpt_nodecoord[num]);
+ draw formatnodeev(labelarbres(ch) scaled scaleev) shifted mpt_nodecoord[num];
if printnodename:
- mylabel@#(textext(ch) scaled scaleev,mpt_nodecoord[num]) withcolor nodefgcolor mpt_po_
+ mylabel@#(textext(ch) scaled scaleev, ptofpath@#(mpt_nodepath[num],mpt_nodecoord[num])) withcolor nodefgcolor mpt_po_
fi)
else:
dess:=image(%
@@ -1508,12 +1498,12 @@ vardef thenodenum@#(text t)=
tmp_pt:=mpt_nodecoord[num];
else:
mpt_nodepath[num]:=formatnodepath(labelarbres(PP) scaled scaleev) shifted mpt_nodecoord[num];
- label(formatnodeev(labelarbres(PP) scaled scaleev),tmp_pt);
+ draw formatnodeev(labelarbres(PP) scaled scaleev) shifted tmp_pt;
if printnodename:
if string PP:
- mylabel@#(textext(PP),tmp_pt) withcolor nodefgcolor mpt_po_;
+ mylabel@#(textext(PP),ptofpath@#(mpt_nodepath[num],mpt_nodecoord[num])) withcolor nodefgcolor mpt_po_;
else:
- mylabel@#(PP scaled defaultscale,tmp_pt) withcolor nodefgcolor mpt_po_;
+ mylabel@#(PP scaled defaultscale,ptofpath@#(mpt_nodepath[num],mpt_nodecoord[num])) withcolor nodefgcolor mpt_po_;
fi
fi
fi;
@@ -1590,6 +1580,7 @@ enddef;
def drawnodes = draw nodes enddef;
+
%%%%%%%%%%%%%
%% Arêtes
%%%%%%%%%%%%%
@@ -1607,8 +1598,7 @@ vardef theedgeAB(expr m,n)=
B:=mpt_nodecoord[n];
path pathab;
if m<>n:
- an:=angle(B-A);
- pathab:=A{dir (an+edgeangleaa[0])}..{dir (an-edgeangleaa[1])}B;
+ pathab:=dessinarete(A,B);
ta=xpart(pathab intersectiontimes mpt_nodepath[m]);
tb=xpart(pathab intersectiontimes mpt_nodepath[n]);
pathab:= subpath(ta,tb) of pathab;
@@ -1666,7 +1656,7 @@ vardef theedgenum(expr nA,nB)(text p)=
numeric edgeangleaa[],tmp_loopangle[];
edgeangleaa[0]=edgeangleaa[1]=edgeangle;
tmp_loopangle[0]:=loopangle;tmp_loopangle[1]:=loopstartangle;
- mpt_isgraph:=true;
+ mpt_isgraph:=true;arbrebool:=false;
nn:=0;
for i=p:
if numeric i:
@@ -1686,7 +1676,7 @@ vardef theedgenumfig(expr nA,nB)(text p)=
save tmppath;
path tmppath;
tmppath:=theedgenum(nA,nB)(p);
- image(draw tmppath withpen pencircle scaled edgelinewidth mpt_po_;
+ image(draw tmppath withpen pencircle scaled edgelinewidth withcolor linecolor mpt_po_;
if mpt_dir:
filldraw arrowhead subpath(0, edgearrowpos*length mpt_tmp_path) of mpt_tmp_path mpt_po_
fi;
@@ -1737,11 +1727,11 @@ vardef theedgepondnum@#(expr nA,nB)(text p)=
if ((ASCII str @# < 58) or (ASCII str @# = 91)) and (str @#<>""):
def mylabel = labelang enddef
else:
- def mylabel = label enddef
+ def mylabel = labelmp enddef
fi;
tmppath:=theedgenum(nA,nB)(p);
tmppt:=point (arctime posprob*(arclength tmppath) of tmppath) of tmppath;
- image(draw theedgenum(nA,nB)(p) withpen pencircle scaled edgelinewidth mpt_po_;
+ image(draw theedgenum(nA,nB)(p) withpen pencircle scaled edgelinewidth withcolor linecolor mpt_po_;
if mpt_dir:
filldraw arrowhead subpath(0, edgearrowpos*length mpt_tmp_path) of mpt_tmp_path mpt_po_
fi;
@@ -1789,12 +1779,12 @@ enddef;
vardef drawedge@#(text s)(text p) text t=
mpt_drop(t);
- draw edge@#(s)(p) withpen pencircle scaled edgelinewidth;
+ mydraw edge@#(s)(p) withpen pencircle scaled edgelinewidth;
mpt_drop();
enddef;
vardef drawedges@#(text s)(text p) text t=
- draw edges@#(s)(p) t
+ mydraw edges@#(s)(p) t
enddef;
@@ -1877,3 +1867,111 @@ enddef;
def drawgrid= draw grid enddef;
+
+
+%%%%%%%%%%%%%%%
+%% Outils
+%%%%%%%%%%%%%%%%
+
+
+vardef isdigit primary d =
+ ("0"<=d)and(d<="9")
+enddef ;
+
+% Convertit un suffixe en chaine avec les chiffres en indice
+vardef _chaine(suffix s)=
+ save c,d;
+ string c,d;
+ d:= str s;
+ if length(d)=1:
+ c:=d
+ elseif isdigit (substring (1,2) of d):
+ c:= (substring (0,1) of d) & "_{" & substring (1,infinity) of d & "}"
+ else: c:=str s
+ fi;
+ c
+enddef;
+
+vardef _chainec(expr d)=
+ save c;
+ string c;
+ if length(d)=1:
+ c:=d
+ elseif isdigit (substring (1,2) of d):
+ c:= (substring (0,1) of d) & "_{" & substring (1,infinity) of d & "}"
+ elseif isdigit (substring (2,3) of d):
+ c:= (substring (0,2) of d) & "_{" & substring (2,infinity) of d & "}"
+ else:
+ c:=d
+ fi;
+ c
+enddef;
+
+% longueur d'un paramètre text
+vardef long_texte(text t)=
+ save i;
+ numeric i;
+ i:=0;
+ for n=t: i:=i+1; endfor
+ i
+enddef;
+
+
+% Placement fin des étiquettes
+vardef thelabelang@#(expr s,z)=
+ save tmpang,tmpfig,tmppt,tmppath,tmpstr;
+ string tmpstr;
+ numeric tmpang;
+ pair tmppt;
+ path tmppath;
+ save p; picture p;
+ tmpstr := str @#;
+ if picture s: p=s
+ else: p = textext(s)
+ fi;
+ tmppath := llcorner p -- lrcorner p -- urcorner p -- ulcorner p -- cycle;
+ if ASCII tmpstr = 91:
+ tmpang := scantokens substring(1,length(tmpstr)-1) of tmpstr
+ else:
+ tmpang := scantokens tmpstr
+ fi;
+ tmppt := tmppath intersectionpoint ((0.5urcorner p+0.5llcorner p)-- (0.5urcorner p +0.5llcorner p+ 100 * (dir (180+tmpang))));
+ p shifted (-tmppt + z + labeloffset*(cosd(tmpang),sind(tmpang)) )
+enddef;
+
+
+% draw et fill sans _op_
+def myfill expr c = addto currentpicture contour c enddef;
+def mydraw expr p =
+ addto currentpicture
+ if picture p:
+ also p
+ else:
+ doublepath p withpen currentpen
+ fi
+enddef;
+
+
+
+
+def labelang = draw thelabelang enddef;
+def labelmp = mydraw thelabel enddef;
+
+
+vardef ptofpath@#(expr p, c)= % Trouve le point du chemin p à la position @# par rapport à c
+ save diam; numeric diam; diam:=abs(urcorner bbox p - llcorner bbox p);
+ save tmpang;numeric tmpang;
+ if (str @#=""):
+ c
+ elseif ((ASCII str @# < 58) or (ASCII str @# = 91)):
+ if ASCII str @# = 91:
+ tmpang := scantokens substring(1,length(str @#)-1) of str @#
+ else:
+ tmpang := scantokens str @#
+ fi;
+ (c--((c+diam*(1,0)) rotatedaround(c,tmpang))) intersectionpoint p
+ else:
+ (c--(c+diam*laboff@#)) intersectionpoint p
+ fi
+enddef;
+