I have a rectangle in TikZ and the top left and bottom right corners are called (topleft) and (bottomright) respectively. I wanted to have a label midway down the left hand side of the rectangle, so I tried the following, both of which failed with cryptic error messages:

\draw let \p1 = (topleft), \p2 = (bottomright) 
in (\x1,\pgfmathparse{0.5*(\y1 + \y2)}\pgfmathresult) node[right]{6 metres};


\draw let \p1 = (topleft), \p2 = (bottomright) 
in (\x1,{0.5*(\y1 + \y2)}) node[right]{6 metres};

I got the desired result in a roundabout way:

\draw let \p1 = (topleft), \p2 = (bottomright) 
in ($(\x1,\y1)!.5!(\x1,\y2)$) node[right]{6 metres};

But why did the first two attempts not work?

EDIT (in response to request for more detail): If it helps, you can assume that the context of the command above is something like:

\draw (0,10) coordinate (topleft) rectangle (6,0) coordinate (bottomright);
%% relevant let statement would go just below here

but I do not want a solution that uses the knowledge that the coordinates are (0,10) and (6,0).

  • 4
    I think we can be more help if you include a full example that we can compile (and therefore see the errors) – Joseph Wright Aug 23 '10 at 7:01
  • @Joseph, I've now done this but I can't help suspecting that a tikz user who doesn't know how to define coordinates probably won't be able to explain why the let statements above don't work... – bryn Aug 23 '10 at 12:11

Working with \pgfmathparse inside a path

If you need to do a calculation inside a path, I recommend to suspend this path, do the calculation, then resume the path. That "escaping" could be done by using the \pgfextra{code} macro executing code.

In your example, \pgfextra may contain the \pgfmathparse calculation, \pgfmathresult may be used later on in the path.

Here's the modification for your first example:

\draw (0,10) coordinate (topleft) rectangle (6,0) coordinate (bottomright);
\draw let \p1 = (topleft), \p2 = (bottomright) 
  in \pgfextra{\pgfmathparse{0.5*(\y1 + \y2)}}
    (\x1,\pgfmathresult pt) node[right]{6 metres};


alt text

This advice is for the case that you need to do more complex calculation not easily done by simple expressions or perhaps intersections.

| improve this answer | |

Rather than doing "all that arithmetic", I'd let Tikz do it for me. Try something like this:

\draw(-10,0)  node (topleft) {TL}; 
\draw(0,-10)  node (bottomright) {BR}; 
\draw (topleft) rectangle (bottomright);
\path (topleft) edge node (here) {Here} (topleft |- bottomright);

The two secrets are these: node will draw at the midpoint of a path, and |- (or -|) represents a vertical/horizontal point of intersection (ie, in the example, "drop a line vertically from (topleft) until it meets a horizontal line through (bottomright). Try swapping -| for |- and you'll see what I'm getting at.

You can also refine things, like this:

\path (topleft) edge[draw opacity=0] 
     node [right,pos=0.25] (here) {Here} 
     (topleft |- bottomright);`

draw opacity=0 suppresses the line that \path normally draws

right places the text to the right

pos=0.25 places the node 1/4 of the way along the path (and so on), saving your arithmetic for better things...

| improve this answer | |

I ran into a similar problem. I am not sure, but it seems as if TikZ has some problems with evaluating nested expressions. So, instead of calulating

0.5*(\y1 + \y2)

I would suggest to calculate


This worked for me.

| improve this answer | |
  • 3
    The problem with ( ) inside outer ( ) is that the first opening ( is matched to to first closing ) found. This is because of the way TeX parses things. For the same reason you can't use [] inside an optional argument directly. Try to hide these things from the TeX parser by placing them in { }: 0.5*{(\y1 + \y2)}. However, this works only on places where an argument (or PGF expression) is awaited so that the {} are stripped again. – Martin Scharrer Apr 6 '11 at 8:53

Your second example does work in TikZ v2.10. So I suspect it is a bug in the math parser of version 2.00.

| improve this answer | |

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.