5

I already produced several figures with TikZ, but I can't see what's wrong with this snippet:

\documentclass[a4paper,10pt,twoside]{scrbook}
\usepackage[utf8x]{inputenc}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
        \def\groundwidth{8.0cm}
        \def\streetwidth{2.0cm}

        \def\gw{0.5*(\groundwidth-\streetwidth)}

        \fill[color=green!75!black] (0, 0) -- (\gw,0) -- (\gw,\gw) -- (0,\gw) -- cycle;
    \end{tikzpicture}
\end{document}

Compiling it with pdftex, it produces the following error message:

! Package pgf Error: No shape named 0 is known.

See the pgf package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.11 ...ll[color=green!75!black] (0, 0) -- (\gw,0)
                                               -- (\gw,\gw) -- (0,\gw) -...

I guess there's something wrong with \gw, but I have no idea how to fix I. Do you have any suggestions or a link to the documentation explaining the problem?

2

2 Answers 2

7

A solution is \def\gw{{0.5*(\groundwidth-\streetwidth)}}

\documentclass[a4paper,10pt,twoside]{scrbook}
\usepackage[utf8x]{inputenc}
\usepackage{tikz}
\begin{document}
        \def\groundwidth{8.0cm}
        \def\streetwidth{2.0cm}
        \def\gw{{0.5*(\groundwidth-\streetwidth)}}    
    \begin{tikzpicture}
        \fill[color=green!75!black] (0, 0) -- (\gw,0) -- (\gw,\gw) -- (0,\gw) -- cycle;
    \end{tikzpicture}
\end{document} 

you can also use

 \fill[color=green!75!black] (0, 0) -- ({\gw},0) -- ({\gw},{\gw}) -- (0,{\gw}) -- cycle;

instead of

  \def\gw{{0.5*(\groundwidth-\streetwidth)}}    
4
  • This is correct, but lacks an explanation why the error happens and why this solution works. Apr 13, 2012 at 18:47
  • Thanks a lot, this solution works for me. It was too simple ^^ Is there a special rule when to apply the {}, or do the {} simply force a node in the syntax tree?
    – Sebastian
    Apr 13, 2012 at 18:47
  • @Sebastian: See my explanation below. Apr 13, 2012 at 18:47
  • @Sebastian put the following in your code to see what \gw is holding as a variable : \node at (1.5,1.5) {\gw};. Then you can appreciate Martin's answer better in my opinion.
    – percusse
    Apr 13, 2012 at 18:55
6

The reason is that the \gw seems to be expanded before the full content of ( ) is parsed, so:

(0, 0) -- (\gw,0)

is seen as:

(0, 0) -- (0.5*(\groundwidth-\streetwidth),0)

Because parenthesis ( ) are not matched like braces { }, the first ) is taken as the closing one, so TikZ thinks 0.5*(\groundwidth-\streetwidth is the content. By the parsing rules of TikZ, this doesn't look like a coordinate, because there is no , or : included. Therefore it is taken as a node name. The syntax is node name.anchor, i.e. it thinks 0 is the node name and 5*(\groundwidth-\streetwidth the anchor name. This leads to the error No shape named 0 is known (shape here means node).

The solution is, as Altermundus already pointed out, to enclose the whole \gw expression with { }. This forces TeX to look for the closing } before it looks further for the ), making the inner pair of ( ) work.

2
  • 2
    Thanks for your explanation! Now I understand what causes the error and why the fix works. It seems as if it is worth learning more details of TikZ before I finish my thesis :-)
    – Sebastian
    Apr 13, 2012 at 18:57
  • @Sebastian: This is actually more about how TeX (i.e. the underlying system of LaTeX) itself parses special input. Instead of only normal arguments, you can use a parameter text which contains character usable as separators. E.g. \def\foo(#1,#2){\bar{#1}{#2}} will make \foo to look for ( then read everything to the next , as argument one and everything else up to the next ) as argument two. Brace groups however must always be matched beforehand, so you need to wrap content which include , or ) inside { }: \foo({a*(b+c)},0) Apr 13, 2012 at 19:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .