3

I have the following code:

\documentclass[tikz,border=4pt]{standalone} \usetikzlibrary{matrix} \begin{document} \begin{tikzpicture} \matrix (P) [ matrix of nodes, nodes={circle,draw}, column sep=1cm, row sep=1cm] { A & B & C \\ D & E & F \\ G & H & I \\ }; \draw[red] (P-1-1) -- (P-2-3); \draw[blue] ([shift={(.5cm,.5cm)}]P-2-1) node[rectangle,draw] {why not from here?} -- (P-3-3); \fill[green,draw] ([shift={(.5cm,.5cm)}]P-2-1) circle [radius=2pt] -- (P-3-3); \end{tikzpicture} \end{document} 

I want the ([shift={(.5cm,.5cm)}]P-2-1) to start from the "green" point, but in:

\draw[blue] ([shift={(.5cm,.5cm)}]P-2-1) node[rectangle,draw] {why not from here?} -- (P-3-3); 

It doesn't perform as my expected.

result

What cause this? How can I use ([shift={(.5cm,.5cm)}]P-2-1) to locate the "green point"'s position?

Edit

If I use ++(.5cm,.5cm) syntax, it's hard to do something below:

I want to plot the cyan line(in only ONE path, and better not to define aux coordinate/nodes), but with green path's syntax, shift is not parsed as my expected intuitively.

\documentclass[tikz,border=4pt]{standalone} \usetikzlibrary{matrix} \begin{document} \begin{tikzpicture} \matrix (P) [ matrix of nodes, nodes={circle,draw}, column sep=1cm, row sep=1cm] { A & B & C \\ D & E & F \\ G & H & I \\ }; \draw[red] (P-1-1) -- (P-2-3); \draw[green] (P-2-1) -- ++(.5cm,.5cm) -- ([shift={(-5mm,-5mm)}]P-3-3) -- (P-3-3) ; \draw[cyan] (P-2-1) ++(.5cm,.5cm) coordinate (x) -- (P-2-1) (P-3-3) ++(-.5cm,-.5cm) -- (x) (P-3-3) ++(-.5cm,-.5cm) coordinate (y) (y) -- (P-3-3) ; \end{tikzpicture} \end{document} 

re-edit

11
  • 1
    what are you trying to do that it makes hard? I don't know what the output is meant to be. Commented Aug 23 at 16:32
  • 1
    well, it is not so good either as you are not drawing the path continuously. the ++ syntax is convenient in some places, less so in others. I would use it at the start here, but not at the end, most likely. or I would set the coordinates first. \draw[green] (P-3-3) ++(-5mm,-5mm) coordinate (y) (P-2-1) -- ++(5mm,5mm) coordinate (x) -- (y) -- (P-3-3);. Commented Aug 23 at 16:57
  • 1
    hmm, interesting. I would have expected that to work. shift can be funny. I am not sure if this is a bug or a feature I do not understand. Commented Aug 23 at 17:05
  • 1
    but, as I say, I did not realise that would not work. I assumed it would and I think it rather strange it does not. Commented Aug 23 at 20:53
  • 1
    @cfr yep, maybe use consecutive ([shift=<...>]P-x-y) is not always the best, but these strange shift behaviour of the nodes in matrix is what make me totally confused.... IMHO, it's more like a bug. Commented Aug 24 at 6:35

5 Answers 5

3

Yet another workaround: do not omit the anchor and use \draw ([shift={(.5cm,.5cm)}]P-2-1.center) -- ...;.

In OP's \fill path

\fill[green,draw] ([shift={(.5cm,.5cm)}]P-2-1) circle [radius=2pt] -- (P-3-3); 

the (center of the) filled green circle is exactly at ([shift={(.5cm,.5cm)}]P-2-1). Then this coordinate is saved as "last position" and used as the start point of the following line-to operation -- (P-3-3).

In a simplified \draw path with no per-coordinate transformation options ([shift={(.5cm,.5cm)}]...)

\draw[blue] (P-2-1) node[rectangle,draw] {why not from here?} -- (P-3-3); 

the resulted line-to operation is part of the line joining centers of two nodes, but shortened so that the start and end points are exactly on the node borders. These points are border points.

Let's denote them by (P-2-1.{atan(2)-90}) and (P-3-3.{180-atan(.5)}), using the (<node name>.<angle>) syntax.

Then in OP's \draw path

\draw[blue] ([shift={(.5cm,.5cm)}]P-2-1) node[rectangle,draw] {why not from here?} -- (P-3-3); 

it's ambiguous what should be the expected start and end points of the resulted line-to path operation, if the shift={(.5cm,.5cm)} is not (fully) ignored.

Here OP expects that the start point should be ([shift={(.5cm,.5cm)}]P-2-1.center), but one can also expect it to be ([shift={(.5cm,.5cm)}]P-2-1.{atan(2)-90}).

Unfortunately tikz decided to ignore the shift={(.5cm,.5cm)} in determining the start point of the lint-to path operation. It's still respected in the saved "last position", which explains why the green filled circle is at ([shift={(.5cm,.5cm)}]P-2-1.center), in OP's \fill path.

In more details, when parsing a \path, \draw, etc., tikz holds two data about the last position: it's computed coordinate and whether it's a shape border.

  • The computed coordinate always respect the coordinate transformation options given as ([<options>]<coord>).
  • If the last position is a shape border and the current path operation supports border points, the coordinate of the last position is recomputed. It's this re-computation that ignores OP's shift={(.5cm,.5cm)}.

Breaking either of the conditions eliminates the ambiguity:

  • Make the last position (after initial move-to) not a shape border
    • use (<node>.<anchor>) or (<node>.<angle>) is instead of (<node>);
    • use node shape coordinate which has no border, thus (x) is always interpreted as (x.center).
  • Use path operations that don't support border points
    • The only operations that support border points are --, -|, |- and the .. as part of the curve-to operation controls ...
    • Workaround (P-2-1) +(.5cm, .5cm) belongs to this type, as the +(.5cm, .5cm) is a move-to operation which doesn't support border points. So after +(.5cm, .5cm), the last position is not a shape border anymore.
    • OP's \fill path belongs to this type too, in which the following path operation is circle. circle updates the last position so it's not a border point any more.
    • OP's \draw path didn't break this condition, because node is not a path operation. node only uses the last position but won't update it.
1
  • Ala! The \fill ... circle [radius=2pt] and \draw[blue] ... node[rectangle,draw] {} is originally just intended to point out the exact position, but it happened to show the distortion between "the start point of the lint-to path operation" and "the saved 'last position' "😀 Thanks for yr detailed supplement again! Commented Aug 26 at 18:38
4

Here is another possible approach.

\documentclass[tikz,border=4pt]{standalone} \usetikzlibrary{matrix} \begin{document} \begin{tikzpicture} \matrix (P) [ matrix of nodes, nodes={circle,draw}, column sep=1cm, row sep=1cm] { A & B & C \\ D & E & F \\ G & H & I \\ }; \draw[red] (P-1-1) -- (P-2-3); \draw[green] ([shift={(.5cm,.5cm)}]P-2-1) coordinate (S) node[rectangle,draw=blue,text=blue,anchor=center]{why not from here?} (S) -- (P-3-3); \fill[green,draw] (S) circle[radius=2pt]; \end{tikzpicture} \end{document} 

enter image description here

3

You can move by (.5,.5) like this:

\documentclass[tikz,border=4pt]{standalone} \usetikzlibrary{matrix} \begin{document} \begin{tikzpicture} \matrix (P) [ matrix of nodes, nodes={circle,draw}, column sep=1cm, row sep=1cm] { A & B & C \\ D & E & F \\ G & H & I \\ }; \draw[red] (P-1-1) -- (P-2-3); \draw[blue] (P-2-1) ++(.5cm,.5cm) node[rectangle,draw] {why not from here?} -- (P-3-3); \fill[green,draw] ([shift={(.5cm,.5cm)}]P-2-1) circle [radius=2pt] -- (P-3-3); \end{tikzpicture} \end{document} 

