46

How can I shift a line the endpoints of which are defined by anchors like this?

\draw (i0) -- (i1);

The following approach does not work:

\draw[xshift=2pt] (i0) -- (i1);
h0b0
  • 5,437
  • 7
  • 35
  • 34
  • 2
    The question are ambiguous. You write anchors like anchors of node (tikz's notion) or you use another definition. I would like to know if anchors are coordinate \coordinate (i0) at (A.north west); or if anchors are nodes like in Marco's answer because the answer is not the same – Alain Matthes Jan 02 '12 at 14:39

2 Answers2

63

Approach 1

You can work with the library calc:

\draw[green] (i0) -- ($(i1)+(1,2)$);

Approach 2

Another approach based on the let operation. An example is given in the question TikZ: Node at same x-coordinate as another node, but specified y-coordinate?

\draw[blue] let \p1 = (i0) in (2,\y1) -- (i1);

Approach 3

Jake mentioned another approach. You set the shift to the coordinate directly. (this method is documented in the manual section 13 "Specifying Coordinates")

\draw ([xshift=2pt]i0) -- ([xshift=2pt]i1);

Note: By using this method will work fine if you define i0 and i1 with \coordinate. If you define i0 and i1 with \node you must give an anchor

\draw ([xshift=2pt]i0.center) -- ([xshift=2pt]i1.center);

This limitation isn't relevant for the other approaches.

Complete example with result

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\verb+Calc+
\begin{tikzpicture}
\node at (0,0) (i0){};
\node at (2,2) (i1){};
\draw[red] (i0) -- (i1);
\draw[blue] ($(i0)+(2,0)$) -- (i1);
\draw[green] (i0) -- ($(i1)+(1,2)$);
\end{tikzpicture}

\verb+let+
\begin{tikzpicture}
\node at (0,0) (i0){};
\node at (2,2) (i1){};
\draw[red] (i0) -- (i1);
\draw[blue] let \p1 = (i0) in (2,\y1) -- (i1);
\draw[green] let \p1 = (i1) in (i0) -- (\x1,4);

\draw[black] let \p0 = (i0), \p1=(i1) in (\x0,2) -- (\x1,3);
\end{tikzpicture}

\verb+shift+ 1
\begin{tikzpicture}
\node at (0,0) (i0){};
\node at (2,2) (i1){};
\draw[red] (i0) -- (i1);
\draw[blue]([xshift=2cm]i0.center) --  (i1);
\draw[green] (i0) -- ([yshift=2cm,xshift=1cm]i1.center);
\end{tikzpicture}

\verb+shift+ 2
\begin{tikzpicture}
\coordinate (i0) at (0,0) ;
\coordinate (i1) at (2,2) ;
\draw[red] (i0) -- (i1);
\draw[blue]([xshift=2cm]i0) --  (i1);
\draw[green] (i0) -- ([yshift=2cm,xshift=1cm]i1);
\end{tikzpicture}
\end{document}

enter image description here

Marco Daniel
  • 95,681
  • 8
    A different approach would be to add the transformation to the coordinate specification (so \draw ([xshift=2pt]i1) -- ([xshift=2pt]i2);). Maybe you could flesh out your answer to show examples for all three approaches? – Jake Jan 02 '12 at 11:38
  • 1
    I just tried the experiment and found that the syntax ([shift={(1,2)}]A) only works for positioning nodes. Strangely, ([shift={(1,2)}]0,0) works for arbitrary paths. I have no idea why this would be so, it seems rather illogical to me. – Andrew Stacey Jan 02 '12 at 12:18
  • 1
    Ah, I see that the answer has been edited and that it works if an explicit anchor is given. This could be a bug in how the point-on-the-perimeter is computed for a translated node. Or one could say that translating a node coordinate without a specific anchor is open to different interpretations on which anchor should be used, so translating without an anchor should not be used. – Andrew Stacey Jan 02 '12 at 12:22
  • Good. And I like the expanded commentary. (Minor typo: an extra ) in the codes in Approach 3). Incidentally, you can specify both shifts at the same time via [shift={(1,2)}] (the braces protect the comma). – Andrew Stacey Jan 02 '12 at 12:25
  • I think there is problem. When you write \draw (i0)--(i1); the line depends of the relative position of the nodes. The anchors used is not the same also when you use ([xshift=10pt]i0.center)you are not sure that center is the good anchor and with let \p0 = (i0) the problem is the same because center are used. For me the result is not fine. – Alain Matthes Jan 02 '12 at 14:42
  • I think i0 and i1 must be coordinates, if i0 and i1 are nodes then the problem is more complicated – Alain Matthes Jan 02 '12 at 14:45
  • @Altermundus: Do you think I should switch to coordinate? – Marco Daniel Jan 02 '12 at 15:10
  • It would be interesting to know what Jake and Andrew think about that. My english is not evolved enough and perhaps I don't understand the question but with nodes at (0,0) and (2,2) anchors used are north east and south west. With coordinates there are no problem. How do you understand "anchors" in the question ? – Alain Matthes Jan 02 '12 at 15:40
  • @Altermundus: "Blind leading the blind" -- My english is also bad. Based on the manual I would say anchor is east or west and so on. – Marco Daniel Jan 02 '12 at 15:49
  • @AndrewStacey and @@Jake Have you seen the comments of @@@Altermundus? What do you think? – Marco Daniel Jan 03 '12 at 09:15
  • @Jake: note Marco's comment. (Marco, only one notification works per comment Jake wouldn't have seen that one. You get this one as you wrote the answer.) – Andrew Stacey Jan 03 '12 at 09:25
  • @Altermundus That's what I was alluding to in my second comment. Specifying (-1,0) -- ([yshift=1cm]i0) is ambiguous. What coordinate should result? Do we first compute the coordinate correct for i0 (west in this example) and then shift it, or do we imagine that there is a copy of i0 at (in this case) (0,1) and then compute the anchor for that node (south west in this example). The problem isn't fully specified. So I think that both yours and Marco's answers complement each other as it is quite possible that someone wanting to do this won't have thought about this (ctd) – Andrew Stacey Jan 03 '12 at 09:33
  • 1
    @Altermundus and Marco Daniel: "anchors" are specified points on a shape, like north east, base west, 135, and so on. If you don't supply an anchor to a coordinate specification, but only a node name (like i0), an anchor on the edge the node that lies in the direction of the path is used. Only if i0 happens to be a node of the coordinate shape (created using \coordinate ... or \node [coordinate] ...), this is equivalent to the center anchor. So the original question is indeed ambiguous, as Altermundus noted. I guess it's another example of why MWEs are useful... – Jake Jan 03 '12 at 09:33
  • 1
    (ctd) until they see the possible solutions, whereupon they will decide which behaviour they want and choose accordingly. – Andrew Stacey Jan 03 '12 at 09:33
10

For me the shifting line is like the blue one

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

\begin{tikzpicture} 
\draw [help lines] (0,0) grid (3,2); 
\node[draw](i0) at (0,0) {};
\node[draw](i1) at (2,2) {};
\draw[red] (i0) -- (i1) coordinate[pos=0] (j0) coordinate[pos=1] (j1); 

\draw[thick,blue] ([xshift=1cm]j0) --  ([xshift=1cm]j1);
\draw[thick,purple] let \p0=(i0),\p1=(i1) in
         ([xshift=.5cm]\x0,\y0) --  ([xshift=.5cm]\x1,\y1);        
\end{tikzpicture} 

\end{document}

enter image description here

Alain Matthes
  • 95,075