
Ich habe eine Anfängerfrage. Ich möchte TikZ
einen Graphen mit Eckpunkten 0,..,m-1
in einem Kreis und Kanten n → n+1 mod m
, n → a⋅n mod m
, wobei m=19
, a=5
, sagen wir , zeichnen.
Der folgende Versuch funktioniert fast - allerdings landen die Pfeile an der falschen Stelle (immer am äußersten rechten Punkt des Kreises um einen Knoten):
\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}
(Ich weiß, ich sollte auch die kurzen Kanten biegen.)
Der folgende Code wird überhaupt nicht kompiliert:
\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}
Ich erhalte die Meldung: „! Package pgf-Fehler: Keine Form mit dem Namen A 0 bekannt.“
Worum geht es jeweils?
Antwort1
Wie Torbjørn T. auch in den Kommentaren bemerkt hat (vor mir, wie es scheint...), besteht das Problem darin, dass Mod
Zahlen wie 1,0 zurückgegeben werden, sodass Sie Knoten zum Punkt bei Winkel Null zeichnen. Ich würde auch die scope
Umgebung löschen und stattdessen verwenden
[evaluate=\n as \na using {int(Mod(\n*\a,\m))}]]
(und \tikzset
) zu produzieren:
Hier ist der Code:
\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}
Ich habe Ihr allgemeines Makro erstellt und ein paar Dinge optimiert.
Antwort2
Eine kleine Variation der Antwort von @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}