# Accessing the logic values of a TikZ coordinate

In TikZ accessing the coordinate values of a node can be done using the let syntax of the calc library or using the PGF command \pgfpointanchor. However, this values are dimensions/lengths in points and not the values of the used coordinate system. For example, I like to label certain points and nodes in the graph with their logical coordinate values, e.g. in a standard tikzpicture, i.e. with x=1cm,y=1cm in effect, a point at (1,2) should be labeled with (1,2) not with (28.4527pt,56.9055pt). The nodes are not positioned manually, but using the various relative positioning techniques of TikZ, so I don't know the coordinates myself. This is about normal 2-D XY coordinate systems with orthogonal X and Y axes.

The way I do this at the moment is to get the length of a unit vector in points and divide the coordinate lengths with it to calculate the corresponding value of the used coordinate system. This works OK, but of course results in rounding errors, e.g. 1.9998 instead of 2. I then use the \num function of siunitx to round the numbers to a fitting number of digits.

My question: Is there a better way to achieve this for arbitrary TikZ coordinates?
I mean something more user-friendly and maybe provided by TikZ itself (I didn't found anything in the manual). Especially: Can TikZ/PGF round the number as well without an extra package? A guess TikZ converts coordinates always quickly to length, so that rounding errors are unavoidable (except using x=1pt,y=1pt maybe).

Here my proof-of-concept solution. It is very inflexible at the moment because it only works for nodes.

\documentclass[png]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\usepackage[round-mode=places]{siunitx}

\makeatletter
\newcommand\xcoord[2][center]{{%
\pgfpointxy{1}{1}%
\@tempdima=\pgf@x
\pgfpointanchor{#2}{#1}%
\@tempdimb=\pgf@x
\pgfmathparse{\@tempdimb/\@tempdima}%
\num{\pgfmathresult}%
}}
\newcommand\ycoord[2][center]{{%
\pgfpointxy{1}{1}%
\@tempdima=\pgf@y
\pgfpointanchor{#2}{#1}%
\@tempdimb=\pgf@y
\pgfmathparse{\@tempdimb/\@tempdima}%
\num{\pgfmathresult}%
}}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw [help lines] (0,0) grid [step=1] (2,4);
\draw [name path=A] (0,0) -- (2,4);
\draw [name path=B] (2,0) -- (0,4);
\draw [name intersections={of=A and B}]
(intersection-1)
node [right] {(\xcoord{intersection-1},\ycoord{intersection-1})}
circle (2pt);
\end{tikzpicture}
\end{document}


-
What other things (other than nodes) would you want to use the function for? I can't think of a way to refer to a coordinate other than through a node. –  Jake May 15 '11 at 18:38
@Jake: Any numeric (x,y) coordinate or node anchor points for example. Here coordinate doesn't need to be a \coordinate. –  Martin Scharrer May 15 '11 at 18:54

PGF has the \pgfmathprintnumber macro that allows you to print and format numbers, including rounding. To round to two decimal digits, you would use \pgfmathprintnumber[precision=2]{\pgfmathresult}, for example.

The unit vectors are stored in \pgf@xx (for the x-component of the x unit vector) and \pgf@yy (the y-component of the y unit vector). So your function could be shortened to

\makeatletter
\newcommand\xcoord[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@x/\pgf@xx}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\newcommand\ycoord[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@y/\pgf@yy}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\makeatother

-
Thanks, that's exactly what I was looking for to solve the rounding part of my question. I gives me (1,2) in the above example. –  Martin Scharrer May 15 '11 at 17:56
Thanks for updating your question to include \pgf@xx and \pgf@yy. They make my live simpler. I saw there are also \pgf@xy and \pgf@yx, but there are zero; for orthogonal coordinate systems I guess. –  Martin Scharrer May 15 '11 at 19:30
Are you sure that it is safe to use \pgf@x and \pgf@y inside \pgfmathparse{...}. –  Martin Scharrer May 15 '11 at 20:14
@Martin: I don't see why it wouldn't be. If the \pgfmathparse follows the \pgfpointanchor directly, \pgf@x should hold the correct value. It's used in a \pgfmathparse expression in tikzlibrarygraphs.code.tex, though there it is preceded by \the. –  Jake May 15 '11 at 20:38
@Jake: It should be save as long \pgfmathparse doesn't change it before reading it. I had a look in tikzlibrarygraphs.code.tex and can't find any use of it in the current version (2.10). –  Martin Scharrer May 16 '11 at 11:54

Here is another method to extract coordinate values from a node or an anchor. Its advantage is to provide these values ​​taking account of the current origin.

\makeatletter
\def\extractcoord#1#2#3{
\path let \p1=(#3) in \pgfextra{
\pgfmathsetmacro#1{\x{1}/\pgf@xx}
\pgfmathsetmacro#2{\y{1}/\pgf@yy}
\xdef#1{#1} \xdef#2{#2}
};
}
\makeatother


Example:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\def\extractcoord#1#2#3{
\path let \p1=(#3) in \pgfextra{
\pgfmathsetmacro#1{\x{1}/\pgf@xx}
\pgfmathsetmacro#2{\y{1}/\pgf@yy}
\xdef#1{#1} \xdef#2{#2}
};
}
\makeatother
\pagestyle{empty}
\begin{document}
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,4);
\begin{scope}[shift={(1,1)}]
\coordinate (A) at (0,0);
\coordinate (B) at (2,3) ;
\coordinate (C) at ($(A)!.5!(B)$);
\fill[red] (A) circle(2pt);
\fill[red] (B) circle(2pt);
\fill[blue] (C) circle(2pt);
\extractcoord\x\y{C}
\end{scope}
\extractcoord\xb\yb{C}
\end{tikzpicture}

Inner scope: $(\x,\y)$\par
Global scope: $(\xb,\yb)$\par
Inner scope (fixed precision):
$(\pgfmathprintnumber[precision=2]{\x},\pgfmathprintnumber[precision=2]{\y})$\par
\end{document}

-