Zeichnen eines Graphen für n→n+1, n→ a⋅n mod m in TikZ

Zeichnen eines Graphen für n→n+1, n→ a⋅n mod m in TikZ

Ich habe eine Anfängerfrage. Ich möchte TikZeinen Graphen mit Eckpunkten 0,..,m-1in 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}

Bildbeschreibung hier eingeben

(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 ModZahlen wie 1,0 zurückgegeben werden, sodass Sie Knoten zum Punkt bei Winkel Null zeichnen. Ich würde auch die scopeUmgebung löschen und stattdessen verwenden

[evaluate=\n as \na using {int(Mod(\n*\a,\m))}]]

(und \tikzset) zu produzieren:

Bildbeschreibung hier eingeben

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}

Bildbeschreibung hier eingeben

verwandte Informationen