
初心者の質問です。 を使用して、円内に頂点があり、、、などの辺TikZ
を持つグラフを描画したいと思います。0,..,m-1
n → n+1 mod m
n → a⋅n mod m
m=19
a=5
次の試みはほぼ機能しますが、矢印が間違った場所(常にノードの周りの円の右端の点)に配置されます。
\begin{tikzpicture}
\def \R {60}
\def \r {9}
\def \radius {\R mm}
\tikzmath{
\m = 19; \a = 5;
\margin = 2*atan(\r/(4*\R));
\mm = \m - 1;
}
\foreach \n in {0,...,\mm}
{
\node[draw, circle,minimum size=\r mm] (v_\n) at ({90-360/\m * \n}:\radius) {$\n$};
\draw[->, >=latex, ] ({90-(360/\m * \n+\margin)}:\radius)
arc ({90-(360/\m * \n+\margin)}:{90-(360/\m * (\n+1)-\margin)}:\radius);
}
\begin{scope}[->,>=latex,shorten >=1pt,color=red]
\foreach \n in {1,...,\mm}
{
\tikzmath{\ntimes = Mod(\n*\a,\m);}
\draw (v_\n) edge (v_\ntimes);
}
\path (v_0) edge [loop above] (v_0);
\end{scope}
\end{tikzpicture}
(短い辺も曲げる必要があることはわかっています。)
次のコードはまったくコンパイルされません。
\begin{tikzpicture}
\def \R {60}
\def \r {9}
\def \radius {\R mm}
\tikzmath{
\m = 19; \a = 5;
\margin = 2*atan(\r/(4*\R));
\mm = \m - 1;
}
\graph[clockwise, radius=6cm] {subgraph C_n [n=\m, name=A]};
\foreach \n in {1,...,\mm} {
\tikzmath{\ntimes = Mod(\n*\a,\m); \np = Mod(\n+1,\m);}
\draw (A \n) -- (A \ntimes);
\draw (A \n) -- (A \np);
}
\end{tikzpicture}
次のメッセージが表示されます: 「! パッケージ pgf エラー: A 0 という名前の図形が認識されていません。」
それぞれの場合、何が問題なのでしょうか?
答え1
Torbjørn T. もコメントで気づいていたように (どうやら私より先に...)、問題は がMod
1.0 のような数値を返すため、角度 0 の点にノードを描画してしまうことです。環境も削除しscope
、代わりに
[evaluate=\n as \na using {int(Mod(\n*\a,\m))}]]
(そして\tikzset
)次を生成します。
コードは次のとおりです:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,math,positioning}
\def \R {60}
\def \r {9}
\def \radius {\R mm}
\tikzset{
myedge/.style={->, >=latex, shorten >=1pt, color=red}
}
\newcommand\macircle[2]{% m=#1, a=#2
\begin{tikzpicture}
\tikzmath{
\margin = 2*atan(\r/(4*\R));
\mm = #1 - 1;
}
\foreach \n in {0,...,\mm}
{
\node[draw=blue, circle,minimum size=\r mm] (v\n) at ({90-360/#1 * \n}:\radius) {$\n$};
\draw[->, >=latex, ] ({90-(360/#1 * \n+\margin)}:\radius)
arc ({90-(360/#1 * \n+\margin)}:{90-(360/#1 * (\n+1)-\margin)}:\radius);
}
\foreach \n [evaluate=\n as \na using {int(Mod(\n*#2,#1))}] in {1,...,\mm}
{
\draw[myedge] (v\n) -- (v\na);
}
\path[myedge] (v0) edge [loop above] (v0);
\end{tikzpicture}
}
\begin{document}
\macircle{19}{5}
\macircle{17}{6}
\end{document}
一般的なマクロを作成し、少し調整しました。
答え2
@Andrew の回答の小さなバリエーション:
\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}[
every edge/.style = {draw=red,-{Straight Barb[angle=60:3pt 3]}, semithick},
every loop/.style = {draw=red,-{Straight Barb[angle=60:3pt 3]}, semithick}
]
\foreach \i in {0,...,18}
{
\node (v\i) [circle, draw, minimum size=9mm] at ({90-\i*360/19}:6) {\i};
\pgfmathsetmacro{\margin}{atan(9/120)}
\path[every edge]
({90+\i*360/19+\margin}:6) arc ({90+\i*360/19+\margin}:{90+(\i+1)*360/19-\margin}:6);
}
\foreach \n in {1,...,18}
{
\pgfmathsetmacro{\nn}{int(Mod(\n*5,19))}
\pgfmathsetmacro{\j}{int(abs(\nn-\n))}
\ifnum\j<3
\pgfmathsign{\nn-\n}
\ifnum\pgfmathresult>0
\path (v\n) edge[bend right] (v\nn);
\else
\path (v\n) edge[bend left] (v\nn);
\fi
\else
\path (v\n) edge[blue] (v\nn);
\fi
}
\path (v0) edge [loop above] ();
\end{tikzpicture}
\end{document}