1

I have the following code:

\documentclass[tikz,border=1pt,12pt]{standalone}
\usetikzlibrary{calc,decorations.markings,arrows.meta}
\begin{document}
\tikzset{-<-/.style={decoration={
  markings,
  mark=at position .5 with {\arrow{<}}},postaction={decorate}}}
\newcommand\Square[1]{+(-#1,-#1) rectangle +(#1,#1)}  
\begin{tikzpicture}[scale=0.5]
  \draw (2,0) circle (.7);
  \draw[-<-] ($(2,0)+(30:.7)$) to[out=30,in=90] (3.8,0) to[out=-90,in=-30] ($(2,0)+(-30:.7)$);
\end{tikzpicture}
\end{document}

the result is not very satisfying: look at the arrows

in particular the arrow is misplaced. How can I get a better result?

1

A second approach: The reason that you are having issues is because the center of the arrowhead is somewhat behind the tip. This is because of the way that tikz's arrow algorithm works. Details are available on page 1016 of the tikz manual. Anyways, to fix your problem, I can make modified versions of the standard arrowheads where this offset is set to zero. To do this, I copied the arrow definition code out of pgfcorearrows.code.tex and commented out certain offending code that defines the offsets. Here's the result:

\documentclass[tikz,border=1pt,12pt]{standalone}
\usetikzlibrary{calc,decorations.markings,arrows.meta}

\makeatletter
% copied with offending section commented out from pgfcorearrows.code.tex 
% lines 1103 to 1157
\pgfarrowsdeclare{tonooffset}{tonooffset}
{
%  \pgfutil@tempdima=-0.84pt%
%  \advance\pgfutil@tempdima by-1.3\pgflinewidth%
%  \pgfutil@tempdimb=0.21pt%
%  \advance\pgfutil@tempdimb by.625\pgflinewidth%
%  \pgfarrowsleftextend{+\pgfutil@tempdima}
%  \pgfarrowsrightextend{+\pgfutil@tempdimb}
}
{
  \pgfutil@tempdima=0.28pt%
  \advance\pgfutil@tempdima by.3\pgflinewidth%
  \pgfsetlinewidth{0.8\pgflinewidth}
  \pgfsetdash{}{+0pt}
  \pgfsetroundcap
  \pgfsetroundjoin
  \pgfpathmoveto{\pgfqpoint{-3\pgfutil@tempdima}{4\pgfutil@tempdima}}
  \pgfpathcurveto
  {\pgfqpoint{-2.75\pgfutil@tempdima}{2.5\pgfutil@tempdima}}
  {\pgfqpoint{0pt}{0.25\pgfutil@tempdima}}
  {\pgfqpoint{0.75\pgfutil@tempdima}{0pt}}
  \pgfpathcurveto
  {\pgfqpoint{0pt}{-0.25\pgfutil@tempdima}}
  {\pgfqpoint{-2.75\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}
  {\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}}
  \pgfusepathqstroke
}
\pgfarrowsdeclare{tonooffset reversed}{tonooffset reversed}
{
  %\pgfutil@tempdima=-0.21pt%
  %\advance\pgfutil@tempdima by-0.475\pgflinewidth%
  %\pgfutil@tempdimb=0.98pt%
  %\advance\pgfutil@tempdimb by1.45\pgflinewidth%
  %\pgfarrowsleftextend{+\pgfutil@tempdima}
  %\pgfarrowsrightextend{+\pgfutil@tempdimb}
}
{
  \pgfutil@tempdima=0.28pt%
  \advance\pgfutil@tempdima by.3\pgflinewidth%
  \pgfsetlinewidth{+0.8\pgflinewidth}
  \pgfsetdash{}{+0pt}
  \pgfsetroundcap
  \pgfsetroundjoin
  \pgfpathmoveto{\pgfqpoint{3.5\pgfutil@tempdima}{4\pgfutil@tempdima}}
  \pgfpathcurveto
  {\pgfqpoint{3.25\pgfutil@tempdima}{2.5\pgfutil@tempdima}}
  {\pgfqpoint{0.5\pgfutil@tempdima}{0.25\pgfutil@tempdima}}
  {\pgfqpoint{-0.25\pgfutil@tempdima}{0\pgfutil@tempdima}}
  \pgfpathcurveto
  {\pgfqpoint{0.5\pgfutil@tempdima}{-0.25\pgfutil@tempdima}}
  {\pgfqpoint{3.25\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}
  {\pgfqpoint{3.5\pgfutil@tempdima}{-4\pgfutil@tempdima}}
  \pgfusepathqstroke
}
\makeatother

\begin{document}
\tikzset{-<-/.style={decoration={
  markings,
  mark=at position .49 with {\arrow{tonooffset reversed}}},postaction={decorate}}}
\newcommand\Square[1]{+(-#1,-#1) rectangle +(#1,#1)}
\begin{tikzpicture}[scale=0.5]
  \draw (2,0) circle (.7);
  \draw[-<-] ($(2,0)+(30:.7)$) to[out=30,in=90] (3.8,0) to[out=-90,in=-30] ($(2,0)+(-30:.7)$);
\end{tikzpicture}
\end{document}
2

unusual but simple :-) :

\documentclass[tikz,border=1pt,12pt]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}
  \node (n1) [circle, minimum size=7mm, draw] {};;
  \draw (n1) to [loop, out=30,in=-30, looseness=8] coordinate (l) (n1);
  \draw[->,shorten <=5] ([yshift=-5] l) -- (l);
\end{tikzpicture}
\end{document}

enter image description here

addendum: an evolution of above solution. now incorporated in decoration:

\documentclass[tikz,border=1pt,12pt]{standalone}
\usetikzlibrary{arrows.meta, decorations.markings}

\begin{document}
    \begin{tikzpicture}[
Arr/.style = {-{Straight Barb[line width=1pt]},shorten <=5},
decoration = {markings,
              mark=at position .5 with {\draw[Arr,rotate=90] (0,5pt) -- (0,0);}}
                    ]
\node (n1) [circle, minimum size=7mm, draw] {};;
  \draw[postaction={decorate}] (n1) to [loop, out= 30,in=-30, looseness=8] (n1);
  \draw[postaction={decorate}] (n1) to [loop, out= 60,in=120, looseness=8] (n1);
  \draw[postaction={decorate}] (n1) to [loop, out=195,in=255, looseness=8] (n1);
    \end{tikzpicture}
\end{document}

enter image description here

1

How about this? I manually fixed it, but you have already split the loop into two parts, so I don't see much harm.

\documentclass[tikz,border=1pt,12pt]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[scale=0.5]
  \draw (2,0) circle (.7);
  \draw ($(2,0)+(30:.7)$) edge[out=30,in=90,->] (3.8,0) (3.8,.014) to[out=-90,in=-30] ($(2,0)+(-30:.7)$);
\end{tikzpicture}
\end{document} 
  • The point is that it seems too artificial to adjust that 0.014 offset, and it depends on other parameters of the drawing. I would like to have this set automatically – MaPo Nov 9 '17 at 14:15
  • Sure, this definitely seems annoying. I think the trick to do what you want is to make a modified version of the arrowhead... I'll see if I can do that. – Hood Chatham Nov 9 '17 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.