对于我正在处理的文档,我希望能够绘制多边形图。这些图将用从0
到的整数标记n - 1
,其中 n 为某个整数。我想编写一个宏,当提供边数(n)和图的“半径”(每个顶点与中心的距离)时,可以在 tikzpicture 中调用该宏来绘制这样的图。事实证明这是一次非常令人沮丧的经历,因为尝试在 TikZ 中使用涉及宏参数的数学表达式\foreach
并不简单,并且会导致许多令人困惑的错误消息,但最终我意识到我只需要使用\pgfmathparse
来避免麻烦。然而,我现在有一个完美的图表,除了边缘“不稳定”——每条边缘似乎都从一个节点连接到略微偏离下一个节点的点。为什么会发生这种情况?以下是我得到的屏幕截图:
这是一个最小的工作示例。
\documentclass[a4paper]{amsart}
\usepackage{tikz}
\tikzset{graph/.style = {every node/.style = { draw,
shape = circle,
fill = black,
minimum size = 0.8mm,
inner sep = 0mm,
label distance = 0.8mm
}}}
\newcommand{\circumferencenode}[3]{\node (#1) at (#3: #2) [label = #3: $#1$] {};}
\newcommand{\polygon}[2]{
\pgfmathparse{subtract(#1, 1)}
\foreach \x in {0, ..., \pgfmathresult} {
\pgfmathparse{90 - 360 * \x / #1}
\circumferencenode{\x}{#2}{\pgfmathresult}
}
\pgfmathparse{subtract(#1, 1)}
\foreach \x in {0, ..., \pgfmathresult} {
\pgfmathparse{mod(\x + 1, #1)}
\draw (\x) -- (\pgfmathresult);
}
}
\begin{document}
\begin{tikzpicture}[graph]
\polygon{6}{10mm}
\end{tikzpicture}
\end{document}
答案1
您最大的问题是\pgfmathparse{mod(\x + 1, #1)}
,因为结果是1.0
,2.0
......而不是1
,2
......使用,您以角度(nodename.x)
选择节点边界上的一个点。nodename
x
一些建议:
- 用于
\pgfmathsetmacro
在宏中存储数学表达式(浮点数)的结果。 - 用于
\pgfmathtruncatemacro
在宏中存储数学表达式(整数)的结果。 - 用于
\typeout
显示(和调试)您的结果。 - 使用默认数学引擎,计算时不能超过 16383.99999,因此请使用
{90-360/#1*\x}
而不是{90-360*\x/#1}
。
因此,这是你的 MWE:
\documentclass{standalone}
\usepackage{tikz}
\tikzset{graph/.style = {every node/.style = { draw,
circle,
fill = black,
minimum size = 0.8mm,
inner sep = 0mm,
}}}
\newcommand{\circumferencenode}[3]{
\node[label = #3: $#1$] (p#1) at (#3: #2) {};
}
\newcommand{\polygon}[2]{
\pgfmathtruncatemacro{\nminusone}{#1 - 1}
\foreach \x in {0, ..., \nminusone} {
\pgfmathsetmacro{\angle}{90 - 360 / #1 * \x}
\circumferencenode{\x}{#2}{\angle}
}
\foreach \x in {0,...,\nminusone} {
\pgfmathtruncatemacro{\next}{mod(\x + 1, #1)}
\typeout{\next}
\draw (p\x) -- (p\next);
}
}
\begin{document}
\begin{tikzpicture}[graph]
\polygon{6}{10mm}
\end{tikzpicture}
\end{document}
答案2
也可以直接使用库shapes.geometric
和形状regular polygon
。
可以按如下方式进行:
\documentclass[a4paper]{amsart}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\tikzset{
new polygon/.code 2 args={
\node[regular polygon, regular polygon sides=#1, draw,minimum size=1.7cm] (s) {};
\foreach \corner in {1,...,#1}{
\pgfmathparse{90-360 * (\corner-1) / #1}
\node at (\pgfmathresult:#2)[label={[font=\small]\pgfmathresult:$\corner$}]{};
\node[fill=black,circle, minimum size=0.8mm,inner sep=0mm] at (s.corner \corner){};
}
}
}
\begin{document}
\tikz[baseline]\node[new polygon={9}{9mm}] {}; \hspace*{0.5cm}
\tikz[baseline]\node[new polygon={5}{8mm}] {}; \hspace*{0.5cm}
\tikz[baseline]\node[new polygon={11}{7mm}] {};
\end{document}
结果: