在 tikz 中排版有向超图

在 tikz 中排版有向超图

与其他几个问题类似,我正在尝试在 tikz 中绘制超图。我想绘制一个有向超图,看起来像这张图片中的那些这里

超图图像

与其他问题相反,我不想在相关边之间画弧。相反,我希望边连接成一个段,然后再次分开。

我不介意指定连接点的位置,但我宁愿不必手动指定传入和传出边缘的角度。我希望线条能够平滑地从连接点分离。

这是我重新创建这个数字的拙劣尝试:

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}

\begin{document}
\tikz{
  \node [circle,draw] (v1) at (0,0)   { $v_1$ };
  \node [circle,draw] (v2) at (-1,-3) { $v_2$ };
  \node [circle,draw] (v3) at (2,-2)  { $v_3$ };
  \node [circle,draw] (v4) at (1,-4)  { $v_4$ };
  \node [circle,draw] (v5) at (3,1)   { $v_5$ };
  \node [circle,draw] (v6) at (5,-1)  { $v_6$ };
  \node [circle,draw] (v7) at (4,-5)  { $v_7$ };
  \node [] (e1) at (1,-2) { $e_1$ };
  \node [] (e2) at (2,0) { $e_2$ };
  \node [] (e3) at (3,-3) { $e_3$ };
  \node [] (e4) at (4,0) { $e_4$ };
%
  \path
% edge 1
        (v1) [-]  edge node { } (e1)
        (v2) [-]  edge node { } (e1)
        (e1) [->] edge node { } (v3)
        (e1) [->] edge node { } (v4)
% edge 2
        (v1) [-]  edge node { } (e2)
        (v3) [-]  edge node { } (e2)
        (e2) [->] edge node { } (v5)
% edge 3
        (v7) [-]  edge node { } (e3)
        (e3) [->] edge node { } (v3)
        (e3) [->] edge node { } (v4)
% edge 4
        (v5) [-]  edge node { } (e4)
        (e4) [->] edge node { } (v6)
        (e4) [->] edge node { } (v7)
        ;
}
\end{document}

由此得出该图:

试图

