Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I need a macro to extract the x and y coordinates from an arbitrary point, like (3,4), or like (A), or like ([xshift=-2pt] A.north west), where A is the name of a node.

I've seen the solution

 \newdimen\mydim
 \newcommand\getx[1]{
      \pgfextractx\mydim{\pgfpointanchor{#1}{center}}
 }

elsewhere on StackExchange, but this obviously won't work for all the cases described above. I need to be able to call \getx{(3,4)} and \getx{(A)} and \getx{([xshift=-2pt] A.north west)}, and for them all to work equally well, in this case putting the x-coordinate of the argument into the variable \mydim.

I'm kind of stunned how hard this seems to be! Surely I've missed something...

share|improve this question
    
You could use \coordinate (tmp) at #1 and then extract the coordinates from (tmp). –  Caramdir Nov 4 '11 at 23:14
1  
Great! Why not post it as a solution, unless you're not bothered about the rep :). –  Jamie Vicary Nov 4 '11 at 23:17
    
I'm not bothered about the rep and I currently don't want to write and test a full solution :). Maybe a bit later (unless someone else already provides a full solution by then). –  Caramdir Nov 4 '11 at 23:20
2  
For a lot of these cases the let operation looks like a good fit. You can just go let \p1 (3,4) in (\x1,0) -- (\x1,\y1) then \x1 and \y1 will hold the 3 and 4 respectively. You can even do multiple points at once. All of this is within a \path the TikZ manual discusses it on page 150. –  Roelof Spijker Nov 5 '11 at 0:35
    
Roelof's answer is a good one for my case. FYI, the "let" command is discussed in section 14.15 of the TikZ manual for version 3.0.0, starting on page 161. –  Derek Sep 9 at 0:40

3 Answers 3

You can use \pgfgetlastxy{\XCoord}{\YCoord} to extract the x,y coordinate of the most recently used point into the dimension registers \XCoord and {\YCoord}. To make the point the most recently used, I use \path macro just before extraction. Here is an example where I define points, extract the x and y coordinates, and then label them via the extracted coordinates:

enter image description here

\documentclass[border=2pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\newdimen\XCoord
\newdimen\YCoord

\newcommand*{\ExtractCoordinate}[1]{\path (#1); \pgfgetlastxy{\XCoord}{\YCoord};}%
\newcommand*{\LabelCurrentCoordinate}[2]{\fill [#1] ($(\XCoord,\YCoord)$) circle (2pt) node [right] {#2}}%

\begin{document}
\begin{tikzpicture}
    \coordinate (A) at (3,2);
    \coordinate (B) at ([xshift=-15pt] A.north west);

    \ExtractCoordinate{$(A)$};
    \LabelCurrentCoordinate{red}{A};

    \ExtractCoordinate{$(B)$};
    \LabelCurrentCoordinate{blue}{B};

    \ExtractCoordinate{$(1,1)$};
    \LabelCurrentCoordinate{green}{C};
\end{tikzpicture}
\end{document}
share|improve this answer

The answers from Peter, Jamie, and wh1t3 (the last one in the comments) are all fine. I'm adding this as a "low level" version since this is often something that one wants to do as a part of a bigger thing, and then it can be useful to know how to do it at this lower level.

The TikZ command that scans a coordinate and figures out where it actually corresponds to is called \tikz@scan@one@point. It sort-of takes two arguments. The first is a macro, the second is the point to be scanned. The "sort-of" is because the second argument isn't an argument, it's just the bare coordinate. The coordinate is parsed until TikZ feels that it understands it enough to produce an honest x-y coordinate on the page, whereupon is called the macro with that x-y coordinate as its argument (specifically, it calls \themacro{\pgfpoint{x-coord}{y-coord}}. By specifying the macro to be \@firstofone (or \pgfutil@firstofone if we want to be good PGFers) we can set \pgf@x and \pgf@y to be those coordinates. If we want to save them, we could either pass a fancy saving macro or simply save the values of \pgf@x and \pgf@y afterwards.

Here's a simple example where we define a macro that takes three arguments, being the coordinate and two macros in which to save the x and y coordinates.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/33703/86}
\usepackage{tikz}
\makeatletter
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw (0,0) .. controls +(1,0) and +(-1,0) .. node[auto] (A) {A} (3,3);
\gettikzxy{(A)}{\ax}{\ay}
\fill[red,fill opacity=.5] (\ax,\ay) circle[radius=12pt];
\begin{scope}[rotate=45,xshift=3cm]
\draw (0,0) -- node[auto] (B) {B} (3,2);
\end{scope}
\gettikzxy{(B)}{\bx}{\by}
\fill[blue,fill opacity=.5] (\bx,\by) circle[radius=12pt];
\gettikzxy{([xshift=-2cm] A.north west)}{\cx}{\cy}
\fill[green] (\cx,\cy) circle[radius=2pt];
\fill ([xshift=-2cm] A.north west) circle[radius=1pt];
\end{tikzpicture}
\end{document}

(The last one is taken from your question but I changed the shift to 2cm so that it would be more obvious.)

The result is:

get TikZ coordinates

share|improve this answer
    
I was very keen on using this, but unfortunately it doesn't seem to work with pgfplots: I add this: \begin{axis} ; \addplot[name path global=cfunc,blue,domain=0:3.1] {sin(deg(x))} ; \node[auto, name path global=D] (D) at (2,2) {D} ; \gettikzxy{(D)}{\ax}{\ay} ; \end{axis} right before the \end{tikzpicture} in this snippet, and the failure is: "Package pgf Error: No shape named D is known." (neither are the other nodes from an axis environment known). Any possibility for that kind of use? –  sdaau Feb 16 at 23:35
1  
@sdaau My guess is that the axis environment saves up its drawing commands until the end, so the D node is not positioned until the axis environment is finished. Within the axis environment then \gettikzxy is executed straight away and so before D is positioned. If you shift the \gettikzxy after the \end{axis} then it seems to work. Can you use it like that? –  Loop Space Feb 17 at 10:18
    
Thanks for the answer @LoopSpace - it makes sense; I'd guess it will work that way (unfortunately, I lost the original example leading to the comment). Cheers! –  sdaau Jun 26 at 5:27

This feels very wrong, but I'll do it anyway...

\newdimen{\tempx}
\newdimen{\tempy}
\newcommand\getxy[1]{
    \coordinate (tmp) at #1;
    \pgfextractx\tempx{\pgfpointanchor{tmp}{center}}
    \pgfextracty\tempy{\pgfpointanchor{tmp}{center}}
}
share|improve this answer
7  
Suggestion: Compile this code snippet in a working MWE and it will be more valuable. That way interested users can see exactly how to utilize your "wrong doings". :) –  Werner Nov 5 '11 at 1:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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