我需要沿给定的距离均匀分布两个(或更多)节点,参见下面的 MWE:
\documentclass[tikz]{standalone}
\usetikzlibrary{positioning, calc}
\begin{document}
\begin{tikzpicture}[
text node/.style={rectangle, draw}
]
\small
\begin{scope}
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\node (c) [text node, right=of aa] {This is a rather long node with text};
\node (d) [text node, right=of c] {Short};
\end{scope}
\begin{scope}[shift={(0,-1)}]
\node (ba) at (0,0) {};
\node (bb) at (14,0) {};
\node (c2) [text node] at ($(ba)!0.33!(bb)$) {This is a rather long node with text};
\node (d2) [text node] at ($(ba)!0.66!(bb)$) {Short};
\end{scope}
\foreach \n in {aa, ab, c, d, ba, bb, c2, d2}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\end{tikzpicture}
\end{document}
当简单地将节点彼此相邻放置时,它们显然会在距离的右侧杂乱无章(第一种情况)。因此,我尝试计算它们沿距离的位置,但由于节点大小不同(第二种情况),这种方法失败了。我如何计算节点的位置,以使它们之间的距离和侧面的距离相等?
答案1
本答案分阶段进行。如果您只想要最终代码,请滚动到底部。
概念验证,也许。请注意,节点始终具有维度,即使它们是空的。因此,您的图片具有误导性,因为您没有显示其他节点所处的节点的边界。但是,如果红色标记是相关点,则必须考虑它们的尺寸,因为它们不在节点的边界上。
\documentclass[tikz,multi,border=10pt]{standalone}
\usetikzlibrary{positioning, calc}
\begin{document}
\begin{tikzpicture}[
text node/.style={rectangle, draw, inner sep=2.5pt},
spread two/.code n args=6{%
\pgfmathsetmacro\firstwidth{width("#3")}%
\pgfmathsetmacro\secondwidth{width("#5")}%
\path ($(#6.west)-(#1.east)$) ++(-\firstwidth-\secondwidth-10 pt,0) coordinate (a);
\node (#2) [text node, anchor=west] at ($(#1.east)+1/3*(a)$) {#3};
\node (#4) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#5};
},
]
\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two={aa}{c}{This is a rather long node with text}{d}{Short}{ab}}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\end{tikzpicture}
\end{document}
也许\let
语法可能会提供更方便的方法。
更新
可以在一定程度上实现自动化。例如,我们可以获取 的值,inner xsep
而不需要对其进行硬编码。(上面我使用了2.5pt
。默认值为.3333em
。)
\begin{tikzpicture}[
text node/.style={rectangle, draw},
spread two/.code n args=6{%
\pgfmathsetmacro\firstwidth{width("#3")}% 145.58443 pt for testing below (default inner xsep is .3333em)
\pgfmathsetmacro\secondwidth{width("#5")}% 22.1179 pt
\path ($(#6.west)-(#1.east)$) ++(-\firstwidth-\secondwidth-4*\pgfkeysvalueof{/pgf/inner xsep},0) coordinate (a);
\node (#2) [text node, anchor=west] at ($(#1.east)+1/3*(a)$) {#3};
\node (#4) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#5};
},
]
\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two={aa}{c}{This is a rather long node with text}{d}{Short}{ab}}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\end{tikzpicture}
和以前一样,这给了我们
inner xsep
[由于我没有另行告知,所以这个版本使用默认值,因此略有不同,但仅此而已。]
下面检查一下它是否按照我们的预期运行:
\begin{tikzpicture}[
text node/.style={rectangle, draw},
spread two/.code n args=6{%
\pgfmathsetmacro\firstwidth{width("#3")}%
\pgfmathsetmacro\secondwidth{width("#5")}%
\path ($(#6.west)-(#1.east)$) ++(-\firstwidth-\secondwidth-4*\pgfkeysvalueof{/pgf/inner xsep},0) coordinate (a);
\node (#2) [text node, anchor=west] at ($(#1.east)+1/3*(a)$) {#3};
\node (#4) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#5};
},
]
\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two={aa}{c}{This is a rather long node with text}{d}{Short}{ab}}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\node [red, inner sep=0pt] at (a) {a};
\path ($(ab.west)-(aa.east)$) ++(-167.7pt,0) ++(-1.3333em,0) node [blue,inner sep=0pt] {a};
\node [blue, inner sep=0pt] at ($(aa.east)+1/3*(a)$) {x};
\node [blue, inner sep=0pt] at ($(ab.west)-1/3*(a)$) {x};
\node [blue, inner sep=0pt, xshift=145.58443pt] at ($(aa.east)+1/3*(a)+(.6667em,0)$) {x};
\node [blue, inner sep=0pt, xshift=145.58443pt] at ($(aa.east)+2/3*(a)+(.6667em,0)$) {x};
\end{tikzpicture}
这给了我们
在我们预期的位置显示蓝色标记。
但是,语法还有待改进。因此,我们可能需要修改 的定义,spread two
使其更有意义一些。例如,
\tikzset{%
text node/.style={rectangle, draw},
spread two/.code args={#1 and #2 with contents #3 and #4 between #5 and #6}{%
\pgfmathsetmacro\firstwidth{width("#3")}%
\pgfmathsetmacro\secondwidth{width("#4")}%
\path ($(#6.west)-(#5.east)$) ++(-\firstwidth-\secondwidth-4*\pgfkeysvalueof{/pgf/inner xsep},0) coordinate (a);
\node (#1) [text node, anchor=west] at ($(#5.east)+1/3*(a)$) {#3};
\node (#2) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#4};
},
}
现在我们可以写
\begin{tikzpicture}\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two=c and d with contents {This is a rather long node with text} and {Short} between aa and ab}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\end{tikzpicture}
生产
完整代码:
\documentclass[tikz,multi,border=10pt]{standalone}
\usetikzlibrary{positioning,calc}
\begin{document}
\begin{tikzpicture}[
text node/.style={rectangle, draw},
spread two/.code n args=6{%
\pgfmathsetmacro\firstwidth{width("#3")}% 145.58443 pt for testing below (default inner xsep is .3333em)
\pgfmathsetmacro\secondwidth{width("#5")}% 22.1179 pt
\path ($(#6.west)-(#1.east)$) ++(-\firstwidth-\secondwidth-4*\pgfkeysvalueof{/pgf/inner xsep},0) coordinate (a);
\node (#2) [text node, anchor=west] at ($(#1.east)+1/3*(a)$) {#3};
\node (#4) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#5};
},
]
\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two={aa}{c}{This is a rather long node with text}{d}{Short}{ab}}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\end{tikzpicture}
\begin{tikzpicture}[
text node/.style={rectangle, draw},
spread two/.code n args=6{%
\pgfmathsetmacro\firstwidth{width("#3")}%
\pgfmathsetmacro\secondwidth{width("#5")}%
\path ($(#6.west)-(#1.east)$) ++(-\firstwidth-\secondwidth-4*\pgfkeysvalueof{/pgf/inner xsep},0) coordinate (a);
\node (#2) [text node, anchor=west] at ($(#1.east)+1/3*(a)$) {#3};
\node (#4) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#5};
},
]
\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two={aa}{c}{This is a rather long node with text}{d}{Short}{ab}}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\node [red, inner sep=0pt] at (a) {a};
\path ($(ab.west)-(aa.east)$) ++(-167.7pt,0) ++(-1.3333em,0) node [blue,inner sep=0pt] {a};
\node [blue, inner sep=0pt] at ($(aa.east)+1/3*(a)$) {x};
\node [blue, inner sep=0pt] at ($(ab.west)-1/3*(a)$) {x};
\node [blue, inner sep=0pt, xshift=145.58443pt] at ($(aa.east)+1/3*(a)+(.6667em,0)$) {x};
\node [blue, inner sep=0pt, xshift=145.58443pt] at ($(aa.east)+2/3*(a)+(.6667em,0)$) {x};
\end{tikzpicture}
\tikzset{%
text node/.style={rectangle, draw},
spread two/.code args={#1 and #2 with contents #3 and #4 between #5 and #6}{%
\pgfmathsetmacro\firstwidth{width("#3")}%
\pgfmathsetmacro\secondwidth{width("#4")}%
\path ($(#6.west)-(#5.east)$) ++(-\firstwidth-\secondwidth-4*\pgfkeysvalueof{/pgf/inner xsep},0) coordinate (a);
\node (#1) [text node, anchor=west] at ($(#5.east)+1/3*(a)$) {#3};
\node (#2) [text node, anchor=east] at ($(#6.west)-1/3*(a)$) {#4};
},
}
\begin{tikzpicture}\small
\node (aa) at (0,0) {};
\node (ab) at (14,0) {};
\tikzset{spread two=c and d with contents {This is a rather long node with text} and {Short} between aa and ab}
\foreach \n in {aa, ab, c, d}
\draw[red, shift=(\n.center)] plot[mark=x] coordinates{(0,0)};
\end{tikzpicture}
\end{document}