1

I'm merging solutions from two different questions, and encountering issues with their compatibility:

The first is from Tikz: Arrowheads in the center, allowing decorations on arrows to have an arrowhead in the middle

The second is from tikz bounding box / cropping: too much space for curves to limit the bounding box when using control points for a curve.

I'm effectively trying to create a directed graph with two loops coming from one edge, so if anyone finds a better solution that would also be great.

I can create the graph I want, but with the bounding box (brown) too large because of the control points:

generated graph with large boundary box Created by the code:

\documentclass{scrarticle}

\usepackage{tikz}
\usepackage{lipsum}

\usetikzlibrary{decorations.markings}

\begin{document}
    \usetikzlibrary{arrows,positioning}
    % arrows with middlearrow arrow head in middle
    \tikzset{middlearrow/.style={
            decoration={markings,
                mark= at position 0.5 with {\arrow{#1}} ,
            },
            postaction={decorate}
        }
%   middlearrow/.default={>}
    }
    \lipsum[66]
    \begin{center}
    \begin{tikzpicture}
        \node[circle,fill=black,inner sep=2pt,label=b] (b) at (0,0) {};
        \draw[middlearrow={>}] (b) .. controls (2,2) and (2,-2) .. (b);
        \draw[middlearrow={>}] (b) .. controls (-2,-2) and (-2,2) .. (b);
        \draw [brown] (current bounding box.south west) rectangle (current bounding box.north east);
    \end{tikzpicture}
    \end{center}
\lipsum[66]
\end{document}

To which I try to add the boundary box solution to remove extra space:

\documentclass{scrarticle}

\usepackage{tikz}
\usepackage{lipsum}

%limit boundary box: from https://tex.stackexchange.com/questions/290357/tikz-bounding-box-cropping-too-much-space-for-curves
\usetikzlibrary{calc,decorations.pathreplacing}
\tikzset{
    bezier/controls/.code args={(#1) and (#2)}{
        \def\mystartcontrol{#1}
        \def\mytargetcontrol{#2}
    },
    bezier/limit/.store in=\mylimit,
    bezier/limit=1cm,
    bezier/.code={
        \tikzset{bezier/.cd,#1}
        \tikzset{
            to path={
                let
                \p0=(\tikztostart),    \p1=(\mystartcontrol),
                \p2=(\mytargetcontrol), \p3=(\tikztotarget),
                \n0={veclen(\x1-\x0,\y1-\y0)},
                \n1={veclen(\x3-\x2,\y3-\y2)},
                \n2={\mylimit}
                in  \pgfextra{
                    \pgfmathtruncatemacro\ok{max((\n0>\n2),(\n1>\n2))}
                }
                \ifnum\ok=1 %
                let
                \p{01}=($(\p0)!.5!(\p1)$), \p{12}=($(\p1)!.5!(\p2)$), \p{23}=($(\p2)!.5!(\p3)$),
                \p{0112}=($(\p{01})!.5!(\p{12})$), \p{1223}=($(\p{12})!.5!(\p{23})$),
                \p{01121223}=($(\p{0112})!.5!(\p{1223})$)
                in
                to[bezier={controls={(\p{01}) and (\p{0112})}}]
                (\p{01121223})
                to[bezier={controls={(\p{1223}) and (\p{23})}}]
                (\p3)
                \else
                [overlay=false] .. controls (\p1) and (\p2) ..  (\p3) [overlay=true]
                \fi
            },
        }%, <-- Comma here results in "Missing character: There is no , in font nullfont!"
    },
    limit bb/.style n args={2}{
        overlay,
        decorate,
        decoration={
            show path construction,
            moveto code={},
            lineto code={\path[#2] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);},
            curveto code={
                \path[#2]
                (\tikzinputsegmentfirst)
                to[bezier={limit=#1,controls={(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)}}]
                (\tikzinputsegmentlast);
            },
            closepath code={\path[#2] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);},
        },
    },
    limit bb/.default={1mm}{draw},
}



\usetikzlibrary{decorations.markings}

\begin{document}
    \usetikzlibrary{arrows,positioning}
    % arrows with middlearrow arrow head in middle
    \tikzset{middlearrow/.style={
            decoration={markings,
                mark= at position 0.5 with {\arrow{#1}} ,
            },
            postaction={decorate}
        }
%   middlearrow/.default={>}
    }
    \lipsum[66]
    \begin{center}
    \begin{tikzpicture}
        \node[circle,fill=black,inner sep=2pt,label=b] (b) at (0,0) {};
        \draw[middlearrow={>},limit bb] (b) .. controls (2,2) and (2,-2) .. (b);
        \draw[middlearrow={>},limit bb] (b) .. controls (-2,-2) and (-2,2) .. (b);
    \end{tikzpicture}
    \end{center}
\lipsum[66]
\end{document}

which returns an error of "I cannot decorate an empty path". (The second code works as desired removing either middlearrow={>} or limit bb from only the options of both arrows)

I suppose I'm looking for a less technical way of limiting the bounding box size, with manually being an option I'd gladly use.

1 Answer 1

2

Your problem can be solved by use of the bbox library:

\documentclass{scrarticle}
\usepackage{tikz}
\usetikzlibrary{arrows,
                bbox,                % <----
                decorations.markings,
                positioning}
\usepackage{lipsum}

\begin{document}
\lipsum[66]
    \begin{center}
\begin{tikzpicture}[bezier bounding box,    % <----
middlearrow/.style={decoration={markings,
                    mark=at position 0.5 with {\arrow{#1}} ,
                                },
                    postaction={decorate}
                    }
                    ]        
\node[circle,fill=black,inner sep=2pt,label=b] (b) at (0,0) {};
\draw[middlearrow={>}] (b) .. controls (2,2) and (2,-2) .. (b);
\draw[middlearrow={>}] (b) .. controls (-2,-2) and (-2,2) .. (b);
\draw [brown] (current bounding box.south west) rectangle (current bounding box.north east);
\end{tikzpicture}
    \end{center}
\lipsum[66]
\end{document}

enter image description here

Note: Libraries should be loaded in document preamble.

2
  • Thanks! I didn't realise there was a tikz package specifically for this, it's perfect for what I need! I'll make sure to load packages in the preamble too :)
    – George
    Nov 29, 2022 at 19:32
  • @George, you are welcome!
    – Zarko
    Nov 29, 2022 at 19:49

You must log in to answer this question.

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