50 foreach在处理首尾相连问题时,「0,2,3,...,11」对于「11到0」的处理时如何避免特殊判断

发布于 2025-08-20 17:35:25

这个问题是上一个问题的姊妹版。

考虑如下首尾相连的情况:

image.png

下面的代码在处理边界「11->0」的时候进行的特判也并不优雅

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
  \begin{tikzpicture}[
    every label/.style={circle, inner sep=0pt, anchor=center}
  ]
    \foreach \i [
        count=\j from -1,
        % remember= \i as \ilast (initially 11)
    ] in {0,...,11} {
        \node[fill, circle, inner sep=1pt, label={
            [minimum width=2.5em,label distance=.2cm]{360/12*(\i-1/2)-60}:{\footnotesize $a_{\i}$}
        }] (a\i) at ({360/12*(\i-1/2)}:2) {};
        \ifnum\i=0\else
            \draw[latex-] (a\i) -- node[inner sep=0pt, circle] {} (a\j);
        \fi
    }
    \draw[latex-] (a0) -- node[inner sep=0pt, circle] {} (a11);
  \end{tikzpicture}
\end{document}

其中

\ifnum\i=0\else
    \draw[latex-] (a\i) -- node[inner sep=0pt, circle] {} (a\j);
\fi

\draw[latex-] (a0) -- node[inner sep=0pt, circle] {} (a11);

同样让人觉得很呆。

尝试过

remember= \i as \ilast (initially 11)

但在\i=0被处理时,\i=11并未被定义。

是否有技巧来避免这种ugly的特判呢?

可能有用

考虑如下坐标映射

x -> y
0 -> 1
1 -> 2
2 -> 3
3 -> 4
4 -> 5
5 -> 6
6 -> 7
7 -> 8
8 -> 9
9 -> 10
10 -> 11
11 -> 0
12 -> 1
13 -> 2
...

这可以通过:

\pgfmathtruncatemacro{\y}{mod(\x+1,12)}

来计算...

查看更多

关注者
0
被浏览
132
M
M 1天前
这家伙很懒,什么也没写!

如果所有点都是有规律的,可以考虑把node-->node换成coordinate-->node的连接模式,从而来规避掉初始阶段a11节点没有定义的情况,保持代码形式的简洁。

  \begin{tikzpicture}[
    every label/.style={circle, inner sep=0pt, anchor=center}
  ]
    \foreach \i [
        evaluate=\i as \angle using {360/12*(\i-1/2)}
    ] in {0,...,11} {
        \node[fill, circle, inner sep=1pt, label={
            [minimum width=2.5em,label distance=.2cm]{\angle-60}:{\footnotesize $a_{\i}$}
        }] (a\i) at (\angle:2) {};
        % 动态计算上一个点的坐标(\angle-30:2)
        \draw[latex-] (a\i) -- (\angle-30:2);
    }
  \end{tikzpicture}
4 个回答
越来越少
越来越少 1天前
这家伙很懒,什么也没写!

87069d1406db373ab1438c506d5c5f79.png

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,graphs}

\begin{document}

\tikz[>=Latex]
  \graph[
    counterclockwise=12,
    radius=2cm,
    nodes={circle, fill, minimum size=4pt,inner sep=0pt},
    empty nodes,
    cycle,
    ->
  ]{ \foreach \i in {0,1,...,11}{""/""[label={90+\i*(360/12):$a_{\i}$}], } };

\end{document}

表面上看这个办法的代码简单, 只是表面上看.

越来越少
越来越少 22小时前
这家伙很懒,什么也没写!

在 tikz 中, 一个路径只能加一个箭头, 所以给 plot 加上 -latex 来一次性加多个箭头很难.

plot 创建 plot stream, 用 plot handler 绘图, 这个思路的话, 可以这样试试:

\makeatletter

\def\mypointcode#1{
    \ifpgf@plot@started%
      \pgfsetarrowsend{Latex}
      \pgfpathmoveto{\lastpoint}%
      \pgfpathlineto{#1}
      \pgfusepath{stroke}
      \def\lastpoint{#1}
    \else%
      \def\lastpoint{#1}
      \def\firstpoint{#1}
      \pgf@plot@startedtrue% 
    \fi%
}
  
\def\myendcode{
      \pgfsetarrowsend{Latex}
      \pgfpathmoveto{\lastpoint}%
      \pgfpathlineto{\firstpoint}
      \pgfusepath{stroke}
}
\begin{tikzpicture}
\path[draw]
  foreach \x[
          evaluate = \x as \angle using {360/12*(\x+1/2)}
      ] in {0,...,11} {
          node[
              shape=circle, color=black, draw, fill,
              inner sep=+0pt, minimum size=+2pt,
              label = {[anchor=\angle+180]{\angle}:$\x$},
              ] (a\x) at (\angle:1.5) {}
  };

\pgfplothandlerrecord{\mystream}
\pgfplotfunction{\x}{0,...,11}{\tikz@scan@one@point\pgf@process(a\x.center)}
\let\pgfplotstreampoint\mypointcode
\let\pgfplotstreamend\myendcode
\tikzset{shorten <=1.5pt, shorten >=1.5pt}
\mystream
\end{tikzpicture}
Sagittarius Rover
我要成为Typst糕手/(ㄒoㄒ)/~~

我也来贡献一个可能的答案吧...

我其实见过Qrrbrbirlbel在这里的一个神级操作

\documentclass[tikz,border=8pt]{standalone}
\begin{document}
  \begin{tikzpicture}
    \path[draw]
    foreach \x[
        evaluate = \x as \angle using {360/12*(\x+1/2)}
    ] in {0,...,11} {
        node[
            shape=circle, color=black, draw, fill,
            inner sep=+0pt, minimum size=+2pt,
            label = {[anchor=\angle+180]{\angle}:$\x$},
            ] (a\x) at (\angle:1) {}
        }
    plot [sharp cycle, samples at = {0,...,11}] (a\x.center);
  \end{tikzpicture}
\end{document}

出于一些我比较菜的原因...我不知道是否有办法对plot加上-latex...

image.png

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览