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.

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?

share|improve this question
1  
Welcome to TeX.sx! You don't have to sign with your name since it automatically appears in the lower right corner of your post. –  Werner Apr 13 '12 at 18:32
    
Very related: Problems with TikZ calculations. Both is basically due to the same syntax limitations, i.e. that ( ) are not matched on a lower level. –  Martin Scharrer Apr 13 '12 at 19:30
add comment

2 Answers

up vote 7 down vote accepted

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)}}    
share|improve this answer
    
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
add comment

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.

share|improve this answer
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
add comment

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.