关于 pgfmath、变量、条件和范围的一个问题

关于 pgfmath、变量、条件和范围的一个问题

首先,我要为我的问题标题模糊而道歉,不知何故我没能想出更精确的答案。

根据以下回答这个问题,我想创建一个函数,用 tikz 绘制 n 次方根(这在上面引用的答案中已经完成了),并用红色勾勒出原始根(这是我想要添加的)。经过一段时间的调查,我偶然发现了 pgfmath,并最终得到了以下内容:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{ifthen}
\pgfmathdeclarefunction{GCD}{2}{
\ifnum#1>#2 \edef\no{#1}\edef\res{#2} \else \edef\no{#2}\edef\res{#1} \fi
\ifnum\res=0 \pgfmathtruncatemacro\temp{0}\pgfmathtruncatemacro\res{\no} \else \pgfmathtruncatemacro\temp{mod(\no,\res)}
    \whiledo{\temp>0}{
        \pgfmathtruncatemacro\no{\res}
        \pgfmathtruncatemacro\res{\temp}
        \pgfmathtruncatemacro\temp{mod(\no,\res)}
    }
\fi 
\pgfmathparse{\res}
}
\newcommand{\plotroots}[1]{
    \edef\n{#1}
    \begin{tikzpicture}[
    dot/.style={draw,fill,circle,inner sep=1pt}
    ]
        \draw[->] (-2.5,0) -- (2.5,0) node[right] {$\mathrm{Re}$};
        \draw[->] (0,-2.5) -- (0,2.5) node[above] {$\mathrm{Im}$};
        \draw[help lines] (0,0) circle (1.7);

        \node[dot,label={below right:$0$}] (H) at (0,0) {};
        \foreach \i in {1,...,\n} {
            \begin{scope}   
                \pgfmathparse{GCD(\i,\n)}
                \ifnum\pgfmathresult=1 \gdef\rootcolor{red} \else\gdef\rootcolor{black}\fi
            \end{scope}
            \node[\rootcolor,dot,label={\i*360/\n-(\i==\n)*45:\textcolor{\rootcolor}{\pgfmathparse{int(mod(\i,\n))}$\zeta_{\n}^{\pgfmathresult}$}}] (w\i) at (\i*360/\n:1.7) {};
    \draw[\rootcolor,->] (H) -- (w\i);
        }
        \draw[->] (0:.3) arc (0:360/\n:.3);
        \node at (360/\n/3:.75) {\footnotesize $2\pi/\n$};
    \end{tikzpicture}
}
\begin{document}
\centering\plotroots{12}
\end{document}

这基本上可以正常工作,例如输出是 enter image description here
不过,我还是想了解其中的一些问题:

  1. 如果根恰好位于其中一个坐标轴上,则标签应放置在与相应轴成 45 度角的位置,而不是通常的位置。如果我没有完全误解上面引用的答案中的代码,这是在但是 label={\i*360/\n-(\i==\n)*45: ,在上面显示的 \n=12 示例中,为什么这会适用于 \i=3,6,9(显然如此)?
    此外,对于 \n=8,输出为: enter image description here
    因此,此处的条件适用于 \i=4,6,但显然不适用于 \i=2。这怎么可能呢?

  2. 在我向循环内添加\begin{scope}...\end{scope}一段新代码\foreach来检查根是否是原始的之前,输出如下所示: enter image description here

编辑:准确地说,产生上面图像的代码是:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{ifthen}
\pgfmathdeclarefunction{GCD}{2}{
\ifnum#1>#2 \edef\no{#1}\edef\res{#2} \else \edef\no{#2}\edef\res{#1} \fi
\ifnum\res=0 \pgfmathtruncatemacro\temp{0}\pgfmathtruncatemacro\res{\no} \else \pgfmathtruncatemacro\temp{mod(\no,\res)}
    \whiledo{\temp>0}{
        \pgfmathtruncatemacro\no{\res}
        \pgfmathtruncatemacro\res{\temp}
        \pgfmathtruncatemacro\temp{mod(\no,\res)}
    }
\fi 
\pgfmathparse{\res}
}
\newcommand{\plotroots}[1]{
    \edef\n{#1}
    \begin{tikzpicture}[
    dot/.style={draw,fill,circle,inner sep=1pt}
    ]
        \draw[->] (-2.5,0) -- (2.5,0) node[right] {$\mathrm{Re}$};
        \draw[->] (0,-2.5) -- (0,2.5) node[above] {$\mathrm{Im}$};
        \draw[help lines] (0,0) circle (1.7);

        \node[dot,label={below right:$0$}] (H) at (0,0) {};
        \foreach \i in {1,...,\n} {     
            \pgfmathparse{GCD(\i,\n)}
            \ifnum\pgfmathresult=1 \gdef\rootcolor{red} \else\gdef\rootcolor{black}\fi
            \node[\rootcolor,dot,label={\i*360/\n-(\i==\n)*45:\textcolor{\rootcolor}{\pgfmathparse{int(mod(\i,\n))}$\zeta_{\n}^{\pgfmathresult}$}}] (w\i) at (\i*360/\n:1.7) {};
    \draw[\rootcolor,->] (H) -- (w\i);
        }
        \draw[->] (0:.3) arc (0:360/\n:.3);
        \node at (360/\n/3:.75) {\footnotesize $2\pi/\n$};
    \end{tikzpicture}
}
\begin{document}
\centering\plotroots{8}
\end{document}

因此,在这种情况下,原点似乎在每次迭代中都在移动。我非常想知道是什么导致了这种效果!我在编写函数 GCD 时犯了什么错误?这会如何影响绘图的位置?为什么 eg\bgroup ... \egroup没有效果,但\begin{scope} ... \end{scope}有效果?(请原谅我对此缺乏先验知识,但这是我第一次尝试在 LaTeX 中编写某种函数)

非常感谢您的帮助,提前谢谢!

答案1

  1. 该表达式\i*360/\n-(\i==\n)*45不是合法的 pgf 表达式。因此结果是“不可预测的”(实际上它与 相同\i*360/\n-\i)。
  2. 如果您想要问题的答案,您应该展示产生该问题的代码。

顺便说一下,我认为这里有更简单、更“tikzedish”的代码:

\documentclass[tikz,border=7pt]{standalone}
\tikzset{
  color1/.style = {red},
  roots/.pic={
    \pgfmathtruncatemacro{\n}{#1}
    \pgfmathtruncatemacro{\m}{\n-1}
    \draw[-latex] (-90:3) -- (90:3) node[right]{Im};
    \draw[-latex] (180:3) -- (0:3) node[below]{Re};
    \draw (0,0) circle(2);
    \foreach[evaluate={\j=mod(4*\i,\n)==0;\k=gcd(\i,\n)}]\i in{0,...,\m}{
      \draw[color\k/.try]
        (0:0) -- (\i*360/\n:2) node[scale=3]{.}
        (\i*360/\n+\j*7:2.35) node{$\zeta_{\n}^{\i}$};
    }
  }
}
\begin{document}
  \begin{tikzpicture}
    \pic{roots=3*4};
  \end{tikzpicture}
\end{document}

enter image description here

相关内容