13

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}
3
  • Nice question, was wondering about these things too. However, I'm having troubles compiling your code. I'm getting Undefined control sequence. ...nce{\globalresult}{rightmidtest}{rightmid}.
    – Ondrian
    Feb 24, 2016 at 15:34
  • @Ondrian My does not compile and I am aware of that. I will adjust my text for future readers. getdistance macro does not work. just comment them out. Feb 24, 2016 at 16:00
  • 1
    \makeatletter\def\getdistance#1#2#3{\pgfpointdiff{\tikz@scan@one@point\pgf@process(#2)}{\tikz@scan@one@point\pgf@process(#3)}\pgfmathveclen{\the\pgf@x}{\the\pgf@y}\edef#1{\pgfmathresult pt}} Feb 24, 2016 at 16:44

4 Answers 4

8

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.

5
\def\pointA{\pgfpoint{0cm}{0cm}}

Use this only if you are familiar with PGF (The foundation of TikZ). Anyway, it is not important what \pgfpoint does in TeX; this command never exists alone. Usually it is part of the syntax, for instance

\coordinate (A) at (current page.north east);

gives a point a name. It is not important what the actual x- and y-coordinates are. We know where (A) is, and that is all we need to know.

\coordinate (A) at (1,1);

Similar to the previous one. Usually we name points to (A) cut down the code length/complexity and (B) improve legibility. For instance

(current page.north east)

With parenthesis, it issues a move to action. It is much like you, holding a pen, move your hand to the next place you want to draw something. For instance

This code makes TikZ move its pen all around the canvas and declare nodes/coordinates.

\node [anchor=east] {}

place a node "near" the pen's current position. By "near", I mean that the anchor you give should coincide the pen's position. It is much like you, on a boat, can throw the anchor to where you want and that anchor will then fix the boat.


practical part

  • you need \makeatletter.
  • you probably want \pgfmathsetlength instead of \pgfmathsetmacros or \pgfmathparse.
    • but remember, all dimensions must be declared prior to its usage.
  • be careful when you are using the node (current page). Usually you need [overlay].
  • you need to be inside a tikzpicture environment to retrieve anything you made in a tikzpicture environment.
    • if you are not doing the job in the same tikzpicture environment, you need [remember picture].

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

