自动改善 tikz 中的平行边

自动改善 tikz 中的平行边

我必须绘制很多带有很多边的图形。有些节点通过一个方向的边连接,有些则通过两个方向的边连接。特定节点被涂成红色,而边缘进入这些节点被涂成黑色。现在我想改变两点,让图表更容易理解:

  • 如果两个节点以两种方式连接,则将两个箭头<---->变成一个<-->(差异很小,但它们让我很烦)。
  • 如果两个节点双向连接,其中一个节点的传出节点为红色自动画两个箭头,稍微弯曲或偏移,一个是黑色,一个是红色。

重要的是,这是自动完成的,因此结果看起来总是相同的,与连接的斜率无关。这是我当前的代码及其结果:

\documentclass[preview]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary {positioning}
\usetikzlibrary{arrows,automata,shapes}
\usetikzlibrary{trees,fit,decorations.pathreplacing}
\usetikzlibrary{calc}
\usetikzlibrary{graphs}
\tikzset{near start abs/.style={xshift=1cm}}

\begin{document}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

Graph type one:
    \begin{figure}[H]
    \centering
        \begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=3cm,semithick]
        \tikzstyle{every state}=[scale =1,fill=blue,draw=none,text=white]

        \def \n {12}
        \def \radius {4cm}
        \def \labelrad {4.7cm}
        \def \margin {8} % margin in angles, depends on the radius

        \foreach \s in {0,...,11}
        {
            \node[draw, state] (\s) at ({-360/\n * (\s +4.5)}:\radius) {$\s$};
            %           \draw[->, >=latex] ({360/\n * (\s - 1)+\margin}:\radius) 
            %           arc ({360/\n * (\s - 1)+\margin}:{360/\n * (\s)-\margin}:\radius);
        }
        \node[fit=(0)(1)(2)(3)](input){};
        \node[fit=(4)(5)](output){};
        \node[fit=(6)(7)(8)(9)](intern){};
        \node[fit=(10)(11)](inhib){};

        % edges
        \path
        (0) edge (9)
        edge (11)
        (1) edge (8)
        edge (9)
        edge (10)
        edge (11)
        (2) edge (6)
        edge (7)
        edge (8)
        edge (9)
        (3) edge (9)
        edge (11)
        (4) edge (7)
        edge (9)
        edge (11)
        (5) edge (6)
        edge (9)
        edge (10)
        (6) edge (4)
        edge (8)
        edge (9)
        edge (11)
        (7) edge (4)
        edge (5)
        edge [red,dashed,bend left =50] node {} (9)
        edge (11)
        (8) edge (4)
        edge (6)
        edge (11)
        (9) edge (4)
        edge (7)
        edge (10)
        (10) edge[red] (5)
        edge[red] (9)
        (11) edge[red] (4)
        edge[red] (5)
        edge[red] (6)
        ;


        % Input area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,black!10]
        (input.north west) rectangle (input.south east);
        \end{pgfonlayer}


        % Input area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,blue!10]
        (output.north west) rectangle (output.south east);
        \end{pgfonlayer}


        % Intern area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,green!10]
        (intern.north west |- intern.north) rectangle (intern.south east |- intern.south);
        \end{pgfonlayer}


        % Inhib area
        \begin{pgfonlayer}{background}
        \filldraw [line width=4mm,join=round,red!10]
        (inhib.north west |- inhib.north) rectangle (inhib.south east |- inhib.south);
        \end{pgfonlayer}


        % captions
        %       \node[below=0.3cm] at (input.south) {Input};
        %       \node[above=0.3cm] at(intern.north) {Intern};
        %       \node[below=0.3cm] at (inhib.south) {Inhibitorisch};

        % Labels
        \foreach \c [count=\x from 0] in {0,2,2,0,0,0,0,1,2,1,1,2} %{{a,f},{b,o},{c,o},{d,b},{e,a},{f,r}} 
        {
            \node (\x) at ({-360/\n * (\x +4.5)}:\labelrad) {\c};
        }
        \end{tikzpicture}
    \end{figure}




Graph type two:
    \begin{figure}[H]
    \centering
        \begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2cm,semithick]
        \tikzstyle{every state}=[scale =1,fill=blue,draw=none,text=white]

        \node[state] (4)                    {4};
        \node[state] (7) [above right of=4] {7};
        \node[state] (9) [below right of=7] {9};
        \node[state] (10)[below left of=9]       {10};

        % edges
        \path
        (4) edge (7)
        edge (9)
        (7) edge (4)
        edge [red,dashed,bend left =50] node {} (9)
        (9) edge (4)
        edge (7)
        edge (10)
        (10) edge[red] (9)
        ;

        % Labels
        \node (l4) at ($(4)+(-.5,.7)$) {$(0,0\rightarrow2)$};
        \node (l7) at ($(7)+(-0,.7)$) {$(2,1\rightarrow2)$};
        \node (l9) at ($(9)+(.5,-.8)$) {$(4,1\rightarrow2)$};
        \node (l10) at ($(10)+(0,-.7)$) {$(2,1\rightarrow2)$};
        \node[red] (gew) at ($(7)!0.5!(9)+(1.3,.7)$) {$(0\rightarrow1)$};
        \end{tikzpicture}
    \end{figure}
