diff options
-rw-r--r-- | Master/texmf-dist/doc/metapost/mptrees/README.md | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/metapost/mptrees/france-region.jpg | bin | 0 -> 411269 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.pdf | bin | 203314 -> 689872 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.tex | 389 | ||||
-rw-r--r-- | Master/texmf-dist/metapost/mptrees/mptrees.mp | 442 |
5 files changed, 658 insertions, 175 deletions
diff --git a/Master/texmf-dist/doc/metapost/mptrees/README.md b/Master/texmf-dist/doc/metapost/mptrees/README.md index f74fa1c30c7..97332c500f6 100644 --- a/Master/texmf-dist/doc/metapost/mptrees/README.md +++ b/Master/texmf-dist/doc/metapost/mptrees/README.md @@ -1,4 +1,4 @@ -Package mptrees - Version 24.02 - February 22, 2024 +Package mptrees - Version 24.04 - April 8th, 2024 --- diff --git a/Master/texmf-dist/doc/metapost/mptrees/france-region.jpg b/Master/texmf-dist/doc/metapost/mptrees/france-region.jpg Binary files differnew file mode 100644 index 00000000000..486b88268af --- /dev/null +++ b/Master/texmf-dist/doc/metapost/mptrees/france-region.jpg diff --git a/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.pdf b/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.pdf Binary files differindex 5a62a3b5176..39438c5357d 100644 --- a/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.pdf +++ b/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.pdf diff --git a/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.tex b/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.tex index 1cc7339d014..9107592c46b 100644 --- a/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.tex +++ b/Master/texmf-dist/doc/metapost/mptrees/mptrees-doc.tex @@ -10,6 +10,7 @@ \usepackage{unicode-math} \setmainfont{STIX Two Text} \setmathfont{STIX Two Math} +\usepackage{fontawesome5} \usepackage{geometry} \geometry{hmargin=2cm,vmargin={1.5cm,1.8cm},includefoot} @@ -180,7 +181,7 @@ \DeclareTCBListing[auto counter]{exemple}{ !O{} }{ enhanced, - title=Exemple \thetcbcounter, + title=Example \thetcbcounter, coltitle=black, fonttitle=\bfseries, attach boxed title to top left, @@ -527,6 +528,8 @@ Numeric controlling the scale of the label at the end of the edge (the event). \begin{mptparam}{nodeformat}{string}{""} String that indicates how the events are printed (the shape of path around the event). Possible values are (for now) \verb|"bbox"|, \verb|"circle"|, \verb|"superellipse"|. + +See below for personalised values. \end{mptparam} \begin{exemple}[lefthand ratio=0.65] @@ -562,6 +565,30 @@ nodefgcolor:=(0.7,0.4,0.7); draw stree[1][1](3cm,2cm)("$A$","$B$"); \end{exemple} +\begin{rpobjet}{nodeshape(expr A,B)}{cycle path} +It is also possible to redefine the path defining the node. Simply rewrite the \verb|nodeshape| macro, which must take a picture as parameter and whose result must be a cycle path. + +The parameter passed to the macro is the figure representing the drawing of the event (normally the name of the event). You may use it, or not, in the macro definition. +\end{rpobjet} + +\begin{exemple}[lefthand ratio=0.6] +vardef nodeshape(expr p)= + fullcircle xscaled 1cm yscaled 0.6cm +enddef; + +draw stree[1][1](3cm,3cm)("$A$","$B$"); +\end{exemple} + + +\begin{exemple}[lefthand ratio=0.7] +vardef nodeshape(expr p)= + llcorner p..ulcorner p..urcorner p..lrcorner p--cycle +enddef; + +nodebgcolor:=0.7white; +draw stree[1][1](3cm,3cm)("$A$","$B$"); +\end{exemple} + \subsection{Leaves} @@ -757,6 +784,10 @@ When the boolean \verb|edgearrow| is set to true, edges end with an arrow. String which indicates the shape of the edge. Possible values are \verb|segment|, \verb|curve|, \verb|broken|. Note that double quotes have to be replaced by single quotes when this parameter is changed locally inside the \verb|tree| macro. + + +See below for personalised values. + \end{mptparam} @@ -808,6 +839,23 @@ Note that double quotes have to be replaced by single quotes when this parameter draw stree[1][1](3cm,3cm)("$A$","$B$"); \end{exemple} +\begin{rpobjet}{edgeshape(expr A,B)}{path} +It is possible to completely redefine the path defining the edge. Simply rewrite the \verb|edgeshape| macro, which must take two pairs as parameters and whose result must be a path. + +The first parameter represents the start point and the second the end point. + +\end{rpobjet} + +\begin{exemple}[lefthand ratio=0.6] +vardef edgeshape(expr S,E)= + save a;numeric a;a=angle(E-S); + S--((0.25cm,0) rotated (a+30) shifted 0.5[S,E]) + --((0.25cm,0) rotated (a-150) shifted 0.5[S,E]) + --E +enddef; + +draw stree[1][1](3cm,3cm)("$A$","$B$"); +\end{exemple} \section{Regular trees} @@ -1136,6 +1184,8 @@ drawnodes(); \begin{mptparam}{nodeformat}{string}{""} String that indicates how the nodes are printed (the shape of path around the node). Possible values are (for now) \verb|"bbox"|, \verb|"circle"|, \verb|"superellipse"| and \verb|"square"|. + +See below for personalised values. \end{mptparam} @@ -1194,6 +1244,41 @@ drawnodes(); \end{exemple} +\begin{rpobjet}{nodeshape(expr A,B)}{(cycle) path} +In the same way as for trees, it is also possible to redefine the path defining the node. Simply rewrite the \verb|nodeshape| macro, which must take a picture as parameter and whose result must be a cycle path. + +The parameter passed to the macro is the figure representing the drawing of the event (normally the name of the event). You may use it, or not, in the macro definition. + +Note that in the path definition, the coordinates $(0,0)$ correspond to the node coordinates. + +\end{rpobjet} + +\begin{exemple}[lefthand ratio = 0.65] +vardef nodeshape(expr p)= + fullcircle xscaled 1.5nodewidth yscaled 0.8nodewidth +enddef; + +defnodes((0cm,0cm),(2cm,2cm),(4cm,0)); +drawnodes(); +\end{exemple} + + +\begin{exemple}[lefthand ratio = 0.65] +vardef nodeshape(expr p)= + pair c,h,v; + h:=lrcorner p - llcorner p; + v:=ulcorner p - llcorner p; + c:=center p; + (c-h -- c+v -- c+h -- c-v -- cycle) shifted -c +enddef; + +defnodes((0cm,0cm),(2cm,2cm),(4cm,0)); +drawnodes(); +\end{exemple} + + + + \begin{rpdeclaration}{drawnodes(<nodes>) withbgcolor <color>} While \verb|withcolor| applies to lines and labels, \verb|withbgcolor| applies to the filling of nodes. \end{rpdeclaration} @@ -1347,6 +1432,28 @@ drawnodes(); drawedges((1,2),(3,1),"$p$")(); \end{exemple} +\begin{mptparam}{startedgeshift}{numeric}{0} +Space added at the beginning of the edge. +\end{mptparam} + +\begin{mptparam}{endedgeshift}{numeric}{0} +Space added at the end of the edge. +\end{mptparam} + +\begin{mptparam}{edgeshift}{numeric}{0} +Space added at both start and end of the edge. +\end{mptparam} + +\begin{exemple}[lefthand ratio = 0.6] +defnodes((0cm,0cm),(2cm,2cm),(4cm,0)); +drawnodes(); +drawedges((1,2),(1,3),"$p$")(); +startedgeshift:=-0.3cm;endedgeshift:=-0.1cm; +drawedges((1,3))() withcolor blue; +edgeshift:=0.2cm; +drawedges((1,2))() withcolor blue; +\end{exemple} + \begin{mptparam}{probformat}{string}{""} String that indicates how the weights are printed (the shape of the path). Possible values are (for now) \verb|"bbox"|, \verb|"circle"|, \verb|"superellipse"| and \verb|"square"|. @@ -1438,6 +1545,28 @@ drawnodes(); drawdiredges((1,1),(2,2),(3,3))(); \end{exemple} +\begin{rpobjet}{edgeshape(expr A,B)}{path} +In the same way as for trees, it is also possible to completely redefine the path defining the edge. Simply rewrite the \verb|edgeshape| macro, which must take two pairs as parameters and whose result must be a path. + +The first parameter represents the start point and the second the end point. + +\end{rpobjet} + +\begin{exemple}[lefthand ratio = 0.6] +vardef edgeshape(expr A,B)= + save a;numeric a;a=angle(B-A); + A--((0.25cm,0) rotated (a+30) shifted 0.5[A,B]) + --((0.25cm,0) rotated (a-150) shifted 0.5[A,B]) + --B +enddef; + +defnodes((0cm,0cm),(2cm,2cm),(4cm,0)); +drawnodes(); +drawedge(1,2)(); +drawdiredge(3,1)(); +\end{exemple} + + \section{Complete graphs} \begin{rplabel}{draw(dir)graph.<pos>(<(Na,Nb)>,<string1>,<(Nc,Nd)>,<string2>,...)(<angle1>,<angle2>)} @@ -1487,6 +1616,262 @@ drawedges((1,2),(3,1))(); \end{exemple} -\end{document} +\section{Examples} + +\subsection*{Weighted graph} +\begin{exemple}[listing above text] +u:=0.8cm; +nodewidth:=0.15cm; +nodebgcolor:=black; +printnodename:=false; +defnodes((5u,0),(0,3u),(2u,4u),(7u,4u),(3u,6u),(2u,7u),(12u,7u),(7u,8u), + (10u,8u),(9.5u,9.5u)); +drawnodes(); +drawedges((1,2),"9",(1,3),"9",(1,4),"8",(1,7),"18")(); +drawedges((2,3),"3",(2,6),"6")(); +drawedges((3,4),"9",(3,5),"2",(3,6),"4")(); +drawedges((4,5),"8",(4,7),"10",(4,8),"7",(4,9),"9")(); +drawedges((5,6),"2",(5,8),"9")(); +drawedges((6,8),"9")(); +drawedges((7,9),"3",(7,10),"4")(); +drawedges((8,9),"5",(8,10),"4")(); +drawedges((9,10),"1")(); +\end{exemple} + + +\subsection*{Minimum spanning tree} +\begin{exemple}[listing above text] +u:=0.8cm; +nodewidth:=0.15cm; +nodebgcolor:=black; +printnodename:=false; +defnodes((5u,0),(0,3u),(2u,4u),(7u,4u),(3u,6u),(2u,7u),(12u,7u),(7u,8u), + (10u,8u),(9.5u,9.5u)); +drawnodes(); +drawoptions(withcolor 0.7white); +drawedges((1,2),"9",(1,3),"9",(1,7),"18")(); +drawedges((2,6),"6")(); +drawedges((3,4),"9",(3,6),"4")(); +drawedges((4,7),"10",(4,9),"9")(); +drawedges((5,8),"9")(); +drawedges((6,8),"9")(); +drawedges((7,10),"4")(); +drawedges((8,9),"5")(); +drawoptions(withcolor black); +edgelinewidth:=2; +drawedges((1,4),"8",(2,3),"3",(3,5),"2",(4,5),"8",(5,6),"2",(4,8),"7", + (8,10),"4",(9,10),"1",(7,9),"3")(); +\end{exemple} + + +\subsection*{Graph colouring} + +\begin{exemple}[lefthand ratio = 0.6] +printnodename:=false; +nodewidth:=0.3cm; +for i=1 upto 7: + defnodes(((2cm,0) rotated (360*i/7))); +endfor +nodebgcolor:=red; +drawnodes(2,6); +nodebgcolor:=blue; +drawnodes(1,4); +nodebgcolor:=green; +drawnodes(3,5,7); +drawedges((1,5),(1,6),(1,7),(2,3),(2,4),(2,5), + (3,4),(4,5),(4,6),(4,7),(6,7))(); +\end{exemple} + +\bigskip +With Lua\LaTeX{} and \verb|luamplib| package you can use \verb|\includegraphics| inside a \MP{} code: + +\begin{exemple}[listing above text] +u:=0.5cm; +nodewidth:=0.4cm; +nodename:="arabic"; +printnodename:=false; +draw btex \includegraphics[width=10cm]{france-region.jpg} etex; +% picture from https://capcarto.fr/telechargements/ +draw grid(20,18)(u); +defnodes((4.5u,12.5u),(7.5u,14.5u),(5u,10u),(9.5u,16.5u),(10u,13u), + (15u,13u),(9u,12u),(12u,11u),(6u,8u),(11u,7u),(9u,3u), + (15u,5u),(19u,1u)); +nodebgcolor:=red; +drawnodes(7,4,11,13); +nodebgcolor:=green; +drawnodes(2,10,6); +nodebgcolor:=blue; +drawnodes(5,3,12); +nodebgcolor:=(1,1,0); +drawnodes(1,8,9); +drawedges((1,2),(1,3),(2,3),(2,4),(2,5),(2,7),(3,7),(3,9),(4,5), + (4,6),(5,6),(5,7),(5,8),(6,8),(7,8),(7,9),(7,10),(8,10), + (9,10),(9,11),(10,11),(10,12),(11,12))(); +\end{exemple} + + + +\subsection*{Markov chain} + +\begin{exemple}[lefthand ratio = 0.6] +scaleprob:=0.8; +u:=1.6cm; +nodebgcolor:=0.8white; +defnodes((0,0),(2u,0),(u,1.5u)); +drawnodes(); +drawoptions(withcolor red); +drawdiredges((1,2),"$0.5$",(1,3),"$0.3$")(-25); +drawdiredge(1,1)("$0.2$",210); +drawoptions(withcolor blue); +drawdiredges((2,1),"$0.1$",(2,3),"$0.3$")(-25); +drawdiredge(2,2)("$0.6$",-30); +drawoptions(withcolor 0.5green); +drawdiredges((3,1),"$0.7$",(3,2),"$0.2$")(-25); +drawdiredge(3,3)("$0.1$"); +\end{exemple} + +\subsection*{Hypercube $Q_3$} + +\begin{exemple}[lefthand ratio = 0.65] +u:=3cm; +nodewidth:=0.3cm; +edgelinewidth:=2; +pair p; p:=(0.4u,0.4u); +defnodes((0,0),(u,0),(0,u),(u,u)); +defnodes((0,0)+p,(u,0)+p,(0,u)+p,(u,u)+p); +nodebgcolor:=black;nodelinecolor:=black; +drawnode.lrt(6,"101"); +nodebgcolor:=red;nodelinecolor:=red; +drawnode.llft(1,"000");drawnode.lrt(2,"001"); +drawnode.rt(4,"011");drawnode.lrt(5,"100"); +nodebgcolor:=blue;nodelinecolor:=blue; +drawnode.lft(3,"010");drawnode.ulft(7,"110"); +drawnode.urt(8,"111"); +drawedges((1,3),(3,4),(2,6),(4,8),(6,8),(5,6),(5,7))(); +drawedges((3,7),(7,8))() withcolor blue; +drawedges((1,2),(1,5),(2,4))() withcolor red; +\end{exemple} + +\subsection*{Three utilities problem} + +With Lua\LaTeX{}, \verb|luamplib| and \verb|fontawesome5| packages. + +\begin{exemple}[lefthand ratio = 0.7] +u:=1.2cm; +defnodes((u,2u),(2u,2u),(3u,2u),(u,u),(2u,u),(3u,u)); +nodelinecolor:=white; +drawnode(1,"\large \faHome"); +drawnode(2,"\large \faHome"); +drawnode(3,"\large \faHome"); +nodebgcolor:=black;nodefgcolor:=blue; +drawnode(4,"\faWater"); +nodefgcolor:=red;drawnode(5,"\faBurn"); +nodefgcolor:=(1,1,0);drawnode(6,"\faBolt"); +drawedges((1,4),(2,4),(2,5),(2,6),(3,6))(); +drawedges((1,5),(5,3))(-115); +vardef edgeshape(expr A,B)= +save a;numeric a;a=angle(B-A);s:=if A>B: - fi 1; +A..(0.7[A,B]+(0.35(B-A) rotated (s*90))){dir a}..B +enddef; +drawedges((4,3))(); +edgelinewidth:=2;drawedges((6,1))() withcolor (1,0.5,0); +\end{exemple} + +\subsection*{Various} +\begin{exemple}[lefthand ratio = 0.6] +nodebgcolor:=0.7white; +nodewidth:=0.2cm; + +for i=1 upto 7: + defnode(A[i],(2cm,0) rotated (360*i/7)); + drawnode[360*i/7](i); + for j=1 upto i-1: + drawedge(i,j)(); + endfor +endfor +\end{exemple} + +\begin{exemple}[lefthand ratio = 0.6] +nodebgcolor:=0.7white; +nodewidth:=0.2cm; +printnodename:=false; +u:=0.7cm; +defnodes((3u,-3u)); +drawnode(1); +for i=1 upto 4: + for j=1 upto 4: + defnodes((0,-2u) rotatedaround((0,-3u),90j) + rotated 90i); + endfor + defnodes((3u,-3u) rotated (90i)); + drawnodes(5i-3,5i-2,5i-1,5i,5i+1); + drawedges((5i-4,5i-3),(5i-3,5i-2),(5i-2,5i-1), + (5i-1,5i),(5i,5i-3),(5i-1,5i+1))(); +endfor; +\end{exemple} + + +\begin{exemple}[listing above text,before lower=\footnotesize] +u:=1.2cm; +nodewidth:=0.4cm; +defnodes((0,0.6u),(3u,0.6u),(5u,0),(8u,0),(10u,0.6u),(13u,0.6u),(0,-0.6u), + (3u,-0.6u),(10u,-0.6u),(13u,-0.6u)); +nodeedgeoffset:=-0.2cm; +nodebgcolor:=0.8white; +edgelinewidth:=0.2cm; +vardef edgeshape (expr A,B)=A{dir 0}..{dir 0}B enddef; +drawedges((1,2))() withcolor red; +drawedges((5,6))() withcolor red; +drawedges((7,8))() withcolor blue; +drawedges((9,10))() withcolor blue; +endedgeshift:=0.1cm; drawedges((2,3))() withcolor red; +endedgeshift:=-0.1cm; drawedges((8,3))() withcolor blue; +endedgeshift:=0cm; +startedgeshift:=0.1cm; drawedges((4,5))() withcolor red; +startedgeshift:=-0.1cm;drawedges((4,9))() withcolor blue; +edgeshift:=0.1cm; drawedges((3,4))() withcolor red; +edgeshift:=-0.1cm; drawedges((3,4))() withcolor blue; +drawnode.bot(1,"C.H.U."); +drawnode.bot(2,"Berges de Maine"); +drawnode.bot(5,"Hôtel de Ville"); +drawnode.bot(6,"Foch - Maison bleue"); +drawnode.bot(7,"Doutre"); +drawnode.bot(8,"Place Molière"); +drawnode.bot(9,"Conservatoire"); +drawnode.bot(10,"Montaigne"); +vardef nodeshape(expr p)= + (halfcircle shifted (0,0.5)-- + halfcircle scaled -1 shifted (0,-0.5)-- + cycle) scaled nodewidth +enddef; +drawnode.bot(3,"Saint-Serge"); +drawnode.bot(4,"Centre de Congrès"); +\end{exemple} + +\begin{exemple}[listing above text] +vardef nodeshape(expr p)= +% From "Drawing with Metapost" by Toby Thurston +% https://github.com/thruston/Drawing-with-Metapost/ + for i=1 upto 20: + (0.4cm if odd(i): - else: + fi 3+ uniformdeviate 3,0) rotated (i*360/20) -- + endfor cycle +enddef; +vardef edgeshape(expr A,B)= + save an;numeric an;an:=angle(B-A); + A{dir (an + 60*(uniformdeviate 2-1))}.. + 0.5[A,B]{dir (180+an)}.. + {dir (an + 60*(uniformdeviate 2-1))}B +enddef; +nodebgcolor:=(1,0.5,0); +nodelinecolor:=0.6red; +nodefgcolor:=0.6red; +linecolor:=0.5green; +edgelinewidth:=1.5; +defnodes((0cm,0cm),(4cm,2cm),(8cm,1cm),(5cm,-3cm)); +drawnodes(); +drawedges((1,2),(2,3),(3,4),(1,4))(); +\end{exemple} + +\end{document} diff --git a/Master/texmf-dist/metapost/mptrees/mptrees.mp b/Master/texmf-dist/metapost/mptrees/mptrees.mp index f31080b61c9..eba564d6652 100644 --- a/Master/texmf-dist/metapost/mptrees/mptrees.mp +++ b/Master/texmf-dist/metapost/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; + |