在两个节点之间生成一条由一条水平线和一条垂直线组成的路径很容易(来自手册):
\begin{tikzpicture}
\draw (0,0) node(a) [draw] {A} (1,1) node(b) [draw] {B};
\draw (a.north) |- (b.west);
\draw[color=red] (a.east) -| (2,1.5) -| (b.north);
\end{tikzpicture}
但是,如果我想用相同的简短语法使用一条水平线、一条垂直线和第二条水平线在 (a) 和 (b) 之间生成一条路径,该怎么办?计算中间点并不困难,但如何定义以下语法?
\begin{tikzpicture}
\draw (0,0) node(a) [draw] {A} (3,1) node(b) [draw] {B};
\draw (a.east) -|- (b.west);
\end{tikzpicture}
答案1
这个答案扩展了 Marc van Dongen 的答案。
两种样式为-|-
和,|-|
默认值为0.5
定位中间点(因此,默认为中间点)。
\documentclass[margin=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
-|-/.style={
to path={
(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)
\tikztonodes
}
},
-|-/.default=0.5,
|-|/.style={
to path={
(\tikztostart) |- ($(\tikztostart)!#1!(\tikztotarget)$) -| (\tikztotarget)
\tikztonodes
}
},
|-|/.default=0.5,
}
\begin{document}
\begin{tikzpicture}[thick]
\draw[->,blue] (2.1,1.1) to[|-|] (1.1,0.1);
\draw[->] (2,1) to[-|-] (1,0);
\draw[->,blue] (3.1,0.1) to[|-|] (4.1,1.1);
\draw[->] (3,0) to[-|-] (4,1);
\begin{scope}[yshift=-1.5cm]
\draw[->,red] (2.1,1.1) to[|-|=.2] (1.1,0.1);
\draw[->,orange] (2,1) to[-|-=.2] (1,0);
\draw[->,red] (3.1,0.1) to[|-|=.8] (4.1,1.1);
\draw[->,orange] (3,0) to[-|-=.8] (4,1);
\end{scope}
\end{tikzpicture}
\end{document}
答案2
A此答案的先前版本解释了paths.ortho
图书馆在我pgf
在 GitHub 上的仓库。图书馆现在是我的一部分tikz-ext
包裹应该使用它(并且有一个适当的手册)。
使用ext.paths.ortho
库是可能的。它通过重写和拦截主 TikZ 解析器来工作。(这也是 TikZ 更新或其他库可能会中断的原因,但我希望不会。)
该库引入了六个路径运算符:
- 之字形
|-|
和-|-
;
- 之字形
r-ud
,r-du
,r-lr
和r-rl
。
存在以下键(当这些键直接与路径操作一起使用时,ortho/
应删除前缀,例如-|-[ratio=.3]
)。
ortho/spacing=<ratio>
这设置了之字形连接中间部分的比率。小于 0 和大于 1 的值将导致线条看起来更像之字形路径。
ortho/distance=<distance>
可以使用绝对距离来代替比率,当为时,从起点测量
<distance> ≥ 0
,否则从目标点测量。ortho/from center=<true or false>
(默认true
)当节点连接时,Zig-Zag 和 Zig-Zig(见下文)连接的中间部分的位置将从这些节点的边界计算。如果此键设置为 ,则连接的中间部分将从节点的中心计算
true
。
为 Zig-Zag 和 Zig-Zig 连接设置了新的计时器,可以通过以下键进行配置。
ortho/spacing=<number>
(默认4
)这会影响到扭结的位置,即 1/
<number>
(默认值为 0.25)和<number>
−1/<number>
(默认值为 0.75)。位置 0.5 将始终位于中间部分的中心。位置 0.0 和 1.0 将分别位于起点和终点。当
<number>
设置为0
位置时-1
将在开始时,0
会在第一个弯角处,1
位于第二个拐点处,2
将在最后0.5
仍将是中间部分的中心。
ortho/middle 0 to 1
是 的替代品ortho/spacing=0
。
Zig-Zig 连接解释如下我的答案到如何绘制从节点 3 到节点 1 的返回箭头。
对于to
和edge
连接键
horizontal vertical horizontal
对于-|-
和vertical horizontal vertical
为了|-|
在其他中都已定义。之前,我曾使用|-|
和-|-
作为这些快捷方式,但它们与arrows
规范相冲突,这就是为什么它们不再默认定义的原因。但是,它们可以通过以下方式轻松定义
\tikzset{ortho/install shortcuts}
在其他人中。
代码(问题)
\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{ext.paths.ortho}
\begin{document}
\begin{tikzpicture}[thick, ->]
\draw[blue] (2.1, 1.1) |-| (1.1, 0.1);
\draw (2 , 1 ) -|- (1 , 0 );
\draw[blue] (3.1, 0.1) |-| (4.1, 1.1);
\draw (3 , 0 ) -|- (4 , 1 );
\begin{scope}[yshift=-1.5cm, ortho/ratio=.2]
\draw[red] (2.1, 1.1) |-| (1.1, 0.1);
\draw[orange] (2 , 1 ) -|- (1 , 0 );
\draw[red] (3.1, 0.1) |-|[ratio=.8] (4.1, 1.1);
\draw[orange] (3 , 0 ) -|-[ratio=.8] (4 , 1 );
\end{scope}
\end{tikzpicture}
\end{document}
输出(问题)
答案3
您可以使用 来执行此操作to path
。以下解决方案旨在强调所需的步骤。该解决方案可以绘制连接任何方向,而不仅仅是垂直/水平连接,因此概括了迄今为止提出的所有其他解决方案。
还要注意,该解决方案不包含动画图片,因此您可以专注于提供的输出,而不会受到动画分散注意力的风险:-)
。
该解决方案展示了不太常用的投影修改器($(a)!(b)!(c)$)的良好应用,它将点(b)投影到通过(a)和(c)的无限线上。
读者可以添加自己喜欢的辅助键来绘制水平-垂直-水平连接,或垂直-水平-垂直连接。
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
% The parsing is done relative to the key "/my connection/,
% which is not part of the user-defined API
\pgfkeys{/my connection/.cd,
% Save the angle value.
angle/.store in=\mycon@angle,
% Save the ratio value.
ratio/.store in=\mycon@ratio,
% The draw key triggers the drawing. Should be last.
draw/.style={/tikz/to path={
let % \n{a} is the angle.
\n{a}=\mycon@angle,
% \n{r} is the ratio.
\n{r}=\mycon@ratio,
% \p{s} is the start of the connection.
\p{s}=(\tikztostart),
% \p{t} is the target of the connection.
\p{t}=(\tikztotarget),
% \p{sa} is some point on the line from \p{s} in direction \n{a}.
\p{sa}=($(\p{s})+(\n{a}:1)$),
% \p{st} is some point on the line from \p{t} in direction \n{a}.
\p{st}=($(\p{t})+(\n{a}:1)$),
% \p{proj s} is the projection of \p{s} on the line through \p{t} and \p{st}.
\p{proj s}=($(\p{t})!(\p{s})!(\p{st})$),
% \p{proj t} is the projection of \p{t} on the line through \p{s} and \p{sa}.
\p{proj t}=($(\p{s})!(\p{t})!(\p{sa})$)
in % Second point of connection.
-- ($(\p{s})!\n{r}!(\p{proj t})$)
% Third point of connection.
-- ($(\p{proj s})!\n{r}!(\p{t})$)
% Last point of connection.
-- (\p{t})
\tikztonodes}}}
% The "connection" key is part of the user-defined API key.
% It has two sub-keys: ratio and angle, with default values 0.5
% and 0 respectively. We use the connection key to set the defaults,
% override the user-provided values for the keys (if any), and then
% draw the connection.
\tikzset{connection/.style={/my connection/.cd,ratio=0.5,angle=0,#1,draw}}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw (0,0) coordinate(a) node[anchor=north]{$a$}
(6,3) coordinate(b) node[anchor=south]{$b$};
\draw[->] (a) to[connection] (b);
\draw[blue,->] (b) to[connection={ratio=0.25,angle=30}] (a);
\draw[red,->] (a) to[connection={ratio=0.25,angle=90}] (b);
\end{tikzpicture}
\end{document}
答案4
尝试这个:
\begin{tikzpicture}
\path (0,0) node(a) [draw] {A} -- (3,1) node(b) [draw] {B} coordinate[pos=0.5](inter);
\draw (a) -| (inter) |- (b) ;
\end{tikzpicture}