2

I have not programmed for a few years and I'm trying to get back to work but I have some problems with updates of "pgf" (perhaps ...) I am having a problem with the syntax "..." that I did not have before. I installed the latest versions of texlive, pgf etc ...

\documentclass{article}
\makeatletter
\def\DrawPolygon(#1,#2){%
 \begingroup
 \draw(#1)
     \foreach \pt in {#2}{--(\pt)}--cycle;%
 \endgroup
} 
\makeatother

\usepackage{tikz}


\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (4,0);
    \coordinate (B) at (2,4);
    \coordinate (C) at (0,0);   
   % \DrawPolygon(A,...,C) % error 
    % now error undefined\ifpgffor@alphabeticsequence \else \ifpgffor@assign@parse \begingroup
    % ! File ended while scanning use of \pgffor@@dotscharcheck.
    \DrawPolygon(A,B,C)
\end{tikzpicture}
\end{document}

The syntax (A,...,C) gives an error

  • 2
    \DrawPolygon(A,...,C) is \foreach \pt in {...,C} with no start for the loop, what range did you intend? – David Carlisle Jul 24 at 9:55
  • 1
    Indeed, the drawing works if one replaces \DrawPolygon(A,...,C) with \DrawPolygon(A,B,...,C) (which is not very different from \DrawPolygon(A,B,C), but one doesn't need to stop at C!) so that the \foreach loop sees a start value. – frougon Jul 24 at 10:49
  • @DavidCarlisle The first value is A. I gave a new example with more points and the result is fine. – Alain Matthes Jul 24 at 19:56
  • but #2 is the part after the first comma so \foreach \pt in {#2} is \foreach \pt in {...,C} and you do not pass in the first value. that is why oerpli uses #1,#2 in his/her answer, to add the starting value back. – David Carlisle Jul 24 at 19:58
  • 1
    @AlainMatthes this could never have worked. – David Carlisle Jul 24 at 19:58
3

Not too much TikZish, but, hey, it works!

\documentclass{article}
\usepackage{tikz}

\def\DrawPolygon(#1){%
  \begingroup
  \xdef\temppolygon{}%
  \foreach \pt in {#1}{\xdef\temppolygon{\temppolygon(\pt)--}}%
  \xdef\temppolygon{\endgroup\noexpand\draw\temppolygon cycle}%
  \temppolygon;
}

\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (4,0);
    \coordinate (B) at (2,4);
    \coordinate (C) at (0,0);
    \DrawPolygon(A,...,C) % error
\end{tikzpicture}
\end{document}

enter image description here

1

(I changed the example from A,B,C to A,...,E to make some points a bit more clear)

I think the problem is, that the first argument of DrawPolygon(A,...,E) (i.e: A) is consumed and the second argument (#2) is then expanded to (,...,E) instead of the desired A,...,E.

Fix this be either passing the start point as well as a list from the second or end (DrawPolygon(A,B,...,E) or by modifying the definition of your function as follows:

\documentclass{article}
\makeatletter
\def\DrawPolygon(#1,#2){%
 \begingroup
 \draw(#1)
     % change is in this line, {#1,#2} instead of {#2}
     \foreach \pt in {#1,#2}{--(\pt)}--cycle;
 \endgroup
} 
\makeatother
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (4,4);
    \coordinate (B) at (0,4);
    \coordinate (C) at (0,0);   
    \coordinate (D) at (4,0);   
    \coordinate (E) at (7,0);   
    \DrawPolygon(A,...,E)
\end{tikzpicture}
\end{document}
1

\foreach does have a loop counter. It can be assigned to a macro with option count. Then, the connecting line can be set in the second and later loop rounds.

\documentclass{article}
\usepackage{tikz}

\def\DrawPolygon(#1){%
  \draw
    \foreach[count=\pti] \pt in {#1} {
      \ifnum\pti>1 --\fi
      (\pt)
    }
    -- cycle
  ;
}

\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (4,4);
    \coordinate (B) at (0,4);
    \coordinate (C) at (0,0);
    \coordinate (D) at (4,0);
    \coordinate (E) at (7,0);
    \DrawPolygon(A,...,E)
\end{tikzpicture}
\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.