# Why is this let expression not working in TikZ (calculating a midpoint)?

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};


and

\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:

\usetikzlibrary{calc}
\begin{tikzpicture}
\draw (0,10) coordinate (topleft) rectangle (6,0) coordinate (bottomright);
%% relevant let statement would go just below here
\end{tikzpicture}


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

-
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

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

\begin{tikzpicture}[scale=1,>=stealth]
\draw(-10,0)  node (topleft) {TL};
\draw(0,-10)  node (bottomright) {BR};
\draw (topleft) rectangle (bottomright);
\path (topleft) edge node (here) {Here} (topleft |- bottomright);
\end{tikzpicture}


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...

-

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:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\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};
\end{tikzpicture}
\end{document}


Output:

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

-

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

0.5*\y1+0.5*\y2


This worked for me.

-
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.

-