如何使 Tikz 树节点弧不互相交叉?

如何使 Tikz 树节点弧不互相交叉?

我正在尝试在 Tikz 中构建一棵树(主题是论证理论,其中论点互相攻击和辩护),但是在树的几个级别之后,节点被放置在彼此的顶部,或者以到其父节点的弧相互交叉的方式放置。

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{arrows}
\tikzset{
  every node/.style={minimum size=4mm, inner sep=0.5mm, font=\sffamily},
  level 1/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 2/.style={every child/.style={edge from parent/.style={draw,green}}},
  level 3/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 4/.style={every child/.style={edge from parent/.style={draw,green}}},
  level 5/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 6/.style={every child/.style={edge from parent/.style={draw,green}}},
  def/.style={circle,thick,solid,draw=green!50,fill=green!20},
  att/.style={circle,thick,solid,draw=red!50,fill=red!20}
}
\begin{document}

\begin{tikzpicture}[<-,>=stealth', semithick]

  \node[def, label=east:defense] {}
    child[level distance=11mm] { node[att, label=east:attack] {}
      child {node[def, label=east:defense] {}
        child { node[att, label=east:attack] {} }
        child { node[att, label=east:attack] {} }
      }
      child {node[def, label=east:defense] {} 
        child {node[att, label=east:attack] {}}
        child {node[att, label=east:attack] {}}
      }
      child {node[def, label=east:defense] {}
        child {node[att, label=east:attack] {} }
        child {node[att, label=east:attack] {} }
        child {node[att, label=east:attack] {} }
      }
  }; 
\end{tikzpicture}

\end{document}

结果如下:

弧线互相交叉

可以看到,在最底层,中间两个节点的弧不可避免地会交叉。此外,最底层第一个节点之后的两个节点是相互叠放的。

是否有一个“随意调整节点之间的距离,以便它们之间的弧线不交叉,节点不会出现在彼此之上”的命令可供我使用?非常感谢您的帮助,我希望这不是一个重复的问题,因为我找不到类似的问题!

答案1

这是展示forest包;标签和着色是根据级别的条件测试自动完成的:

\documentclass{article}
\usepackage{forest}

\begin{document}

\begin{forest}
for tree={
  edge={<-,>=latex},
  l sep=1cm,
  circle,
  minimum size=12pt,
  anchor=west,
  where={iseven(level)}
    {edge={green},
      draw=green!50,
      fill=green!20,
      edge label={node[anchor=west,right,font=\sffamily,xshift=7pt,yshift=1pt]{\color{black}defense}}
    }
    {edge={red},
      draw=red!50,
      fill=red!20,
      edge label={node[anchor=west,font=\sffamily,xshift=7pt,yshift=1pt]{\color{black}attack}}
    },
  if={level>1}
    {s sep=1.3cm}
    {}
}
[,tikz={\node[pos=0,font=\sffamily,anchor=west,xshift=12pt,yshift=1pt]{defense};}
  [,s sep=1.85cm
    [ [] [] ]
    [ [] [] ]
    [ [] [] [] ]
  ]
]
\end{forest}

\end{document}

在此处输入图片描述

由于标记和着色是根据节点级别的条件测试自动完成的,因此相同的序言for tree规范适用于

[,tikz={\node[pos=0,font=\sffamily,anchor=west,xshift=12pt,yshift=1pt]{defense};}
  [,s sep=1.85cm
    [ [ [] [] ] [] ]
    [ [ [] [] ] [] ]
    [ [ [] [] ] [] [ [] [] ] ]
  ]
]

将生产

在此处输入图片描述

答案2

您可以为每个级别设置不同的兄弟距离

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{arrows}
\tikzset{
  every node/.style={minimum size=4mm, inner sep=0.5mm, font=\sffamily},
  level 1/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 2/.style={every child/.style={edge from parent/.style={draw,green}},
    sibling distance=12em},
  level 3/.style={every child/.style={edge from parent/.style={draw,red}},
    sibling distance=5em},
  def/.style={circle,thick,draw=green!50,fill=green!20,label={right:defense}},
  att/.style={circle,thick,draw=red!50,fill=red!20,label={#1:attack}},
  att/.default=right
}
\begin{document}

\begin{tikzpicture}[<-,>=stealth']
  \node[def] {}
    child[level distance=11mm] { node[att={[yshift=1mm]right}] {}
      child {node[def] {}
        child { node[att] {} }
        child { node[att] {} }
      }
      child {node[def] {} 
        child {node[att] {}}
        child {node[att] {}}
      }
      child {node[def] {}
        child {node[att] {} }
        child {node[att] {} }
        child {node[att] {} }
      }
  }; 
\end{tikzpicture}
\end{document}

在此处输入图片描述


或者使用graphdrawing库(需要 pgf/tikz 版本 3.0.0 和 LuaLaTeX):

\documentclass[margin=5mm,tikz]{standalone}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{trees}
\usetikzlibrary{arrows}
\tikzset{
  every node/.style={minimum size=4mm, inner sep=0.5mm},
  def/.style={circle,thick,solid,draw=green!50,fill=green!20,label={right:defense}},
  att/.style={circle,thick,solid,draw=red!50,fill=red!20,label={#1:attack}},
  att/.default=right
}

\begin{document}
\begin{tikzpicture}[>=stealth',font=\sffamily]
  \graph[tree layout,empty nodes]{
    {[trie]a[def]<-[red]a[att={[yshift=1mm]right}]<-[green]{[nodes=def]a,b,c},},
    {[nodes=att,edges=red,trie,sibling distance=\widthof{attack\qquad}]
      a a a<-{a,b},
      a a b<-{a,b},
      a a c<-{a,b,c},
    }
  };
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案3

添加sibling distance会使事情稍微扩散一些。

\documentclass{standalone}
\usepackage{tikz}

\usetikzlibrary{arrows}
\tikzset{
  every node/.style={minimum size=4mm, inner sep=0.5mm, font=\sffamily},
  level 1/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 2/.style={every child/.style={edge from parent/.style={draw,green}}},
  level 3/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 4/.style={every child/.style={edge from parent/.style={draw,green}}},
  level 5/.style={every child/.style={edge from parent/.style={draw,red}}},
  level 6/.style={every child/.style={edge from parent/.style={draw,green}}},
  def/.style={circle,thick,solid,draw=green!50,fill=green!20},
  att/.style={circle,thick,solid,draw=red!50,fill=red!20}
}
\begin{document}

\begin{tikzpicture}[<-,>=stealth', semithick,sibling distance=10em]
  \node[def, label=east:defense] {}
    child[level distance=11mm] { node[att, label=east:attack] {}
      child {node[def, label=east:defense] {}
        child { node[att, label=east:attack] {} }
        child { node[att, label=east:attack] {} }
      }
      child {node[def, label=east:defense] {} 
        child {node[att, label=east:attack] {}}
        child {node[att, label=east:attack] {}}
      }
      child {node[def, label=east:defense] {}
        child {node[att, label=east:attack] {} }
        child {node[att, label=east:attack] {} }
        child {node[att, label=east:attack] {} }
      }
  }; 
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容