答案1

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\makeatletter
\tikzset{
    @pos/.style={@pos1={#1},@pos2={#1}},
    @ratio/.style={@ratio1={#1},@ratio2={#1}},
    @delta/.style={@delta1={#1},@delta2={#1}},
    @edge/.style={@@edge/.append style={#1}},
    @edge 0/.style={@@edge 0/.append style={#1}},
    @edge 1/.style={@@edge 1/.append style={#1}},
    @edge 2/.style={@@edge 2/.append style={#1}},
    @edge 3/.style={@@edge 3/.append style={#1}},
    @edge 4/.style={@@edge 4/.append style={#1}},
    % and for four:
    @pos1/.store in=\qrr@posA,
    @pos2/.store in=\qrr@posB,
    @ratio1/.store in=\qrr@ratioA,
    @ratio2/.store in=\qrr@ratioB,
    @delta1/.store in=\qrr@deltaA,
    @delta2/.store in=\qrr@deltaB,
    @pos=.5,
    @ratio=.5,
    @delta=.1,
}
\newcommand*{\connectThree}[4][]{
    \begingroup
    \tikzset{#1}
    \coordinate (@aux1) at ($(#2)!\qrr@ratioA!(#3)$);
    \coordinate (@aux2) at ($(#4)!\qrr@posA!(@aux1)$);
    \path (@aux2) edge[@@edge/.try, @@edge 0/.try, @@edge 3/.try] (#4);
    \draw[@@edge/.try, @@edge 1/.try] (@aux2) .. controls ($(#4)!\qrr@posA+\qrr@deltaA!(@aux1)$) .. (#2);
    \draw[@@edge/.try, @@edge 2/.try] (@aux2) .. controls ($(#4)!\qrr@posA+\qrr@deltaA!(@aux1)$) .. (#3);
    \endgroup
}
% \renewcommand*{\connectThree}[4][]{\connectFour[#1, @@edge 4/.style={draw=none}, @ratio2=0]{#2}{#3}{#4}{0,0}}

\newcommand*{\connectFour}[5][]{
    \begingroup
    \tikzset{#1}
    \coordinate (@aux1a) at ($(#2)!\qrr@ratioA!(#3)$);
    \coordinate (@aux1b) at ($(#4)!\qrr@ratioB!(#5)$);
    \coordinate (@aux2a) at ($(@aux1b)!\qrr@posA!(@aux1a)$);
    \coordinate (@aux2b) at ($(@aux1a)!\qrr@posB!(@aux1b)$);
    \path (@aux2a) edge[@@edge/.try,@@edge 0/.try] (@aux2b);
    \draw[@@edge/.try,@@edge 1/.try] (@aux2a) .. controls ($(@aux1b)!\qrr@posA+\qrr@deltaA!(@aux1a)$) .. (#2);
    \draw[@@edge/.try,@@edge 2/.try] (@aux2a) .. controls ($(@aux1b)!\qrr@posA+\qrr@deltaA!(@aux1a)$) .. (#3);
    \draw[@@edge/.try,@@edge 3/.try] (@aux2b) .. controls ($(@aux1a)!\qrr@posB+\qrr@deltaB!(@aux1b)$) .. (#4);
    \draw[@@edge/.try,@@edge 4/.try] (@aux2b) .. controls ($(@aux1a)!\qrr@posB+\qrr@deltaB!(@aux1b)$) .. (#5);
    \draw[help lines] (@aux1a) -- (@aux1b) node[midway,above,sloped,font=\tiny,shape=rectangle,inner xsep=+0pt,draw=none,align=center,fill=white,fill opacity=.75,outer ysep=\pgflinewidth,text opacity=1] {ratio: \qrr@ratioA/\qrr@ratioB\\pos: \qrr@posA/\qrr@posB\\delta: \qrr@deltaA/\qrr@deltaB};
    \endgroup
}
\makeatother
\begin{document}
\begin{tikzpicture}
  \node [circle,draw] (v1) at (0,0)   { $v_1$ };
  \node [circle,draw] (v2) at (-1,-3) { $v_2$ };
  \node [circle,draw] (v3) at (2,-2)  { $v_3$ };
  \node [circle,draw] (v4) at (1,-4)  { $v_4$ };
  \node [circle,draw] (v5) at (3,1)   { $v_5$ };
  \node [circle,draw] (v6) at (5,-1)  { $v_6$ };
  \node [circle,draw] (v7) at (4,-5)  { $v_7$ };
        \connectThree[
          @edge 3=->
        ]{v1}{v3}{v5}
        \connectThree[
          @ratio=0,
          @edge 1=->,
          @edge 2=->
        ]{v6}{v7}{v5}
        \connectThree[
          @edge 1=->,
          @edge 2=->
        ]{v3}{v4}{v7}
        \connectFour[
          @ratio=.4,
          @pos1=.7,
          @pos2=.5,
          @edge 3=->,
          @edge 4=->,
          @edge=thick
        ]{v1}{v2}{v3}{v4}
        \connectFour[@edge=blue,@edge 3=->, @edge 4={draw}, @ratio2=0]{v3}{v5}{v6}{v7}
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

在此处输入图片描述

具有内联的超图Asymptote,使用flowchart模块hypg.tex

\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}

\begin{asy}
size(0,200);
import flowchart;

pair[]pv={
  (0,0)   , // pv[0], not used, included for convenient indexing nodes from pv[1]
  (0,0)   ,
  (-1,-3) ,
  (2,-2)  ,
  (1,-4)  ,
  (3,1)   ,
  (5,-1)  ,
  (4,-5)  ,
};

pair[][] pe={  // point coordinates and a relative position of the label (N=North etc)
  {(0,0),  N}  , // ev[0], not used, included for convenient indexing nodes from ev[1]
  {(0.2,-2) ,N}  ,
  {(2,0)  ,SE}  ,
  {0.1pv[3]+0.2pv[6]+0.7pv[7],E},
  {(4.5,0.75)  ,SW} ,
};

pen nodeFill=yellow+opacity(0.8);
pen nodeLine=darkblue+1.2pt+opacity(0.5);

block[] v=new block[pv.length];
block[] e=new block[pe.length];


for(int i=1;i<pv.length;++i){
  v[i]=circle("$v_"+string(i)+"$",pv[i],nodeFill,nodeLine);
  draw(v[i]);
}

string s;
for(int i=1;i<pe.length;++i){
  s="$e_"+string(i)+"$";
  e[i]=circle(s,pe[i][0]);
  label(s,pe[i][0],pe[i][1]);
  dot(pe[i][0]);
}

add(
  new void(picture pic, transform t) {
    blockconnector operator --=blockconnector(pic,t);
    real tg;
     pen linePen=darkblue+0.8pt;
     currentpen=linePen;
     arrowfactor=4;
     draw(pic,v[1].bottomleft(t) .. {dir(-30)}t*e[1].center{dir(-30)} ..v[3].bottomleft(t),Arrow(HookHead));
     draw(pic,v[2].top(t){dir(80)} .. {dir(-30)}t*e[1].center{dir(-30)} ..v[4].top(t),Arrow(HookHead));
     draw(pic,v[1].right(t) .. t*e[2].center ..v[5].bottom(t),Arrow(HookHead));
     draw(pic,v[3].topleft(t){dir(120)} .. {dir(20)}(t*pe[2][0]));

     tg=-30;
     draw(pic,v[5].right(t) .. {dir(tg)}t*e[4].center{dir(tg)} ..v[6].top(t),Arrow(HookHead));
     draw(pic,v[5].right(t) .. {dir(tg)}t*e[4].center{dir(tg)} ..v[7].topright(t),Arrow(HookHead));

     tg=90;
     draw(pic,v[7].top(t) .. {dir(tg)}t*e[3].center{dir(tg)} ..v[3].right(t),Arrow(HookHead));
     draw(pic,v[7].top(t) .. {dir(tg)}t*e[3].center{dir(tg)} ..v[4].topright(t),Arrow(HookHead));

  }
);
\end{asy}
\end{document}

为了处理它latexmk,请创建文件latexmkrc

sub asy {return system("asy '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

然后运行latexmk -pdf hypg.tex

相关内容