tikz-pgf – Optimal Methods for Intersections and Calculations with Relative Coordinates in TikZ

calculationscoordinatestikz-pgf

I've been doing many TikZ diagrams lately and every so often I encounter a situation where I am forced to use some temporary coordinate in a \path. In the following short example, the problem is drawing the red line:

Output of MWE

\documentclass{article}
\usepackage{tikz}
%\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

% Angled line connecting to a straigt line. This is where my problem lies.
\draw[red] (A.140) -- ++(0,1) coordinate(temp) -- (temp -| B.50);

% Some examples of what I think would be useful in this case.
% None of these things seem to be supported in TikZ.
%\draw[red] (A.140) |- (+(0,1) -| B.50);
%\draw[red] (A.140) -- ++(1,0) -- (\currentcoordinate -| B.50);
%\draw[red] (A.140) |- ($(B.50).x, (+(0,1)).y$);
\end{tikzpicture}
\end{document}

So I wonder if there is a better way to draw the red line. By "better" I mean more concise, without repetition, ideally without ($calculations$). Some examples of what I think could be useful are included as comments in the code.

Since "better" is mostly a matter of taste, I have broken my question down to what I think could be useful to solve the problem:

  1. Is it possible to use relative coordinates in the intersection syntax (a -| b)?
  2. Is there some way (macro or other) to access the current coordinate of the current path?
  3. Is it possible to use relative coordinates in the calculation syntax ($(a) + (b)$)?
  4. Is there a way to combine x-Part of one coordinate with the y-Part of another, other than the (a -| b) syntax? Can it be used with relative coordinates?

Best Answer

Before trying to answer your questions, I'd like to make it clear that this is all based on experiment and in trying to follow what goes on through the code. So it's a guess - hopefully and intelligent one, though.

  1. Is it possible to use relative coordinates in the intersection syntax (a -| b)?

    Not really. What happens is that TikZ sees the -| and assumes that the syntax is (coordinate -| coordinate). It then passes the coordinates back to the parser, but it does so as (coordinate) (since in the -| syntax there are no brackets around the coordinates).

    However, there is nothing stopping you defining a new coordinate system which is effectively a relative coordinate system. One has to be a bit careful with groupings since TikZ parses a coordinate by looking for clues and the order in which it does them is therefore important.

  2. Is there some way (macro or other) to access the current coordinate of the current path?

    Not to my knowledge but it is very easy to define one.

  3. Is it possible to use relative coordinates in the calculation syntax ($(a) + (b)$)?

    No, but once you have a \currentcoordinate macro then it's easy to use this to make relative coordinates, and once you have an extra relative coordinate system then this can be used as well.

  4. Is there a way to combine x-Part of one coordinate with the y-Part of another, other than the (a -| b) syntax? Can it be used with relative coordinates?

    Yes! (At last) This can be done using the let syntax (Section 14.15 of the PGF manual, version 2.10).

Here's an example with lots of the above. It's not stress-tested so there may be things that don't work when put in more advanced situations.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/53734/86}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\newcommand\currentcoordinate{\the\tikz@lastxsaved,\the\tikz@lastysaved}

\tikzdeclarecoordinatesystem{+}{%
  \tikz@scan@one@point\pgfutil@firstofone+(#1)%
}

\makeatother

\begin{document}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

% Angled line connecting to a straigt line. This is where my problem lies.
\draw[red] (A.140) -- ++(0,1) coordinate(temp) -- (temp -| B.50);
\end{tikzpicture}

% Some examples of what I think would be useful in this case.
% None of these things seem to be supported in TikZ.
\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) |- ({{$(\currentcoordinate)+(0,1)$}} -| B.50);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) |- ({+ cs:0,1} -| B.50);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) |- ($(+ cs:0,1) + (2,0)$);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) -- ++(0,1) -- (\currentcoordinate -| B.50);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) let \p1=(B.50), \p2=+(0,1) in |- (\x1,\y2);
\end{tikzpicture}
\end{document}

Results:

Various relative coordinates