![相对于一组节点定位节点](https://linux22.com/image/477250/%E7%9B%B8%E5%AF%B9%E4%BA%8E%E4%B8%80%E7%BB%84%E8%8A%82%E7%82%B9%E5%AE%9A%E4%BD%8D%E8%8A%82%E7%82%B9.png)
我有一组由宏生成的节点,我想将节点定位在这组节点的北、西、南方向。在我的示例中,例如,我想将标记为 的节点定位在由(A)
宏生成的节点组的西边\graphcircuit
,问题是我既不知道生成的图形的大小(即,它取决于传递给宏的列表),也没有某种可以引用的全局节点。
\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\newcommand{\graphcircuit}[1]{
\foreach[count=\n] \v in {#1}; % count the number of elements
\pgfmathsetmacro{\r}{\n*0.2} % set the node distance from (0,0)
\pgfmathsetmacro{\b}{90/\n} % evaluate the bend angle
\foreach[count=\i, evaluate=\i as \a using (\i-1)*360/\n] \v in {#1}
\node [circle, draw, font=\scriptsize] (n-\i) at (\a:\r) {$\v$};
\foreach \i [remember=\i as \j (initially \n)] in {1,...,\n}
\draw[semithick,-stealth] (n-\j) to[bend right=\b] (n-\i);
}
\begin{document}
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1}
\node[font=\normalsize] (A) at (0,0) {(A)};
\end{tikzpicture}
\end{document}
答案1
您可以将整个图形放入一个节点并引用它。而且您不需要库来math
实现这一点。
\documentclass[tikz]{standalone}
\usetikzlibrary{fit}
\newcommand{\graphcircuit}[1]{
\begin{scope}
\def\myfitarray{}
\foreach[count=\n] \v in {#1}; % count the number of elements
\pgfmathsetmacro{\r}{\n*0.2} % set the node distance from (0,0)
\pgfmathsetmacro{\b}{90/\n} % evaluate the bend angle
\foreach[count=\i, evaluate=\i as \a using (\i-1)*360/\n] \v in {#1}
\node [circle, draw, font=\scriptsize] (n-\i) at (\a:\r) {$\v$};
\foreach \i [remember=\i as \j (initially \n)] in {1,...,\n}{
\draw[semithick,-stealth] (n-\j) to[bend right=\b] (n-\i);}
\foreach \x in {1,...,\n}{%
\expandafter\xdef\expandafter\myfitarray\expandafter{\myfitarray (n-\x)}}
\node[inner sep=2pt,fit=\myfitarray] (groupnode) {};
\end{scope}
}
\begin{document}
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1}
\node[font=\normalsize,anchor=south] (A) at (groupnode.north) {(A)};
\node[font=\normalsize,anchor=east] (B) at (groupnode.west) {(B)};
\begin{scope}[shift={(4,5)}]% Another one
\graphcircuit{1:5,7:2,3:0,4:0,9:1}
\node[anchor=north] (C) at (groupnode.south) {(C)};
\node[anchor=north west] (D) at (groupnode.south east) {(D)};
\end{scope}
\end{tikzpicture}
\end{document}
答案2
根据 OP 的代码,第一个节点可以用作全局参考点。这里,位于\s
第一个节点右侧 1 厘米(由宏定义)的标签 (A) 用于节点组的全局参考。设置后,可以使用above, below, right, left= xx cm of A
及其变体来定位其余节点。但是,north, west, south
在本例中,解决方案使用polar coordinate
来放置其余节点。
代码
\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\usetikzlibrary{math,calc,positioning}
\newcommand{\graphcircuit}[1]{
\foreach[count=\n] \v in {#1}; % count the number of elements
\pgfmathsetmacro{\r}{\n*0.2} % set the node distance from (0,0)
\pgfmathsetmacro{\b}{90/\n} % evaluate the bend angle
\foreach[count=\i, evaluate=\i as \a using (\i-1)*360/\n] \v in {#1}
\node [circle, draw, font=\scriptsize] (n-\i) at (\a:\r) {$\v$};
\foreach \i [remember=\i as \j (initially \n)] in {1,...,\n}
\draw[semithick,-stealth] (n-\j) to[bend right=\b] (n-\i);
}
\def\s{1} % determine the location of the global reference
\begin{document}
\centering
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1}
\node[font=\normalsize,xshift=\s cm] (A) at (n-1) {(A)};
\node[font=\normalsize] (B) at (180:\r+\s) {(B)};
\node[font=\normalsize] (C) at (90:\r+\s) {(C)};
\node[font=\normalsize] (D) at (-90:\r+\s) {(D)};
\end{tikzpicture}
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1,1:1,2:2,3:3}
\node[font=\normalsize,xshift=\s cm] (A) at (n-1) {(A)};
\node[font=\normalsize] (B) at (180:\r+\s) {(B)};
\node[font=\normalsize] (C) at (90:\r+\s) {(C)};
\node[font=\normalsize] (D) at (-90:\r+\s) {(D)};
\end{tikzpicture}
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1,1:1,2:2,3:3,1:1,2:2,3:3}
\node[font=\normalsize,xshift=\s cm] (A) at (n-1) {(A)};
\node[font=\normalsize] (B) at (180:\r+\s) {(B)};
\node[font=\normalsize] (C) at (90:\r+\s) {(C)};
\node[font=\normalsize] (D) at (-90:\r+\s) {(D)};
\end{tikzpicture}
\end{document}
答案3
解决方案 2:这是使用 的另一种解决方案local bounding box
。
\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\newcommand{\graphcircuit}[2]{
\begin{scope}[local bounding box=#2]
\foreach[count=\n] \v in {#1}; % count the number of elements
\pgfmathsetmacro{\r}{\n*0.2} % set the node distance from (0,0)
\pgfmathsetmacro{\b}{90/\n} % evaluate the bend angle
\foreach[count=\i, evaluate=\i as \a using (\i-1)*360/\n] \v in {#1}
\node [circle, draw, font=\scriptsize] (n-\i) at (\a:\r) {$\v$};
\foreach \i [remember=\i as \j (initially \n)] in {1,...,\n}
\draw[semithick,-stealth] (n-\j) to[bend right=\b] (n-\i);
\end{scope}
}
\begin{document}
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1}{groupnode}
\foreach \a in {north, east, south, west}
\node[circle, fill=red, inner sep=1pt] at (groupnode.\a) [label={\a:\a}]{};
\end{tikzpicture}
\end{document}
解决方案 1:
这是一个无需库的解决方案fit
,可在节点内绘制图形。我个人更喜欢fit
percusse 的解决方案和我的第二个解决方案。我给出这个是为了完整性。
\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\newcommand{\graphcircuit}[2]{
\node[name=#2]{
\begin{tikzpicture}
\foreach[count=\n] \v in {#1}; % count the number of elements
\pgfmathsetmacro{\r}{\n*0.2} % set the node distance from (0,0)
\pgfmathsetmacro{\b}{90/\n} % evaluate the bend angle
\foreach[count=\i, evaluate=\i as \a using (\i-1)*360/\n] \v in {#1}
\node [circle, draw, font=\scriptsize] (n-\i) at (\a:\r) {$\v$};
\foreach \i [remember=\i as \j (initially \n)] in {1,...,\n}
\draw[semithick,-stealth] (n-\j) to[bend right=\b] (n-\i);
\end{tikzpicture}
};}
\begin{document}
\begin{tikzpicture}
\graphcircuit{1:5,7:2,3:0,4:0,9:1}{groupnode}
\foreach \a in {north, east, south, west}
\node[circle, fill, inner sep=1pt] at (groupnode.\a) [label={\a:\a}]{};
\end{tikzpicture}
\end{document}