# centre text exactly on an exactly specified point on path

I would like to place text exactly centred over an exactly specified point on a highly complex path as shown in this Figure:

I have developed my example by specifying the point at 0.1 from the beginning of path and adding a mark to it:

\documentclass[border=1cm]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.text, decorations.markings}

\begin{document}
\begin{tikzpicture}

\coordinate (A) at (0,0);
\coordinate (B) at (1, 3);
\coordinate (C) at (2, -1);
\coordinate (D) at (3, 0.5);

%placement of mark
\draw plot [smooth] coordinates { (A) (B) (C) (D) };
\path [
postaction={decorate},
decoration={
markings,
mark = at position 0.1 with {\fill[red] circle[radius=0.2cm];}
}
] plot [smooth] coordinates { (A) (B) (C) (D) };

%placement of text
\path [
postaction={decorate},
decoration={
text along path,
raise=0.4cm,
text align/left indent = {0.1\dimexpr\pgfdecoratedpathlength\relax},
text={here!!}
}
] plot [smooth] coordinates { (A) (B) (C) (D) };

\end{tikzpicture}
\end{document}


The output is

To centre the text over the mark I would only need to replace left with center in text align/left indent = {0.1\dimexpr\pgfdecoratedpathlength\relax}. Then everything would be perfect! Unfortunately after this change the example no longer compiles.

How to fix this problem?

Just add the text to the markings. (You need transform shape to rotate it to become typeset along the tangent at that point.)

\documentclass[border=1cm]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\begin{document}
\begin{tikzpicture}

\coordinate (A) at (0,0);
\coordinate (B) at (1, 3);
\coordinate (C) at (2, -1);
\coordinate (D) at (3, 0.5);

%placement of mark
\draw plot [smooth] coordinates { (A) (B) (C) (D) };
\path [
postaction={decorate},
decoration={
markings,
mark = at position 0.1 with {\fill[red] circle[radius=0.2cm];
\node[transform shape] at (0,0.5) {here!};}
}
] plot [smooth] coordinates { (A) (B) (C) (D) };

%placement of text
\end{tikzpicture}
\end{document}


Alternatively you can just subtract 50% of the width from the shift. (Note that I use in this code \pgfmathsetmacro{\mywidth}{5*width("here!!")} because 5*0.1=1/2 so in 0.1\dimexpr\pgfdecoratedpathlength-\mywidth pt\relax we subtract 50% of the width of the text.)

\documentclass[border=1cm]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.text, decorations.markings}

\begin{document}
\begin{tikzpicture}

\coordinate (A) at (0,0);
\coordinate (B) at (1, 3);
\coordinate (C) at (2, -1);
\coordinate (D) at (3, 0.5);

%placement of mark
\draw plot [smooth] coordinates { (A) (B) (C) (D) };
\path [
postaction={decorate},
decoration={
markings,
mark = at position 0.1 with {\fill[red] circle[radius=0.2cm];}
}
] plot [smooth] coordinates { (A) (B) (C) (D) };

\pgfmathsetmacro{\mywidth}{5*width("here!!")}
%placement of text
\path [
postaction={decorate},
decoration={
text along path,
raise=0.4cm,
text align/left indent ={0.1\dimexpr\pgfdecoratedpathlength-\mywidth pt\relax},
text={here!!}
}
] plot [smooth] coordinates { (A) (B) (C) (D) };

\end{tikzpicture}
\end{document}


Some style for that. (Note that I use the hobby path simply because otherwise there can be dimension too large problems. These problems have nothing to do with the specifics of the style, it is a general problem of decorated paths.)

\documentclass[tikz,border=1cm]{standalone}
\usetikzlibrary{decorations.text, decorations.markings,hobby}
\tikzset{move text/.style args={#1 to pos #2}{%
postaction={decorate,
/utils/exec=\pgfmathsetmacro{\mywidth}{(0.5/#2)*width("#1")},
decoration={
text along path,
raise=0.4cm,
text align/left indent={#2\dimexpr\pgfdecoratedpathlength-\mywidth pt\relax},
text={here!!}
}}
}}
\begin{document}
\foreach \X in {0.1,0.2,...,0.9}
{\begin{tikzpicture}[]
\path[use as bounding box] (-2,-1) rectangle (4,4);
\coordinate (A) at (0,0);
\coordinate (B) at (1, 3);
\coordinate (C) at (2, -1);
\coordinate (D) at (3, 0.5);

\draw [
postaction={decorate,
decoration={
markings,
mark = at position \X\space with {\fill[red] circle[radius=0.2cm];}
}},move text={here!!} to pos \X,
] plot [smooth,hobby] coordinates { (A) (B) (C) (D) };

\end{tikzpicture}}
\end{document}


• The marking is used in this example to highlight the exact point. What if I do not need any marking? – Viesturs Jun 25 at 16:16
• @Viesturs Just drop \fill[red] circle[radius=0.2cm];. – marmot Jun 25 at 16:18
• It turns out we are using a markings loophole to place text in a way impossible with text decorations. – Viesturs Jun 25 at 16:20
• @Viesturs I added a second proposal in which you just subtract 50% of the width of the text from the shift. This does work with the text decorations. – marmot Jun 25 at 16:22
• Your solution fails if position is changed from 0.1 to something else. How do you get 5 in \pgfmathsetmacro{\mywidth}{5*width("here!!")}. You need to explain that 0.1 is a factor to 5 to produce 0.5. If some other position is used the new coefficient is calculated as 0.5/coeff. – Viesturs Jun 27 at 16:18