# Tikz: The position of a label change step-wise and not in a continuous way

Consider the following MEW. I do not understand why the position of the label of i2 change step-wise and not in a continuous way. With 178-180 I get

With 175-177 I get

The first is too low, the second too high... It's an error of mine or a weakness of the system?

\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{calc,patterns,angles,quotes,intersections}
\begin{document}
\noindent\hrulefill
\begin{center}
\begin{tikzpicture}[scale=0.5,
dot/.style 2 args={circle,inner sep=1pt,fill,label={#2},name=#1},
dot2/.style 2 args={circle,inner sep=.6pt,draw=black, fill=white,label={#2},name=#1},
dot3/.style 2 args={circle,inner sep=.8pt,draw=black, fill=white,label={#2},name=#1},
extended line/.style={shorten >=-#1,shorten <=-#1},
extended line/.default=1cm]

\draw[help lines,step=1] (-1,-1) grid (10,6);
\draw [->] (-1,0) -- (10,0) node [below left]  {$x$};
\draw [->] (0,-1) -- (0,6) node [below left] {$y$};

\node [dot={p1}{[below=1.5mm]$p_1$}] at (3,1) {};
\node [dot={p2}{[above right]$p_2$}] at (8,0) {};
\node [dot={p3}{[above=1mm]$p_3$}] at (3.5,2.5) {};
\node [dot={p4}{[above right]$p_4$}] at (6,3) {};

\coordinate (i1) at (intersection of p1--p2 and p3--p4);
\coordinate (i2) at (intersection of p1--p3 and p2--p4);
\draw [extended line=0.3cm] (p2) -- (i1) ;
\draw [extended line=0.3cm] (p2) -- (i2) ;
\draw [extended line=0.3cm] (p4) -- (i1) ;
\draw [extended line=0.3cm] (p1) -- (i2) ;
\draw [thick] (p1) -- (p2);
\draw [thick] (p2) -- (p4);
\draw [thick] (p3) -- (p4);
\draw [thick] (p3) -- (p1);
\draw [very thick,extended line=0.3cm] (i1) -- (i2) ;
\coordinate (i3) at (intersection of p2--p3 and i1--i2);
\coordinate (o) at (intersection of p2--p3 and p1--p4);
\coordinate (i4) at (intersection of i1--o and p2--p4);
\coordinate (i5) at (intersection of i2--o and p1--p2);
\coordinate (i6) at (intersection of i1--o and p1--p3);
\coordinate (i7) at (intersection of i2--o and p3--p4);
\draw [very thin,extended line=0.3cm] (p1) -- (p4) ;
\draw [very thin,extended line=0.3cm] (p2) -- (i3) ;
\draw [very thin,extended line=0.3cm] (i1) -- (i4) ;
\draw [very thin,extended line=0.3cm] (i2) -- (i5) ;
\node[dot2,label={}] at (o) {};
\node[dot2,label={}] at (i4) {};
\node[dot2,label={}] at (i5) {};
\node[dot2,label={}] at (i6) {};
\node[dot2,label={}] at (i7) {};
\node[dot3,label={[above]$i_1$}] at (i1) {};
\node[dot3,label={[label distance=0mm]176.0:$i_2$}] at (i2) {}; % <<<=====
\end{tikzpicture}
\end{center}
\noindent\hrulefill
\end{document}

• increase the label distance to see the effect. – nidhin Aug 17 '19 at 14:33
• Note that a label is implemented as a separate node, which would give you more control to do manually. \path (i1) node[doct3] ++(150:1em) node{$i_1$}; – John Kormylo Aug 17 '19 at 14:43
• @JohnKormylo Thank you. Here the checked version of your proposal: \path (i2) node[dot3] {} ++(160:1.5em) node{$i_2$} ; – PeptideChain Aug 17 '19 at 15:01
• one plus sign + is enough \path (E) +(-75:2mm) node[scale=.8,blue]{E}; – Black Mild Aug 19 '19 at 2:18

The behavior you encountered is duly documented in the TikZ & PGF manual, precisely on page 247 for version 3.1.4b. Relevant quotes:

1. The 〈angle〉 is used to determine a position on the border of the main node. (...)
2. Then, an anchor point for the label node is computed. It is determined in such a way that the label node will “face away” from the border of the main node. (...) For angles between these “major” angles, like 30° or 110°, combined anchors, like south west for 30° or south east for 110° , are used. However, for angles close to the major angles, (differing by up to 2° from the major angle), the anchor for the major angle is used. Thus, a label at a border point for 2° will have the anchor west, while a label for 3° will have the anchor south west, resulting in a “jump” of the anchor. You can set the anchor “by hand” using the anchor key or indirect keys like left.

So, to achieve precise positioning, either use the suggestion given in comments (like \path (i2) ++(160:1.5em) node{$i_2$} ;) or apply what the last quoted sentence says using the anchor option, as in

\node[label={[label distance=0mm, anchor=0] 180:$i_2$}] at (i2) {};


or

\node[label={[label distance=0mm, anchor=357] 177:$i_2$}] at (i2) {};


Here, the 177 corresponds to 〈angle〉 in the above quote from the manual and is relative to the empty node created by \node (...) at (i2) {}; (the default is above, i.e., 90), whereas the anchor=357 concerns the node created by the label option. I kept a difference of 180° between them so that they face each other. Here is the output with:

\node[label={[label distance=0mm, anchor=345] 165:$i_2$}] at (i2) {};


To understand the positioning well, I suggest to try something like this:

\node[name=aaa, draw,
label={[draw, label distance=0mm, anchor=345] 165:$i_2$}]
at (i2) {};
\fill[red] (aaa.165) circle (1pt);


This way, the function that maps the angle to the $i_2$ label is continuous (modulo the limited precision of floating point representation), but as mentioned in the comments, one can make the function even more regular by using the circle shape for both nodes:

\node[name=aaa, circle, draw,
label={[circle, draw, label distance=0mm, anchor=345] 165:$i_2$}]
at (i2) {};
\fill[red] (aaa.165) circle (1pt);


Note: the label distance is followed according to the direction determined by 〈angle〉 in the main node options, not the direction indicated with anchor in the label option. For some reason I don't know, it seems though that the distance between both anchors of interest is the double of that indicated with the label distance option:

\node[name=aaa, circle, draw,
label={[name=bbb, circle, draw, label distance=8mm, anchor=310] 270:$i_2$}]
at (i2) {};
\fill[red] (aaa.270) circle (1pt);
\fill[blue] (bbb.310) circle (1pt);
\draw[orange!35, <->] (aaa.270) -- node[right] {$d$} +(0,-16mm);


• very interesting, thank you – PeptideChain Aug 17 '19 at 18:10
• @Schrödinger'scat judging from the last picture of the answer, intuitively, two objects have to become circles, to achieve smoothness + constant distance by changing angle – PeptideChain Aug 17 '19 at 18:12
• I added some precisions regarding this. We already had the continuity (modulo floating or fixed point representation), so “any position” could already be obtained with the rectangle shape; but it is true that the mapping from angle to label position must be more regular with the circle shape for both nodes—which I used in the last code snippet and screenshot. – frougon Aug 17 '19 at 20:46
• very interesting – PeptideChain Aug 17 '19 at 20:55

Too long for a comment.
Continous variation can be seen for higher label distance.

\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{calc,patterns,angles,quotes,intersections}
\begin{document}
\begin{tikzpicture}[
dot3/.style 2 args={circle,inner sep=.8pt,fill=black,label={#2},name=#1},]

\coordinate (i2) at (0,0);
\draw[thin,gray] (i2) -- ++(178:105mm);
\draw[thin,gray] (i2) -- ++(179:105mm);
\draw[thin,gray] (i2) -- ++(180:105mm);

\node[dot3,label={[label distance=0mm]178.0:$i_2$}] at (i2) {}; % <<<=====
\node[dot3,label={[label distance=0mm]179.0:$i_2$}] at (i2) {}; % <<<=====
\node[dot3,label={[label distance=0mm]180.0:$i_2$}] at (i2) {}; % <<<=====

\node[dot3,label={[label distance=50mm,blue]178.0:$i_2$}] at (i2) {}; % <<<=====
\node[dot3,label={[label distance=50mm,blue]179.0:$i_2$}] at (i2) {}; % <<<=====
\node[dot3,label={[label distance=50mm,blue]180.0:$i_2$}] at (i2) {}; % <<<=====

\node[dot3,label={[label distance=100mm,red]178.0:$i_2$}] at (i2) {}; % <<<=====
\node[dot3,label={[label distance=100mm,red]179.0:$i_2$}] at (i2) {}; % <<<=====
\node[dot3,label={[label distance=100mm,red]180.0:$i_2$}] at (i2) {}; % <<<=====

\end{tikzpicture}
\end{document}