我应该如何在 Tikz 中绘制具有多个分支的路径?该draw
命令仅提供一维路径。有没有办法自然地合并它们?
我的想法:
通常我会简单地组合多个draw
命令。但是对于虚线等,绘制在连接点处失败。
最小工作示例:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% way 1: only draw missing part
\draw[dashed,->] (0,0) -- (1,0) -- (1,1);
\draw[dashed] (2.5,0) -- (1,0);
\end{tikzpicture}
\vspace{1em} % dummy space
\begin{tikzpicture}
% way 2: draw full path
\draw[dashed,->] (0,0) -- (1,0) -- (1,1);
\draw[dashed,->] (2.5,0) -- (1,0) -- (1,1);
\end{tikzpicture}
\end{document}
两种情况下的结果都很难看:
答案1
这是对我在这个问题下的评论的一些解释;
\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (10.9pt,0);
\coordinate (c) at (1,0);
\draw[densely dashed,->] (a) -| ($(b)+(0,1)$);
\draw[->] %
let \p1=($(a)-(b)$), % the cornering point carried to origin
\n1={mod(veclen(\x1,\y1),5pt)>3?%length of the cornering path up to
3-mod(veclen(\x1,\y1),5pt):% corner modulo dash on pattern
mod(veclen(\x1,\y1),5pt))
}
in [densely dashed,dash phase=\n1] (b) -- (c);
\end{tikzpicture}
\end{document}
对于5pt
,我知道什么是密集虚线图案,但你可以事先定义所有这些。但我仍然认为,对于一般路径,这是不可能的。一个直接的原因是,第二条路径不知道第一条路径的存在。因此,真正的路径合并不可能开箱即用。
有关如何快速获取虚线图案长度的参考,
\tikzstyle{ultra thin}= [line width=0.1pt]
\tikzstyle{very thin}= [line width=0.2pt]
\tikzstyle{thin}= [line width=0.4pt]
\tikzstyle{semithick}= [line width=0.6pt]
\tikzstyle{thick}= [line width=0.8pt]
\tikzstyle{very thick}= [line width=1.2pt]
\tikzstyle{ultra thick}= [line width=1.6pt]
\tikzstyle{solid}= [dash pattern=]
\tikzstyle{dotted}= [dash pattern=on \pgflinewidth off 2pt]
\tikzstyle{densely dotted}= [dash pattern=on \pgflinewidth off 1pt]
\tikzstyle{loosely dotted}= [dash pattern=on \pgflinewidth off 4pt]
\tikzstyle{dashed}= [dash pattern=on 3pt off 3pt]
\tikzstyle{densely dashed}= [dash pattern=on 3pt off 2pt]
\tikzstyle{loosely dashed}= [dash pattern=on 3pt off 6pt]
\tikzstyle{dashdotted}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{dash dot}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{densely dashdotted}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{densely dash dot}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{loosely dashdotted}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt]
\tikzstyle{loosely dash dot}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt]
\tikzstyle{dashdotdotted}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{densely dashdotdotted}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{loosely dashdotdotted}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt]
\tikzstyle{dash dot dot}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{densely dash dot dot}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{loosely dash dot dot}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt]
答案2
这不是标准解决方案,但解决上述一些简单情况的一种方法是从重叠侧开始绘图:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% way 3: start drawing at overlapping point
\draw[dashed,<-] (1,1) -- (1,0) -- (0,0);
\draw[dashed,<-] (1,1) -- (1,0) -- (2.5,0);
\end{tikzpicture}
\end{document}
但对于一般情况,这个问题仍然没有得到令人满意的答案。
答案3
解决这个问题最简单的方法似乎是画三条线,都从 (1,1) 开始。这样可以得到:
tex 代码:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% way 2: draw full path
\draw[dashed,->] (1,0) -- (1,1);
\draw[dashed,->] (1,0)--(2.5,0);
\draw[dashed,->] (1,0)--(0,0);
\end{tikzpicture}
\end{document}
答案4
经过一番思考:每条分支路径都可以解释为分支点/连接点处有节点的图。
情况1: 我们有一个无循环图。
在这种情况下,图表可以解释为一棵树(简单图论)。因此,人们可以轻松地按照我的第一个答案开始在树的根节点处绘制所有路径。然后,冲刺的所有周期都将同步。
案例 1 的示例:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% spanning tree starting from some root node (here: (0,0))
\draw[dashed,->] (0,0) -- (1,1) -- (2,1) -- (4,2);
\draw[dashed,->] (0,0) -- (1,1) -- (0,2);
\draw[dashed,->] (0,0) -- (1,1) -- (2,1) -- (3,0) -- (4,0);
\end{tikzpicture}
\end{document}
案例 2: 图中恰好有 1 个循环
在这种情况下,必须确保虚线相位乘以某个自然数可得出环的(欧几里得)长度。完成此操作后,我们可以简单地使用生成树(加上一条闭合环的边)来实现无矛盾的虚线路径。由于相位适合环长度,因此在添加“闭合边”时不会产生矛盾。
算法文字说明:
- 计算循环的欧几里得长度大号。
- 将边缘相位设置为数字液氮, 在哪里否是一个自然数(描述闭合循环的#edges);请在此处关注 percusse 的回答。
- 从环中移除 1 条边。
- 使用案例 1 中的算法绘制剩余的树(=无环图)。
- 绘制另一条路径(从步骤 4 的根音开始)以闭合循环。
情况 2 的示例:
\documentclass{article}
\usepackage{tikz}
\begin{document}
% loop has length 2 + 2*sqrt(2) = 4.8284...
% N = 20 => (2+2*sqrt(2))/20 = 0.2414
\begin{tikzpicture}[x=1cm,y=1cm]
% spanning tree starting from some root node (here: (0,0))
\tikzstyle{dashed}=[dash pattern=on 0.15cm off 0.0914cm] % 0.15 + 0.0914 = 0.2414
\draw[dashed] (0,0) -- (1,1) -- (2,1) -- (4,2);
\draw[dashed] (0,0) -- (1,1) -- (0,2);
\draw[dashed] (0,0) -- (1,1) -- (2,1) -- (3,0) -- (4,0);
% closing edge
\draw[dashed] (0,0) -- (1,1) -- (0,2) -- (0,0);
\end{tikzpicture}
\end{document}
编辑:由于循环问题,我不得不修改我的算法和标准,因为循环在稍后移除边后不会给出可能的根节点。我将添加有关此问题的信息...
案例三: 我们有一个包含多个循环的图
一般情况下,这种情况是不可能实现的。简单反例:
在这种情况下,我们有一个长度为4以及长度为2+平方根(2)在所有连接点上没有矛盾意味着存在自然数n和钾,一方面,破折号阶段可以写成4/n另一方面(2+sqrt(2))/k. 这是矛盾的,因为4/n是有理数,但是(2+sqrt(2))/k不是。
那么,在多重循环的情况下,一切都会丢失吗?不是。在(罕见)情况下,您可以为所有循环找到一致的破折号阶段,您只需扩展案例 2 中的算法即可。在所有其他情况下,我将继续以独立路径绘制所有边缘,就像 Andrew 在他的帖子中所建议的那样(尽管这会导致破折号阶段略有不同,并且在连接点处出现(可接受的)不一致)。另一种选择:您也可以尝试找到适合您目的的良好近似值。
未来的工作:
- 应该为情况 1 提供一个一体化命令。这并不难。
- 更难的是:为情况 2 提供命令。