7

Is there a smart way to produce the following diagram using tikz?

enter image description here

With smart I mean not drawing each line for line and node for node but rather something like a for loop.

  • 1
    Some use of \foreach probably, or maybe \matrix. Are you wishing to recreate the labelling - if so could you explain how it's derived as it seems pretty non-trivial (no d but multiple repeated letters, I can't get my head round it). – Dai Bowen Oct 22 '16 at 12:47
  • 4
    Please provide the non-smart code you've got so people don't have to start from scratch in order to help you. – cfr Oct 22 '16 at 12:49
  • 1
    @DaiBowen, the letters should be like that to produce a triangulation for a torus. – Sigur Oct 22 '16 at 12:49
13

Example, which uses both smart stuff (grid), \foreach loops and manual elements:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
  \draw
    (0, 0) grid[step=1cm] (3, 3)
    (0, 2) -- (1, 3)
    (0, 1) -- (2, 3)
    (0, 0) -- (3, 3)
    (1, 0) -- (3, 2)
    (2, 0) -- (3, 1)
  ;
  \fill[radius=3pt]
    \foreach \x in {0, ..., 3} {
      \foreach \y in {0, ..., 3} {
        (\x, \y) circle[]
      }
    }
  ;
  \path[above left]
    \foreach \y in {0, 3} {
      \foreach[count=\x] \v in {a, b, c, a} {
        (\x - 1, \y) node {$\v$}
      }
    }
    \foreach \p/\v in {
      {0, 2}/e,
      {1, 2}/f,
      {2, 2}/g,
      {3, 2}/e,
      {0, 1}/h,
      {1, 1}/j,
      {2, 1}/k,
      {3, 1}/h%
    } {
      (\p) node {$\v$}
    }
  ;
\end{tikzpicture}
\end{document}

Result

  • Ow, thanks. I didn' t know about circle[]. I have been using circle () to inform radius. – Sigur Oct 22 '16 at 13:40
  • circle(<radius>) is the old syntax. The documentation says, that "the use of parentheses for something other than a coordinate is ill-chosen." Therefore, I am using the new and normal syntax with square brackets. – Heiko Oberdiek Oct 22 '16 at 15:23
13

A (hopefully accurate) scalable version for arbitrary size (can't say if it's mathematically useful but was fun to make).

alphalph used to generate arbitrary number of labels some increased spacing is probably necessary if you're going beyond a 5x5 grid to make more space for the double letter labels. The code basically uses a lot of foreach with a little bit of maths to make sure each label has the appropriate number associated.

\documentclass{article}
\usepackage{tikz}
\usepackage{alphalph}

\newcommand{\triangulation}[1]{
\pgfmathsetmacro{\triangulationdimension}{#1}
\pgfmathsetmacro{\triangulationdim}{\triangulationdimension-1}
\begin{scope}[yscale=-1]
\node [circle,draw,fill=black,label=above left:{\alphalph{1}}] at (\triangulationdimension,\triangulationdimension) {};
\foreach \i  [evaluate=\i as \l  using int(\triangulationdimension*(\i-1)+1)] in {1,...,\triangulationdim} {
    \node [circle,draw,fill=black,label=above left:{\alphalph{\i}}] at (\i,\triangulationdimension) {};
    \node [circle,draw,fill=black,label=above left:{\alphalph{\l}}] at (\triangulationdimension,\i) {};
    \foreach \j [evaluate=\j as \k  using int(\triangulationdimension*(\j-1)+\i)] in {1,...,\triangulationdim} {
        \node [circle,draw,fill=black,label=above left:{\alphalph{\k}}] at (\i,\j) {};
        \foreach \x in {0,1} {
            \draw (\i+\x,\j) -- (\i+\x,\j+1);
            \draw (\j,\i+\x) -- (\j+1,\i+\x);
        }
        \draw (\j,\i+1) -- (\j+1,\i);
    }
}
\end{scope}
}

\begin{document}
\begin{tikzpicture}
    \triangulation{3}
\end{tikzpicture}
\begin{tikzpicture}
    \triangulation{4}
\end{tikzpicture}
\begin{tikzpicture}
    \triangulation{8}
\end{tikzpicture}
\end{document}

enter image description here

7

A sort of a programmer styled answer, similar to @HeikoOberdiek 's one:

\documentclass{article}
\usepackage{tikz}
\begin{document}


\begin{tikzpicture}

    \foreach \x in {0,..., 3}{
        \foreach \y in {0,..., 3}{
            \fill (\x, \y) circle (3pt);
            \draw (0,0) rectangle (\x,\y);
        }
    }
    \foreach \x in {0, ..., 2}{
            \foreach \y in {2, ..., 0}{
                \draw (\x, \y) -- (\x + 1, \y + 1);
            }
    }
    \path[above left]
        \foreach \a in {0, 3}{
            \foreach[count=\x] \b in {a, b, c, a}{
                (\x - 1, \a) node {$\b$}
            }
        }
        \foreach \a/\b in {
            {0, 2}/e,
            {1, 2}/f,
            {2, 2}/g,
            {3, 2}/e,
            {0, 1}/h,
            {1, 1}/j,
            {2, 1}/k,
            {3, 1}/h
        } {
        (\a) node {$\b$}
        }
    ;
\end{tikzpicture}

\end{document}

enter image description here

4

Here's an alternative in Metapost, using the luamplib interface. Compile with lualatex.

enter image description here

The MP construct forsuffixes provides a way to use the labels to control the loop.

\RequirePackage{luatex85}
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);

    numeric u;   u = 1.618cm;
    numeric x,y; x = 0; y = 0; 

    forsuffixes @=a,b,c,a,
                  h,j,k,h,
                  e,f,g,e,
                  a,b,c,a:

       if (x>0):           draw ((x,y) -- (x-u,y  )); fi
       if (y>0):           draw ((x,y) -- (x,  y-u)); fi
       if (x>0) and (y>0): draw ((x,y) -- (x-u,y-u)); fi

       dotlabel.ulft("$" & str @ & "$", (x,y));

       x := x + u;
       if x > 3u:
          x := 0;
          y := y + u;
       fi

    endfor
endfig;
\end{mplibcode}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.