\makeatletter
\newcommand{\getdistance}[3]{
% Syntax: <length variable/macro> <coordinate1> <coordinate2>
  \pgfpointdiff{\pgfpointanchor{#2}{center}} % http://tex.stackexchange.com/a/39325/13552
               {\pgfpointanchor{#3}{center}} % http://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
}

\begin{document}

\begin{tikzpicture}[remember picture,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}

\tikz[remember picture,overlay]{
    \getdistance{\globalresulta}{rightmidtest}{rightmid}
    \getdistance{\globalresultb}{current page}{rightmid}
}

\globalresulta

\globalresultb

\end{document}
5
  • Thanks. The answer does not get as technical (getting into PGF) as much as I'd hoped, or address the particular differences between the items I listed. Please understand, I don't mean to come across as rude, but I am going to keep this open and wait for more information (see what answers show up). The issues with \makeatother and overlay were just left out by my laziness when copying code to this site. I fixed that up. I am moderately experienced with TikZ. Feb 24, 2016 at 17:30
  • Also, your code fails if you write \getdistance{\globalresultb}{current page.north east}{rightmid} Feb 24, 2016 at 17:45
  • @macmadness86 I am sort of confused whether you want to focus on theory or the task you gave below. For the later, you cannot "take anchor" twice; the problem is that the definition and the usage of \getdistance do not match.
    – Symbol 1
    Feb 24, 2016 at 17:53
  • Mostly theory, but both. I want to know why, for example, why setting \coordinate (A) at (current page.north east); then applying it in my macro \getdistance{\globalresultb}{A}{rightmid} works, but using \getdistance{\globalresultb}{current page.north east}{rightmid} does not. I think that truly understanding the subtle differences between the things I listed in my question will be helpful. Feb 24, 2016 at 17:58
  • @macmadness86 that is indeed a good question.
    – Symbol 1
    Feb 24, 2016 at 18:07
3
  1. \def\pointA{\pgfpoint{0cm}{0cm}}

    This is basically the same as \coordinate (A) at (0,0);

  2. \coordinate (A) at (current page.north east);

    Here you're just naming the top right corner of the page as A. It's pointless in the sense that the location is already named, but it can be helpful not having to type all of that and just write A.

  3. \coordinate (A) at (1,1);

    Coordinates in TikZ are basically nodes with the coordinate shape, they don't require a caption and, especially important, they don't have sep. So it's a point. Still, writing \node[coordinate] (a) at (0,0) {}; equals to \coordinate (a) at (0,0);

    See also TikZ: difference between \node and \coordinate?

  4. (current page.north east)

    This indicates the top-right corner of the current "page". Typically this would be an A4 page, but it can be any dimension. Page in this case is not necessarily intended as the usual piece of paper, but it can be any designated area.

  5. \node [anchor=east] {} <-- an anchor?

    No, this is not an anchor. It's a node whose positioning is determined by placing the designed anchor at the coordinate. So \node [anchor=east] at (4,0) {}; will place the node having the east anchor coincide with the coordinate (4,0).

2
  • But was is #4 exactly? I know what it indicates, that is obvious. I am looking for clarification of terminology and why a term is appropriate (also applied knowledge-why choose one over other, equivalencies, etc.). Haha, I know that number 5 is not an anchor. I just threw that in the mix to demonstrate the overlap of terms we throw around. Nice explanation there though! Feb 24, 2016 at 17:37
  • @macmadness86 Well, if you knew it was an anchor, why did you write it like that? I cannot read minds. :P Not sure what "clarification" you want. (current page.north east) is not that opaque a concept, but if you could specify what you want to know, I can fix that.
    – Alenanno
    Feb 24, 2016 at 17:39
1

I do not know how to edit my old answer. I will simply write a new one.

In TikZ there are many ways to specifying points

  • Give numeric coordinates.
    For example (1,2), (3mm,4in,5pt), (6:7), (axis cs:x=8).

  • Give predefined node name and anchor name.
    For example (current page.south east), (current bounding box.north west).

  • Give predefined node name.
    For example (current page). This is equivalent to (current page.center)

  • Give predefined coordinate.
    For example \coordinate(X)at(1,2);\path(X);. A coordinate is actually a node, of which anchors "vanish": (X), (X.center), (X.south), and (X.34) all give the same result.

Their PGF counter parts are

  • \pgfpointxy, \pgfpointxyz, \pgfpointpolar, and so on
  • \pgfpointanchor{#1}{#2}
  • \pgfpointanchor{#1}{center}
  • \pgfpointanchor{#1}{center}

Now you see that in the definition of \getdistance, one can only fill-in a node name and the anchor center is chosen mandatory. Therefore

\getdistance{\globalresultb}{current page.north east}{rightmid}

does not compile because current page.north east is not a node anymore. But

\coordinate (A) at (current page.north east);
\getdistance{\globalresultb}{A}{rightmid}

does compile because (A) is the name of a node.

It is up to you what kind of input \getdistance can handle. For example in TikZ, \tikz@parse@node can handle both (X) and (Y.Z). but not (1,2). More generally \tikz@@scan@@no@calculator and handle (X), (Y.Z), and (1,2). Even more generally \tikz@@@scan@@absolute can handle ($ (current page.north east) + (0,-10cm) $). You need to choose one.

2
  • 1
    Isn't there an edit button below your answer on the left?
    – Alenanno
    Feb 24, 2016 at 19:01
  • @Alenanno I have a hard time understanding OP's purpose. I give up to edit my old anwawer because it is very different form this one; I do not know how to mix these two.
    – Symbol 1
    Feb 24, 2016 at 19:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .