13

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

Stefan Kottwitz
  • 231,401
bryn
  • 10,264
  • 14
  • 46
  • 43
  • 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 07: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

4 Answers4

12

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:

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.

Stefan Kottwitz
  • 231,401
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...

6

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.

  • 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 06 '11 at 08:53
1

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

Caramdir
  • 89,023
  • 26
  • 255
  • 291