[Tex/LaTex] the difference between points, coordinates, and anchors in TikZ/PGF and how can I deal with them

pgfmathtikz-pgf

I should note that I am already familiar with TikZ and am I am looking for technical answers, as if TikZ weren't technical enough.

This question boils does to the following question, what is the difference between these things:

  • \def\pointA{\pgfpoint{0cm}{0cm}}
  • \coordinate (A) at (current page.north east);
  • \coordinate (A) at (1,1);
  • (current page.north east)
  • \node [anchor=east] {} <– an anchor? :-p (just demonstrating overlapping of terms)
  • \pgfpointanchor <– but this must really be an anchor, or is it a point? :-p

I think my understanding is lacking, and it is interfering with my attempts shown below.

In mathematics

A point is defined as:

A point is an exact position or location on a plane surface. It is important to understand that a point is not a thing, but a place.

A coordinate is defined as:

Coordinates are an ordered set of numbers that define the position of a point.

An anchor is:

enter image description here

I would like to clarify this with practical examples.

Let's define a coordinate:

\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library

There are many implicit coordinates (should they be called coordinates, points, or anchors or something else?) such as:

  • (current page.north west)
  • (current page.north)
  • (current page.north east)
  • (current page.east)
  • (current page.south east)
  • (current page.south)
  • (current page.south west)
  • (current page.center)

Let's say I want to calculate the vertical distance between two things (I am choosing the word "things" on purpose) AND store this variable for use outside of the current scope.

e.g. the two things are (current page.north east) and (rightmid)

To do arithmetic I know of the following options (is that all of them?):

  1. I could use \pgfmathparse to evaluate the arithmetic

  2. I could use the \path let \p1= syntax.

Using option 1, I can set \pgfxa, \pgfya to \pgfx and \pgfy for the calculations and acquire the result with \pgfmathresult.

I can then define a unique length (global) e.g. \setlength{\mylength}{2cm}. I can then use \mylength to retrieve it. This will not allow me to write everything in a self-contained macro, because \setlength may only be defined once. An alternative is to use \global\let\mylength{2cm}, which seems to me better for the job (correct me if I am wrong. Does this have implications on the value+unit/dimension)?

Putting it all together

Here is an experiment that does not compile based on a couple of answers:

\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}

% A4 Paper
\pdfpagewidth=210mm \pdfpageheight=297mm % for PDF output
\paperwidth=210mm \paperheight=297mm     % for TikZ

\newcommand{\getdistance}[3]{
\makeatletter
% Syntax: <length variable/macro> <coordinate1> <coordinate2>
  \pgfpointdiff{\pgfpointanchor{#2}{center}} % https://tex.stackexchange.com/a/39325/13552
               {\pgfpointanchor{#3}{center}} % https://tex.stackexchange.com/a/39325/13552
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgfmathparse{veclen(\pgf@xa,\pgf@ya)} 
  \global\let#1\pgfmathresult % <-- I want the pgfmathresult to be a dimension like 510 pt
\makeatother
}

\begin{document}

\begin{tikzpicture}[overlay]
\coordinate (rightmidtest) at ($ (current page.north east) + (0,-10cm) $); % use tikz calc library
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\end{tikzpicture}

\getdistance{\globalresult}{rightmidtest}{rightmid}
\getdistance{\globalresult}{current page.north east}{rightmid}
\getdistance % <-- Should expand to last distance measured
\end{document}

Updated Code 2016-02-25 Working

After analysis and newfound understanding from percusse's answer, I came up with something else.

Remember:

  • (current page) is implicit
  • anchor .center is implicit in TikZ but not in PGF \pgfpointanchor{<ref>}{<anchor e.g. center>}

I used xparse syntax for the macro because it is easier to read.

\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{xparse}

\makeatletter
\NewDocumentCommand{\getdistance}{ m m O{center} m O{center} }{%
    %Syntax: {\<macro>} {<ref1>} [<anchor>] {<ref2>} [<anchor>]
    \pgfpointdiff{\pgfpointanchor{#2}{#3}}% https://tex.stackexchange.com/a/39325/13552
                 {\pgfpointanchor{#4}{#5}}% https://tex.stackexchange.com/a/39325/13552
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    \pgfmathparse{veclen(\pgf@xa,\pgf@ya)} % result as number (floating point)
    %\pgfmathveclen{\pgf@xa}{\pgf@ya} % alternate syntax to pgfmathparse: result as number (floating point)
    %\global\let#1\pgfmathresult pt % does not recognize pt.
    \global\edef#1{\pgfmathresult\ pt}
    %\pgfmathprintnumber{\pgfmathresult}%
  }    
\makeatother    

 \begin{document}
 
\begin{tikzpicture}[remember picture,overlay]
    % (current page) is implicit
    % .center is implicit in TikZ but not in PGF \pgfpointanchor{<ref>}{<anchor e.g. center>}
    \coordinate (referral1) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
    \node [minimum height=2cm] (referral2) {};
\end{tikzpicture}
    
\begin{tikzpicture}[remember picture,overlay]
  \getdistance{\globalresultA}{current page}{referral1}
  \getdistance{\globalresultB}{current page}[north east]{referral1}
  \getdistance{\globalresultC}{current page}[north east]{referral2}[north]
  \getdistance{\globalresultD}{current page}[north east]{referral2}[south]
\end{tikzpicture}

\globalresultA

\globalresultB

\globalresultC

\globalresultD
\end{document}

Best Answer

I think the confusion comes from the fact that TikZ works with referrals not objects. When certain node name a is mentioned. It usually assumes that the user probably means its center coordinate. Or in case of drawing things between two things if one of them is a node then it computes the point on its border magically so the user doesn't notice.

But all of this is done internally. And nothing is related to nodes or else. A node has a name that you can refer to and predefined places where it understands.

None of these are stored. They are simply checked for existence or just executed. In other words, if you write shape=duck, then it doesn't go through all possible shape names, it simply does an existence check of the sort (I'm using nonsense names for the actual macros)

\pgfutil@ifdefined\pgf@Shape@#1@...{<if it exists use>}{<if not err>}

Anchors are the same deal, if you say anchor=heel, it asks for that name via some \pgf@sh@#1@anchor@#2 and so on.

Now where do these come from? They are defined at the shape declaration via \savedanchor and \anchor and so on.

So they are there and meticulously arranged so that when you refer to it everything from the textbox width height to shape path is painfully hand coded. That's why it is a very tedious job to define new shapes. And when you refer to them they are arranged in such a way that the anchor position is written (globally!) inside the length registers \pgf@<x,y>

Anyway long story short, when you refer to a node anchor actually there is a pretty involved procedure to get a coordinate out of it.

Furthermore, there is a difference between a coordinate which is \pgf@<x,y> and a coordinate type node which is \coordinate.

Finally, when you refer to a node, TikZ try to help you by assuming that you meant its center anchor so that you can save some keystrokes but occasioanlly you need to make a finer surgery such as distance measurements.

You cannot get away with referral names. You need actual coordinates (again not \coordinates). As Mark Wibrow commented, you have to somehow understand the context and that is done via \pgf@process to answer such questions: is it a literal coordinate(1,1), is it a node name, is it a node anchor etc. Then you can use the resulting \pgf@<x,y> registers.

Then you can do whatever you want with them. Your example let syntax also does an amazing job to simplify this but it is still doing what you have described. Actually your question is basically why TikZ exists on top of PGF. It is a very well designed front end to a very verbose but powerful syntax of PGF.