这个问题是上一个问题的姊妹版。
考虑如下首尾相连的情况:
下面的代码在处理边界「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)}
来计算...
如果所有点都是有规律的,可以考虑把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}
\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}
表面上看这个办法的代码简单, 只是表面上看.
在 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}
我也来贡献一个可能的答案吧...
我其实见过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
...
感谢回复。
您上面的代码中用的是
这里的
(a\i)
是node
而(\angle-30:2)
是coordinate
!确实是不错的想法!非常感谢您!