12

I need to design a custom arrowtip in TikZ, but so far I haven't had much luck. I have been able to define a circle arrow with the arrows meta library, but I cannot figure out how to add the plus sign in the center. Can anyone help me out with this?

Arrow with custom tip

The code for a circle arrow head:

\documentclass[border=1pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\tikzset{circleplus/.tip={Circle[open]}}

\begin{document}

\begin{tikzpicture}
  \draw [-circleplus] (0,0)  -- +(1,0);
\end{tikzpicture} 

\end{document} 

3 Answers 3

13

I couldn't see how to combine existing arrows but you can modify the definition of Circle easily enough:

enter image description here

\documentclass[border=1pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\makeatletter


\pgfdeclarearrow{
  name = CircleP,
  defaults = {
    length  = +2.39365pt +3.191538,
    width'  = +0pt 1,
    line width = +0pt 1 1,
  },
  setup code = {
    % Cap the line width at 1/2th of the length
    \pgf@x.5\pgfarrowlength
    \ifdim\pgf@x<\pgfarrowlinewidth
      \pgfarrowlinewidth\pgf@x
    \fi
    \ifpgfarrowreversed
      \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}
    \else
      \pgfarrowssetlineend{.5\pgfarrowlinewidth}
    \fi
    \pgfarrowssettipend{\pgfarrowlength}
    % The hull:
    \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth}
    \pgfarrowsupperhullpoint{.75\pgfarrowlength}{.5\pgfarrowwidth}
    \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth}
    \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth}
    \ifpgfarrowharpoon%
      \pgfarrowshullpoint{0pt}{-.5\pgfarrowlinewidth}
      \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth}
    \fi%
    % The following are needed in the code:
    \pgfarrowssavethe\pgfarrowlinewidth
    \pgfarrowssavethe\pgfarrowlength
    \pgfarrowssavethe\pgfarrowwidth
  },
  drawing code = {
    \pgfsetdash{}{+0pt}
    \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi
    \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi
    \ifpgfarrowharpoon
      \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x
          by-.5\pgfarrowlinewidth}{0pt}}
      {%
        \pgf@xa.5\pgfarrowlength
        \advance\pgf@xa by-.5\pgfarrowlinewidth
        \pgftransformxscale{+\the\pgf@xa}
        \pgf@xa.5\pgfarrowwidth
        \advance\pgf@xa by-.5\pgfarrowlinewidth
        \pgftransformyscale{+\the\pgf@xa}
        \pgfpathmoveto{\pgfqpoint{-.5\pgfarrowlength}{0pt}}
        \pgfpathlineto{\pgfqpoint{.5\pgfarrowlength}{0pt}}
        \pgfpatharc{0}{180}{1pt}
      }
      \pgfpathclose
    \else%
        \pgfpathmoveto{\pgfqpoint{.25\pgfarrowlength}{0pt}}
        \pgfpathlineto{\pgfqpoint{.75\pgfarrowlength}{0pt}}
        \pgfpathmoveto{\pgfqpoint{.5\pgfarrowlength}{.25\pgfarrowlength}}
        \pgfpathlineto{\pgfqpoint{.5\pgfarrowlength}{-.25\pgfarrowlength}}
      \pgfpathellipse{\pgfqpoint{.5\pgfarrowlength}{0pt}}{\pgfqpoint{.5\pgfarrowlength\advance\pgf@x
          by-.5\pgfarrowlinewidth}{0pt}}{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y
          by-.5\pgfarrowlinewidth}}
    \fi
    \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi
  },
  parameters = {
    \the\pgfarrowlinewidth,%
    \the\pgfarrowlength,%
    \the\pgfarrowwidth,%
    \ifpgfarrowharpoon h\fi%
    \ifpgfarrowopen o\fi%
    \ifpgfarrowroundjoin j\fi%
  },
}


\tikzset{circleplus/.tip={
CircleP[open]}}

\begin{document}

\begin{tikzpicture}
  \draw [-circleplus] (0,0)  -- +(1,0);
\end{tikzpicture} 

\end{document} 
9

You could probably define a new arrow tip, as described in Custom arrow tip with arrows.meta TikZ library

If you don't need the full power of declaring a new arrow, you could just use a marking:

\documentclass[tikz, border=2pt]{standalone}
\usetikzlibrary{decorations.markings}
\tikzset{
  -circleplus/.style = {
    decoration={markings,
                mark=at position 1 with
                  {\draw[fill=white] (-2pt,0) circle (2pt);
                   \draw[-] (-3pt,0) -- (-1pt,0) (-2pt,1pt) -- (-2pt,-1pt);
                  }
                },
    postaction={decorate}
  }
}
\begin{document}
\begin{tikzpicture}
  \draw[-circleplus] (0,0) .. controls (.5,0) .. (1,1);
\end{tikzpicture}
\end{document}

marked path

This won't combine with other arrow tips in the usual way, but you can still add an arrow tip at the other end using, e.g., \draw[-circleplus, <-] .... You'd have to define a separate command for circleplus- if you want to use that.

4

@David Carlisle said that he

couldn't see how to combine existing arrows

but he definitely know how: put things together and apply negative spaces.

\tikzset{circleplus/.tip={.
    Circle[open,length=0 10,sep=0 -7.5]
    Rectangle[length=0 5,width=0 1,sep=0 -3]
    Rectangle[length=0 1,width=0 4]
}}

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.