我刚开始使用 TikZ 制作基本图表,并尝试重现彼得森图表。我设法在不使用 for 循环的情况下完成了此操作,但对于较大的示例,这显然不是一种好方法。
目前,我的新代码为:
\begin{tikzpicture}
\foreach \x in {1,...,5}{
\pgfmathparse{(\x-1)*360/5+90}
\node[draw,circle,inner sep=8pt] (\x) at (\pgfmathresult:120pt) [semithick] {};
}
\foreach \x in {1,...,5}{
\pgfmathparse{(\x-1)*360/5+90}
\node[draw,circle,inner sep=8pt] (5+\x) at (\pgfmathresult:60pt) [semithick] {};
}
\end{tikzpicture}
这可行,但并不完整。但是,我意识到第二组五个节点的编号不是 而是6, ... , 10
,5+1, ... , 5+5
这不是我想要的。我尝试使用\pgfmathparse{int(5+\x)}\pgfmathresult
而不是5+\x
,但这会导致错误。奇怪的是(至少对我来说),如果我\pgfmathparse{int(5+\x)}\pgfmathresult
在第二个循环的末尾放入空括号,它会很乐意将数字 6、...、10 放入圆圈中,所以我不明白为什么我的方法不起作用。
我做错了什么?为什么它不起作用?
编辑:新代码:
\begin{tikzpicture}
\foreach \i[evaluate={\angle=(\i)*360/5+90}] in {0,...,4}
{
\node[draw,circle,inner sep=8pt] (\i) at (\angle:120pt) [semithick] {};
}
\foreach \i[evaluate={\angle=(\i)*360/5+90}, evaluate={\Name=int(\i+5)}] in {0,...,4}
{
\node[draw, circle,inner sep=8pt] (\Name) at (\angle:60pt) [semithick] {};
}
\foreach \i in {0,...,4}
{
\pgfmathparse{int(mod(\i+1,5))}
\draw[-] (\i) -- (\pgfmathresult);
}
\foreach \i in {0,...,4}
{
\pgfmathparse{int(mod(\i,5)+5)}
\draw[-] (\i) -- (\pgfmathresult);
}
\foreach \i in {5,...,9}
{
\pgfmathparse{int(mod(\i+2,5)+5)}
\draw[-] (\i) -- (\pgfmathresult);
}
\end{tikzpicture}
答案1
最简单的方法是计算名称以及角度作为循环的选项\foreach
。
.pgfmath
您可能还对处理程序以及.pgfmath int
函数strcat
(及其处理程序)感兴趣。
该strcat
函数将文本输入(包含在一对中"
)和/或数学输入组合在一起作为一个“字符串”。我们可以使用它来创建名称,如敲击‘回答n-6
,以、n-7
等形式构建名称。
chains
不过,在代码 3 中我展示了如何使用库和nodes around center
完全处理定位的自定义样式让您的生活变得更轻松。
join
这些线是在外部链上的初始节点定位循环中绘制的,并且\draw
在链上的节点之间使用单个命令。内部链上节点之间的线使用与原始代码中类似的循环。外部链上最后一个节点和第一个节点之间的最终线是手动绘制的。
使用宏\numberOfNodes
是为了让您不需要5
在代码中重复数字(或任何您想要使用的内容)。
引用;你不能(或者甚至不需要)\pgfmath…
在大多数路径元素中使用
代码 1
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \x[evaluate={\angle=(\x-1)*360/5+90}, evaluate={\Name=int(\x+5)}] in {1,...,5}
\node[draw, circle] (\Name) at (\angle:60pt) {\x};
\end{tikzpicture}
\end{document}
代码 2
\documentclass[tikz]{standalone}
\makeatletter
\pgfkeys{/handlers/.pgfmath/.code=\pgfmathparse{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\pgfkeys{/handlers/.pgfmath int/.code=\pgfmathparse{int(#1)}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\pgfkeys{/handlers/.pgfmath strcat/.code=\pgfmathparse{strcat(#1)}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\pgfmathdeclarefunction{strcat}{...}{%
\begingroup
\let\pgfmathresult\pgfutil@empty
\pgfmathstrcat@@#1\pgfmath@stop}
\def\pgfmathstrcat@@#1{%
\ifx\pgfmath@stop#1%
\let\pgfmath@next\pgfmathstrcat@@@
\else
\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult#1}%
\let\pgfmath@next\pgfmathstrcat@@
\fi
\pgfmath@next}
\def\pgfmathstrcat@@@{\pgfmath@smuggleone\pgfmathresult\endgroup}
\makeatother
\begin{document}
\begin{tikzpicture}
\foreach \x[evaluate={\angle=(\x-1)*360/5+90}] in {1,...,5}
\node[draw, circle, name/.pgfmath strcat={"n-",int(\x+5)}] at (\angle:60pt) {\pgfmathprint{strcat("n-",int(\x+5)}};
\end{tikzpicture}
\end{document}
代码 3
\documentclass[tikz]{standalone}
\usetikzlibrary{chains}
\tikzset{
nodes around center/.style args={#1:#2:#3:#4}{% #1 = start angle, #2 = number of nodes
% #3 = center, #4 = distance
at={(#3)},shift={({(\tikzchaincount-1)*360/(#2)+#1}:{#4})}}}
\begin{document}
\begin{tikzpicture}[
start chain=inner placed {nodes around center=90:\numberOfNodes:{0,0}:60pt},
start chain=outer placed {nodes around center=90:\numberOfNodes:{0,0}:120pt}
]
\newcommand*{\numberOfNodes}{5}
\foreach \cnt in {1,...,\numberOfNodes} {
\node[draw, circle, inner sep=+0pt, minimum size=+20pt, on chain=inner] {};
\node[draw, circle, inner sep=+0pt, minimum size=+20pt, on chain=outer, join] {};
\draw (inner-\cnt) -- (outer-\cnt);
}
\foreach \cnt[evaluate={\nextCnt=int(mod(\cnt+2,\numberOfNodes)+1)}] in {1,...,\numberOfNodes}
\draw (inner-\cnt) -- (inner-\nextCnt);
\draw (outer-end) -- (outer-begin);
\end{tikzpicture}
\end{document}
输出 3
答案2
您还必须对节点名称使用宏。您不能再次使用,\pgfmathparse
因为结果保存在\pgfmathresult
宏中,并且它会覆盖您获得的其他操作。因此您必须使用它\pgfmathtruncatemacro
来定义自己的宏。
圆圈的尺寸不一样,因为里面的文本的尺寸也不相同,但我添加它们只是为了向您显示节点具有正确的名称。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,5}{
\pgfmathparse{(\x-1)*360/5+90}
\node[draw,circle,inner sep=8pt] (\x) at (\pgfmathresult:120pt) [semithick] {};
}
\foreach \x in {1,...,5}{
\pgfmathsetmacro\macroa{(\x-1)*360/5+90}
\pgfmathtruncatemacro\macrob{5+\x}
\node[draw,circle,inner sep=8pt] (\macrob) at (\macroa:60pt) [semithick] {\macrob};
}
\end{tikzpicture}
\end{document}
答案3
不要使用独立数字作为节点名称,我找不到最好的示例,但这会给调试带来不必要的麻烦。此外,您将无法使用角度锚点,例如 6.45 不是右上角的锚点。它只是一个数字。使用带有字母的名称,例如 n-3 等。
对于简单的操作,使用计数器或评估表达式。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x[count=\xi from 6] in {1,...,5}{
\pgfmathparse{(\x-1)*360/5+90}
\node[draw,circle] (n-\xi) at (\pgfmathresult:60pt) [semithick] {\xi};
}
\end{tikzpicture}
\end{document}