\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
事先说明几点:
- 自 TikZ/PGF 3.0 版以来,该库
arrows
(和arrows.spaced
) 已弃用。它仍然有效,但新arrows.meta
库提供了更多选项和可靠性。 - 该
? of=?
语法已被弃用(并且实际上不应再使用),另请参阅PGF/TikZ 中“right of=”和“right=of”之间的区别。使用positioning
库和below=? of ?
语法。可以使用选项生成旧键的行为on grid
。 - 我已经使用了该
chains
库(它使我们不再需要重复使用\node
和below=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 进行处理。输出: