6

If I extract coordinates with \pgfgetlastxy{}{}, I get changing results depending on the transformations I've applied to my draw (rotation, scale):

\documentclass[margin=0.5cm]{standalone}
\usepackage{tikz}

\newcommand{\myDraw}[2]{%
\begin{minipage}[t]{6cm}
  \centering #1,#2\\
  \begin{tikzpicture}[#1,#2]
    \draw[->] (0,0) -- (3,0);
    \draw[->] (0,0) -- (0,3);
    \coordinate (A) at (1,3);
    \draw[blue] (A) node {$+$} node[above right] {\footnotesize A(2,3)};
    \path (A); \pgfgetlastxy{\xA}{\yA}; % Extract the coordinates of A
    \draw[red] (canvas cs:x=\xA,y=\yA)
      node {$+$} node[red,below right] {\parbox{2.5cm}{\footnotesize \textbackslash xA = \xA\\\textbackslash yA = \yA}};
  \end{tikzpicture}
\end{minipage}}

\begin{document}
  \myDraw{scale=1}{rotate=0}
  \myDraw{scale=0.5}{rotate=0}
  \myDraw{scale=1}{rotate=-20}
\end{document}

Output

And yet, I want to get the coordinates of A in the current scope (i.e \xA = 1 and \yA = 3 in the example above) because I need to apply later some conditionals (like "if \xA < \xb then...").

I was thinking maybe of using a command like \pgftransformreset inside a group and then "smuggle" the non transformed coordinates out of the group. But I'm mostly an LaTeX/TikZ end user and I don't know how to achieve that.

  • Are A coords always fixed? – percusse Aug 29 '13 at 21:35
  • In the macro I'm working on, it's an intersection point (it will be different if I change the parameter of the macro). – remjg Aug 29 '13 at 21:41
  • Related: this thread (It seems that some consider an alternative to the one-node-path-method \path (A); \pgfgetlastxy{\xA}{\yA}; % Extract the coordinates of A more recommendable. – Peter Heinig Jul 16 '17 at 12:25
7

Numbers get slightly distorted due to internal transformation inersion.

\documentclass[margin=0.5cm]{standalone}
\usepackage{tikz}
\makeatletter
\newcommand{\myDraw}[2]{%
\begin{minipage}[t]{6cm}
  \centering #1,#2\\
  \begin{tikzpicture}[#1,#2]
    \draw[->] (0,0) -- (3,0);
    \draw[->] (0,0) -- (0,3);
    \coordinate (A) at (1,3);
    \draw[blue] (A) node {$+$} node[above right] {\footnotesize A(2,3)};
    \pgfpointanchor{A}{center} %<----
    \edef\xa{\the\pgf@x}
    \edef\ya{\the\pgf@y}       %<----
    \draw[red] (canvas cs:x=\xa,y=\ya)
               node {$+$} node[red,below right] {\parbox{2.5cm}{\footnotesize%
               \textbackslash xA = \xa\\\textbackslash yA = \ya}};

  \end{tikzpicture}
\end{minipage}}
\makeatother
\begin{document}
  \myDraw{scale=1}{rotate=0}
  \myDraw{scale=0.5}{rotate=0}
  \myDraw{scale=1}{rotate=-20}
\end{document}

enter image description here

The marked code can be replaced with a higher level TikZ syntax

\path (A); \pgfgetlastxy{\xA}{\yA}; % Extract the coordinates of A
\begin{scope}
\pgftransforminvert
\coordinate (B) at (\xA,\yA);\path (B); \pgfgetlastxy{\xB}{\yB};    
\xdef\xorigA{\xB}
\xdef\yorigA{\yB}
\end{scope}

which does more or less the same thing.

  • Note that there is a low level smuggle mechanism for PGF but let me know if you need it. – percusse Aug 29 '13 at 22:06
  • Nice! Since I need to do that many times, I have included your code in a separate macro which can be called like this: \extractCoordinates{A}{\xA}{\yA}. I've pasted the definition of the macro below: \newcommand{\extractCoordinates}[3]{% \begin{scope} \path (#1); \pgfgetlastxy{\xTEMP}{\yTEMP}; % Extract the coordinates of A \pgftransforminvert \coordinate (TEMP) at (\xTEMP,\yTEMP);\path (TEMP); \pgfgetlastxy{\xTEMP}{\yTEMP}; \xdef#2{\xTEMP} \xdef#3{\yTEMP} \end{scope}} I run quickly into some troubles so I had to change the names of the variables. Any advice on how to improve it? – remjg Aug 29 '13 at 22:41
  • @remjg I've simplified a little – percusse Aug 29 '13 at 23:47
  • Indeed, it's way simpler, I like it! I'm going to chose this answer but I have two requests if you don't mind. Could you post your previous answer in an other answer? I think it's a valuable answer, at least for learning. Also, do you mind if I add a macro version at the end of your answer? – remjg Aug 30 '13 at 8:16
  • @remjg Sure be my guest. I've put the old version. – percusse Aug 30 '13 at 15:28
5

Here a solution, without the low level macro \pgfgetlastxy, via a let operation:

enter image description here

\documentclass[margin=0.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\myDraw}[2]{%
\begin{minipage}[t]{6cm}
  \centering #1,#2\\
  \begin{tikzpicture}[#1,#2]
    \draw[->] (0,0) -- (3,0);
    \draw[->] (0,0) -- (0,3);
    \coordinate (A) at (1,3);
    \draw[blue] (A) node {$+$} node[above right] {\footnotesize A(2,3)};

    \path [green!50!black]
    let \p1=(A) in
    (\x1,\y1)  node {$+$}
    node[below right,align=left,font=\footnotesize]{
      \textbackslash xA = \x1\\
      \textbackslash yA = \y1
    };

  \end{tikzpicture}
\end{minipage}}

\begin{document}
  \myDraw{scale=1}{rotate=0}
  \myDraw{scale=0.5}{rotate=0}
  \myDraw{scale=1}{rotate=-20}
\end{document}

If you need these macro definitions after the path and its let operation, you may:

  • use \xdef:

\path let \p1=(A) in
  \pgfextra{
    \xdef\xA{\x1}
    \xdef\yA{\y1}
  };
  • use \AfterGroup (from etextools package):

\usepackage{etextools}
...
\path let \p1=(A) in
  \pgfextra{
    \AfterGroup*{
      \noexpand\def\noexpand\xA{\x1}
      \noexpand\def\noexpand\yA{\y1}
    }
  };
  • Thank you! The issue with the let operation is that it can only be used inside a path. I need to access to the coordinates inside conditionals later on. – remjg Aug 29 '13 at 22:20
  • After a few tries, I can use the let operation and an empty node to define \xA and \yB so I can use them later: \draw let \p1=(A) in (A) node {\xdef\xA{\x1}\xdef\yA{\y1}}; But I don't know really what \xdef is (a king of global variable I imagine) and I gess it's quite a bad pratice... – remjg Aug 30 '13 at 10:08
  • 2
    @remjg You don't need the node to \xdef (yes it globally defines \xA while expanding its content (\x1 and \y1 here), you can do \path let \p1=(A) in \pgfextra{\xdef…};. – Qrrbrbirlbel Aug 30 '13 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.