enter image description here

1
  • It work, but I found it not so neat to use twice in a path. See my edit. Commented Aug 23 at 14:52
0

As @muzimuzhi paraphase in issues #1407 and #1409

The maybe simpler solution for this is to use node with <anchor> together with shift:

\documentclass[tikz,border=4pt]{standalone} \usetikzlibrary{matrix} \begin{document} \begin{tikzpicture} \matrix (P) [ matrix of nodes, nodes={circle,draw}, column sep=1cm, row sep=1cm] { A & B & C \\ D & E & F \\ G & H & I \\ }; \draw[red] (P-1-1) -- (P-2-3); \draw[green] (P-2-1) -- ++(.5cm,.5cm) -- ([shift={(-5mm,-5mm)}]P-3-3) -- %<- this `shift` will be ignored for path operation "--" after that (P-3-3) ; \draw[cyan] (P-2-1) -- ([shift={(.5cm,.5cm)}]P-2-1.center) -- ([shift={(-5mm,-5mm)}]P-3-3.center) -- (P-3-3) ; \end{tikzpicture} \end{document} 

result

Now the syntex:

\draw[cyan] (P-2-1) -- ([shift={(.5cm,.5cm)}]P-2-1.center) -- ([shift={(-5mm,-5mm)}]P-3-3.center) -- (P-3-3) ; 

is more smoothly than the original

\draw[cyan] (P-2-1) ++(.5cm,.5cm) coordinate (x) -- (P-2-1) (P-3-3) ++(-.5cm,-.5cm) -- (x) (P-3-3) ++(-.5cm,-.5cm) coordinate (y) (y) -- (P-3-3) ; 

without clumsy aux (x) and (y)...

-1

shift expects polar coordinates. Giving cartesian ones won't compile. Use xshift and yshift if you prefer cartesian (with units) as option. - Kindly watch the syntax used.

\documentclass[tikz,border=4pt]{standalone} \usetikzlibrary{matrix} \begin{document} \begin{tikzpicture} \matrix (P) [ matrix of nodes, nodes={circle,draw}, column sep=1cm, row sep=1cm] { A & B & C \\ D & E & F \\ G & H & I \\ }; \draw[red] (P-1-1) -- (P-2-3); \draw[blue] ([shift=(45:2)]P-2-1) node[rectangle,draw] {polar shift} -- (P-3-3); \draw ([xshift=1cm,yshift=.5cm]P-2-1) node[rectangle,draw,magenta] {x- and y-shift} -- (P-3-3); \fill[green,draw] ([shift={(.5cm,.5cm)}]P-2-1) circle [radius=2pt] -- (P-3-3); \end{tikzpicture} \end{document} 

result


Voting to delete? Kindly review the pages given in the manual first, cited in my comment.

8
  • 1
    "shift expects polar coordinates." But in \fill[green,draw] ([shift={(.5cm,.5cm)}]P-2-1)..., the ([shift={(.5cm,.5cm)}]P-2-1) locate the "green" point correctly? Commented Aug 23 at 14:56
  • 2
    shift allows Cartesian coordinates and compiles just fine. Commented Aug 23 at 15:13
  • 2
    it works fine with cartesian, but you are missing needed braces shown in the example you quote from the manual. polar coords don't use commas so can get away without braces. Commented Aug 23 at 16:27
  • 3
    @MS-SPO yes, because colons are not commas so you can get away with omitting the braces for polar. Commented Aug 23 at 16:29
  • 1
    Thanks for pointing out. Lucky me? Well, even the manual (V 3.1.9a) uses it: pages 136 (relative coordinate shift), 624 (anchor points), 1149 (coordinate) , also within chain-syntax ... Commented Aug 23 at 16:59

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.