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?

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)}}    
  • This is correct, but lacks an explanation why the error happens and why this solution works. – Martin Scharrer Apr 13 '12 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 '12 at 18:47
  • @Sebastian: See my explanation below. – Martin Scharrer Apr 13 '12 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 '12 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
    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 '12 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) – Martin Scharrer Apr 13 '12 at 19:02

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.