从 |- 线中间连接

从 |- 线中间连接
\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows}

\begin{document}
\begin{frame}
  \begin{figure}[h]
    \centering
    \begin{tikzpicture}[
      % type of arrow head
      >=stealth',
      % keep arrow head from touching the surface
      shorten >= 1pt,
      % automatic node positioning
      auto,
      % 
      node distance=1.2cm,
      % line thickness
      semithick,
      graybox/.style = {draw=gray!20, fill=gray!20, rounded corners},
      line/.style = {draw=black, thick},
      team/.style = {circle, draw=blue!50, fill=blue!20, minimum size=8mm}
    ]

    \coordinate (O) at (0cm, 0cm);

    % this node is named 'C1' and located at (O). Its style is 'team'
    \node [team] (C1) at (O) {\small 1};
    \node [team] (C2) [below of=C1] {\small 2};
    \node [team] (C3) [below of=C2] {\small 3};
    \node [team] (C4) [below of=C3] {\small 4};
    \node [team] (C5) [below of=C4] {\small 5};

    \path [line] (C5) --++ (1cm, 0cm) |- (C4);

    \end{tikzpicture}
  \end{figure}
\end{frame}
\end{document}

这是我编写的用于生成简单图表的 LaTeX 代码。

在此处输入图片描述

但我真正想要的是这样的东西。

1 --------------+
                |
                |
2 ----------+   |
            |   |
            |   |
3 ------+   +---+
        |   |
        +---+
4 --+   |
    |   |
    +---+
    |
5 --+

我可以使用命令连接 4 和 5 |-,但我不知道如何在这条垂直线的中间标记,然后将其连接到3。在 LaTeX 中绘制上述 ASCII 艺术的最佳方法是什么?

答案1

可以计算出线上的起点。以下示例取垂直线段的中间位置:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}

\begin{document}
\begin{frame}
  \begin{figure}[h]
    \centering
    \begin{tikzpicture}[
      % type of arrow head
      >=stealth',
      % keep arrow head from touching the surface
      shorten >= 1pt,
      % automatic node positioning
      auto,
      % 
      node distance=1.2cm,
      % line thickness
      semithick,
      graybox/.style = {draw=gray!20, fill=gray!20, rounded corners},
      line/.style = {draw=black, thick},
      team/.style = {circle, draw=blue!50, fill=blue!20, minimum size=8mm}
    ]

    \coordinate (O) at (0cm, 0cm);

    % this node is named 'C1' and located at (O). Its style is 'team'
    \node [team] (C1) at (O) {\small 1};
    \node [team] (C2) [below of=C1] {\small 2};
    \node [team] (C3) [below of=C2] {\small 3};
    \node [team] (C4) [below of=C3] {\small 4};
    \node [team] (C5) [below of=C4] {\small 5};

    \path [line] (C5) --++ (1cm, 0cm) coordinate (C45r) |- (C4);
    \path [line] ($(C5)!.5!(C4)$) coordinate (C45m)
                 (C45r |- C45m) --++ (1cm, 0cm) coordinate (C34r) |- (C3);
    \path [line] ($(C45m)!.5!(C3)$) coordinate (C34m)
                 (C34r |- C34m) --++ (1cm, 0cm) coordinate (C23r) |- (C2);
    \path [line] ($(C34m)!.5!(C2)$) coordinate (C23m)
                 (C23r |- C23m) --++ (1cm, 0cm) |- (C1);

    \end{tikzpicture}
  \end{figure}
\end{frame}
\end{document}

结果

答案2

以下是使用以下选项的解决coordinate方案pos

另一个有趣的例子是水平/垂直线到操作 |- 和 -|。对于它们来说,位置(或时间) 0.5 恰好是角点。

(摘自 pgfmanual,第 236 页,第 17.8 节“明确地将节点放置在直线或曲线上”)

之后|-,通过位置0.25,您可以获得垂直线的中间位置。

在此处输入图片描述

\documentclass[tikz,margin=2mm]{standalone}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}[
  % type of arrow head
  >=stealth',
  % keep arrow head from touching the surface
  shorten >= 1pt,
  % automatic node positioning
  auto,
  % 
  node distance=1.2cm,
  % line thickness
  semithick,
  graybox/.style = {draw=gray!20, fill=gray!20, rounded corners},
  line/.style = {draw=black, thick},
  team/.style = {circle, draw=blue!50, fill=blue!20, minimum size=8mm}
  ]
  
  \coordinate (O) at (0cm, 0cm);
  % this node is named 'C1' and located at (O). Its style is 'team'
  \node [team] (C1) at (O) {\small 1};
  \node [team] (C2) [below of=C1] {\small 2};
  \node [team] (C3) [below of=C2] {\small 3};
  \node [team] (C4) [below of=C3] {\small 4};
  \node [team] (C5) [below of=C4] {\small 5};
  \path [line]    (C5) --++ (1cm, 0cm) |- coordinate[pos=.25] (r-4-5) (C4);
  \path [line] (r-4-5) --++ (1cm, 0cm) |- coordinate[pos=.25] (r-3-4) (C3);
  \path [line] (r-3-4) --++ (1cm, 0cm) |- coordinate[pos=.25] (r-2-3) (C2);
  \path [line] (r-2-3) --++ (1cm, 0cm) |- (C1);
  
\end{tikzpicture}
\end{document}

答案3

事先说明几点:

  1. 自 TikZ/PGF 3.0 版以来,该库arrows(和arrows.spaced) 已弃用。它仍然有效,但新arrows.meta库提供了更多选项和可靠性。
  2. ? of=?语法已被弃用(并且实际上不应再使用),另请参阅PGF/TikZ 中“right of=”和“right=of”之间的区别。使用positioning库和below=? of ?语法。可以使用选项生成旧键的行为on grid
  3. 我已经使用了该chains库(它使我们不再需要重复使用\nodebelow=of有人可能会说这甚至chains已经“过时”了,而新graphs库的功能要强大得多(有些人可能是正确的)。我为graphs库添加了一个示例。在选项中添加边缘路径\graph和/或将其作为graphs库的一部分则留给读者。

的确,看来我的 udlr 家人似乎可以帮上忙。你需要这些文件

在您的 texmf 树中或 LaTeX 可以找到它们的其他位置(.tex例如在与您的主文件相同的文件夹中)。

除其他外,它允许您使用r-rl路径运算符,这意味着在两个坐标之间绘制正交连接,从第一个坐标开始,向右,r然后向上或向下,然后l向左到目标坐标(或节点)。您可以写入r-rl[distance=?]以更改节点/坐标与路径垂直部分之间的距离(默认值:0.5 厘米)。该选项from center添加从节点中心(而不是其边界)的距离。

在您的示例中,我为最后一个节点添加了一个附加(辅助)名称,并在coordinate (@)连接上添加了一个坐标,这使我可以\path重复使用相同的规范。此@坐标(默认pos=.5)位于r-rl连接垂直部分的中间。

所有这些选项以及它们如何影响路径上节点/坐标的放置,将在我的答案pgf-tikz 中的垂直线和水平线


如果您仍想使用|-,我建议您使用to path如下定义的:

rl/.style={
  near start,
  to path={(\tikztostart) -- ++(#1,0) |- (\tikztotarget) \tikztonodes}},
rl/.default=.5

然后你就可以轻松地做到

\foreach \i in {4,...,1}
  \path (@.east) edge[line, rl] coordinate (@) (ch-\i);

请注意,您必须这样做.east,否则第一个连接会更接近和4节点5,因为距离++(X, Y)是从节点中心计算的。(坐标只是一个点,因此.east锚点与没有锚点的坐标相同。)

样式rl还设置了near start(的快捷方式pos=.25),以便它自动使用垂直部分中间的点。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{paths.ortho, chains, graphs}
\begin{document}
\begin{tikzpicture}[
  shorten >= 1pt, node distance=.4cm, semithick,
  line/.style = {draw=black, thick},
  team/.style = {circle, draw=blue!50, fill=blue!20, minimum size=8mm},
]
\begin{scope}[start chain=ch going below]
\foreach \i in {1,...,5} \node [on chain, team] {\small \i};
\end{scope}
\path (ch-end) [late options={alias=@}];
\foreach \i in {4,...,1}
  \path[line] (@) r-rl coordinate (@) (ch-\i);
\end{tikzpicture}
\begin{tikzpicture}[
  shorten >= 1pt, semithick,
  line/.style = {draw=black, thick},
  team/.style = {circle, draw=blue!50, fill=blue!20, minimum size=8mm}
]
\graph[name=C, branch down sep=.4cm, typeset=\small\tikzgraphnodetext, nodes=team]
  {\foreach \i in {1,...,5}{\i}};
\path (C 5) [late options={alias=@}];
\foreach \i in {4,...,1}
  \path[line] (@) r-rl coordinate (@) (C \i);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案4

对于可能感兴趣的人,这里有一个 MetaPost 解决方案,借助该boxes包。

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
  \mplibtextextlabel{enable}
\begin{document}
  \begin{mplibcode}
    input boxes; input mpcolornames;
    beginfig(1); 
      % circular boxes: definitions
      boxjoin(a.s - b.n = (0, .5cm)); circmargin := 3mm;
      for i = 1 upto 5:
        circleit.c[i]("\sffamily" & decimal i);
      endfor
      % circular boxes: drawings
      for i = 1 upto 5:
        fill bpath c[i] withcolor .25[white,blue];
        draw bpath c[i] withcolor blue;
        drawunboxed(c[i]);
      endfor
      % connexions defined and drawn iteratively
      h := .75cm; o := h;
      pair A, B, C, D; A = c4.e ; B = A + (h, 0); C = D + (h, 0); D = c5.e;
      draw A + (pt, 0) -- B -- C -- D;
      for i = 3 downto 1:
        h := h + o;
        D := .5[B, C]; A := c[i].e; B := A + (h, 0); C := D + (o, 0);
        draw A + (pt, 0) -- B -- C -- D;
      endfor 
    endfig; 
  \end{mplibcode}
\end{document}

使用 LuaLaTeX 进行处理。输出:

在此处输入图片描述

相关内容