Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

For a document I am working on, I wanted to be able to draw polygon graphs. The graphs are to be labelled with the integers from 0 to n - 1, for some n. I wanted to write a macro that could be called inside a tikzpicture to draw such a graph, when supplied with the number of edges (n) and the "radius" of the graph (distance of each vertex from the centre). It turned out to be quite a frustrating experience because trying to use mathematical expressions involving macro arguments in TikZ's \foreach is not straightforward and results in many baffling error messages, but eventually I realised I just need to use \pgfmathparse to avoid the hassle. Yet I now have a perfectly good graph, except that the edges are "wonky" - each edge seems to connect from one node to a point slightly off the next node. Why is this happening? Here is a screengrab of what I am getting:

Here is a minimal working example.

\documentclass[a4paper]{amsart}

\usepackage{tikz}

\tikzset{graph/.style = {every node/.style = { draw,
                                               shape = circle,
                                               fill = black,
                                               minimum size = 0.8mm,
                                               inner sep = 0mm,
                                               label distance = 0.8mm
                                               }}}

\newcommand{\circumferencenode}[3]{\node (#1) at (#3: #2) [label = #3: $#1$] {};}
\newcommand{\polygon}[2]{
    \pgfmathparse{subtract(#1, 1)}
    \foreach \x in {0, ..., \pgfmathresult} {
        \pgfmathparse{90 - 360 * \x / #1}
        \circumferencenode{\x}{#2}{\pgfmathresult}
    }
    \pgfmathparse{subtract(#1, 1)}
    \foreach \x in {0, ..., \pgfmathresult} {
        \pgfmathparse{mod(\x + 1, #1)}
        \draw (\x) -- (\pgfmathresult);
    }
}

\begin{document}
    \begin{tikzpicture}[graph]
        \polygon{6}{10mm}
    \end{tikzpicture}
\end{document}
share|improve this question

2 Answers 2

up vote 11 down vote accepted

Your big problem is with \pgfmathparse{mod(\x + 1, #1)}, because the results are 1.0, 2.0... and not 1,2... With (nodename.x), you select a point on the border of node nodename in angle x.

Some advices:

  • Use \pgfmathsetmacro to store the result of a math expression (float) in a macro.
  • Use \pgfmathtruncatemacro to store the result of a math expression (integer) in a macro.
  • Use \typeout to show (and debug) your results.
  • With default math engine, you can't exceed 16383.99999 during calculation, so use {90-360/#1*\x} instead of {90-360*\x/#1}.

So, here is your MWE :

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\tikzset{graph/.style = {every node/.style = { draw,
                                               circle,
                                               fill = black,
                                               minimum size = 0.8mm,
                                               inner sep = 0mm,
                                               }}}

\newcommand{\circumferencenode}[3]{
  \node[label = #3: $#1$] (p#1) at (#3: #2)  {};
}
\newcommand{\polygon}[2]{
    \pgfmathtruncatemacro{\nminusone}{#1 - 1}
    \foreach \x in {0, ..., \nminusone} {
        \pgfmathsetmacro{\angle}{90 - 360 / #1 * \x}
        \circumferencenode{\x}{#2}{\angle}
    }
    \foreach \x in {0,...,\nminusone} {
        \pgfmathtruncatemacro{\next}{mod(\x + 1, #1)}
        \typeout{\next}
        \draw (p\x) -- (p\next);
    }
}

\begin{document}
\begin{tikzpicture}[graph]
  \polygon{6}{10mm}
\end{tikzpicture}
\end{document}
share|improve this answer

There is also the possibility of using directly the library shapes.geometric and the shape regular polygon.

One might proceed as follows:

\documentclass[a4paper]{amsart}

\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\tikzset{
        new polygon/.code 2 args={
        \node[regular polygon, regular polygon sides=#1, draw,minimum size=1.7cm] (s) {};
        \foreach \corner in {1,...,#1}{
         \pgfmathparse{90-360 * (\corner-1) / #1}
         \node at (\pgfmathresult:#2)[label={[font=\small]\pgfmathresult:$\corner$}]{};
         \node[fill=black,circle, minimum size=0.8mm,inner sep=0mm] at (s.corner \corner){};
        }
    }
}

\begin{document}
\tikz[baseline]\node[new polygon={9}{9mm}] {}; \hspace*{0.5cm}
\tikz[baseline]\node[new polygon={5}{8mm}] {}; \hspace*{0.5cm}
\tikz[baseline]\node[new polygon={11}{7mm}] {};  
\end{document}

The result:

enter image description here

share|improve this answer
    
Thanks for your advice. I chose Paul's answer because he explained why the graph was incorrect as well as giving a fix, but I appreciate it. –  Hammerite Dec 2 '12 at 11:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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