我正在尝试用 Tikz 树描绘牛顿有限差分法。不幸的是,几个节点加倍了。这种方法是错误的还是有解决方案?
\documentclass{article}
\usepackage{tikz}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{0pt}%
\tikzset{root/.style={align=center,draw=none},level 2/.style={align=center,left=1.5cm}}
\begin{document}
\begin{tikzpicture}[grow=left,
level 1/.style={sibling distance=15mm},edge from parent/.style={<-,draw},>=latex]
\node[root] {$\delta_{[x_0,x_1,x_2,x_3]}$}
child {node[level 2] (c1) {$\delta_{[x_0,x_1,x_2]}$}
child {node[level 2] (c11) {$\delta_{[x_0,x_1]}$}
child {node[level 2] (c111) {$\delta_{[x_0]}$}}
child {node[level 2] (c112) {$\delta_{[x_1]}$}}
}
child {node[level 2] (c12) {$\delta_{[x_1,x_2]}$}
}
}
child {node[level 2] (c2) {$\delta_{[x_1,x_2,x_3]}$}
child {node[level 2] (c21) {$\delta_{[x_1,x_2]}$}}
child {node[level 2] (c22) {$\delta_{[x_2,x_3]}$}
child {node[level 2] (c221) {$\delta_{[x_2]}$}}
child {node[level 2] (c222) {$\delta_{[x_3]}$}}
}
};
\end{tikzpicture}
\end{document}
例如,节点 c12 和 c21 相同。我想保留它们两个,而不绘制其中一个。
答案1
以下是两个使用 的解决方案chains
。
第二种解决方案是逐列构建图表,并使用四条链(最后一条链仅包含一个节点)。所有链向下(“下方”)。边缘是手动绘制的。
第一个解决方案(我发现它稍微流畅一些)使用了八条链。其中四条链从左下(“左下方”)开始,另外四条链从左上(“左上方”)。边缘是连接,并自动绘制。由于所有节点都属于两条链,因此\chainin
使用宏。
有一个烦恼:左下(“左下方”)链的第一个节点需要它chain on
在左上链上,所有其他节点都相反。(或者我太头晕了,看不到一个直接的解决方案。)
由于解决方案使用不同的放置选项,节点距离也不同(首先是因为一个解决方案仅使用垂直放置,而另一个解决方案使用垂直和水平放置,其次是因为我xshift*
在第二个解决方案中的方法)。不过,这个问题可以解决……不知何故。
我添加了微小的蓝色标签来突出显示节点的名称。
答案一
代码
\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{positioning,chains,backgrounds}
\newcommand*{\toplevel}{3}
\newcommand*{\base}{\delta}
\newcommand*{\bbase}{x}
\newcommand*{\nodeOnTwoChains}[2]{% shortcut to clean up the loop and to deal better with two chains
\node[on chain=#1,
label={[font=\tiny,blue,label distance=-2mm]below:c-\level-\llevel}
] (c-\level-\llevel)
{$\base_{[\foreach \bbbase in {\llevel,...,\lastlevel} {\ifnum\bbbase=\llevel\else,\fi\bbase_{\bbbase}}]}$};
\chainin (c-\level-\llevel) [on chain=#2];
}
\begin{document}
\begin{tikzpicture}[gridded,
node distance=0cm and 1.5cm,
start chain/.list/.expanded={0 going below left,... going below left,\toplevel\space going below left},
start chain/.list/.expanded={0' going above left,...' going above left,\toplevel' going above left},
every join/.append style={latex-},
every on chain/.style={join},
]
\foreach \level[evaluate={\lastlevel=int(\toplevel-\level)}] in {0,...,\toplevel} {
\foreach \llevel in {0,...,\lastlevel} {
\ifnum\llevel=0
\nodeOnTwoChains{\llevel'}{\level}
\else
\nodeOnTwoChains{\level}{\llevel'}
\fi
}
}
\end{tikzpicture}
\end{document}
输出
答案二
当我开始回答这个问题时这并不是我所期待的。
当然有很多方法可以解决这个问题。我想到了 CVS 版本的图形绘制库(它可以 a) 绘制子节点有多个父节点的图形,并且 b) 更好地放置节点),但由于下标也有一些规则,我将其包裹在两个\foreach
循环中。
每列中的节点与库一起放置(这与更新时重复chains
使用大致相同)。below=of \tikzchainprevious
\tikzchainprevious
positioning-plus
图书馆可以轻松使用已指定的node distance
(或其中的一部分),而无需将其存储在某个宏中。它仅用于xshift*
模拟below right
一半垂直距离和一倍水平距离的选项。
另一种链排列方式可能更好。特别是因为它可以使用选项,join
但人们可能必须做很多\chainin
工作,因为链在每个方向的每个节点上都会分裂。使用两个边来手动操作似乎更容易。
代码
\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{positioning-plus,chains,backgrounds}
\newcommand*{\toplevel}{3}
\newcommand*{\base}{\delta}
\newcommand*{\bbase}{x}
\begin{document}
\begin{tikzpicture}[gridded,
node distance=.5cm and 1.5cm,
start chain/.list/.expanded={0 going below,... going below,\toplevel\space going below},
every edge/.append style={latex-}
]
\coordinate (@aux) at (0,0);
\foreach \level in {0,...,\toplevel} {
\ifnum\level>0
\path (c-\number\numexpr\level-1\relax-\number\numexpr\level-1\relax.south east) -- coordinate[pos=.5] (@aux) (c-\number\numexpr\level-1\relax-\level.north east);
\tikzset{shift={([xshift*]@aux)}}
\fi
\foreach \llevel[evaluate={\lllevel=int(\llevel-\level)}] in {\level,...,\toplevel} {
\node[on chain=\level,
label={[font=\tiny,label distance=-2mm,blue]below:c-\level-\llevel}
] (c-\level-\llevel) {$\base_{[\foreach \bbbase in {\lllevel,...,\llevel} {\ifnum\bbbase=\lllevel\else,\fi\bbase_{\bbbase}}]}$};
\ifnum\level>0
\path (c-\level-\llevel) edge (c-\number\numexpr\level-1\relax-\number\numexpr\llevel-1\relax)
edge (c-\number\numexpr\level-1\relax-\llevel);
\fi
}
}
\end{tikzpicture}
\end{document}