\end{document} 

结果是:

在此处输入图片描述

编辑:只需忽略从节点 7 到节点 9 的虚线边,这是不同的事情。

答案1

这不是一个答案。它是 TikZ 图形语法及其对图形绘制算法的支持的说明。

前 2 个图仅说明了语法。第三个图使用算法图布局工具,因此需要 LuaTeX。

如果以下行出现错误,请将其注释掉。这是为了修复与standalone当前 LuaTeX 的兼容性问题。

\RequirePackage{luatex85}
\documentclass[border=10pt,multi,tikz]{standalone}

加载一些 TikZ 库。graphs支持语法。graphdrawing支持与 LuaTeX 一起使用的算法图布局。

\usetikzlibrary{graphs,graphdrawing,arrows.meta}

算法graphdrawing支持包括许多用于各种现成布局算法的库。这是其中之一。

\usegdlibrary{circular}
\begin{document}

此示例未使用算法,但确实说明了语法。它使用了一种circular placement以循环方式布置 12 个节点组的策略。

\begin{tikzpicture}
  [

my node是一种将传入边设置为黑色、将传出边设置为红色的样式。

    my node/.style={<red, >black},
  ]

这是图形规范本身。我们将节点旋转一个角度,并稍微增加默认半径,以使布局与默认布局略有不同。

  \graph [clockwise=12, radius=25mm, phase=-120, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]

现在讨论图中的节点。

  {

布局我们的 12 个节点。

    {\foreach \i in {0,...,11} \i,},

指定它们之间的各种连接。

    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}

示例 1

这是一个略有不同的布局,它明确使用了circular placement

\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [circular placement, group polar shift=(-30:0), /tikz/>=Stealth, nodes={fill=blue, circle, minimum size=5mm, inner sep=1pt, text=white}]
  {
    a/ [fill=none] -!- \foreach \i in {0,...,11} { a -!- \i },
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}

示例 2

第三个示例使用了我们在库中加载的算法布局之一circular,称为simple necklace layout

\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]

请注意,此处使用node sep来增加节点之间的间距,而不是上面的手动方法。radius例如,设置 显然仅适用于圆形布局。相比之下,node sep在布局之间是中性的。

  \graph [simple necklace layout, grow'=60, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]
  {
    {\foreach \i in {0,...,11} \i,},
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}

示例 3

\end{document}

可以设计自己的算法来控制图形的布局和外观。由于这种方式指定了节点之间的结构关系,因此在绘制图形时可以使用这些信息。

在原始代码中,没有任何内容指定这些结构关系,因此没有任何信息可用于以所需的方式自动化图形的外观。

通过使用\graph,您可以提供结构信息。

是否值得采用这种方法可能取决于您想要以这种方式绘制的图形的数量和复杂程度。

完整代码:

\RequirePackage{luatex85}
\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{graphs,graphdrawing,arrows.meta}
\usegdlibrary{circular}
\begin{document}
\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [clockwise=12, radius=25mm, phase=-120, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]
  {
    {\foreach \i in {0,...,11} \i,},
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}
\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [circular placement, group polar shift=(-30:0), /tikz/>=Stealth, nodes={fill=blue, circle, minimum size=5mm, inner sep=1pt, text=white}]
  {
    a/ [fill=none] -!- \foreach \i in {0,...,11} { a -!- \i },
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}
\begin{tikzpicture}
  [
    my node/.style={<red, >black},
  ]
  \graph [simple necklace layout, grow'=60, /tikz/>=Stealth, nodes={fill=blue, circle, node sep=12.5mm, minimum size=5mm, inner sep=1pt, text=white}]
  {
%     0 -!- \foreach \i in {1,...,11} { 0 -!- \i },
    {\foreach \i in {0,...,11} \i,},
    {1, 9} -> 10 [my node] -> 9,
    {0, 1, 3, 4, 5, 6, 7, 8} -> 11 [my node] -> {4, 5, 6},
    {0, 1, 2, 3, 4, 5, 6} -> 9 -> {4, 7},
    {1, 2, 6} -> 8 -> {4, 6},
    {2, 4} -> 7 -> 4,
    {2, 4, 5} -> 6 -> 4,
  };
\end{tikzpicture}
\end{document}

相关内容