自定义定义与装饰的兼容性以及从边界框中删除控制点空间

自定义定义与装饰的兼容性以及从边界框中删除控制点空间

我正在合并两个不同问题的解决方案,但遇到了兼容性问题:

第一个来自Tikz:箭头位于中心,允许箭头上的装饰在中间有一个箭头

第二个来自tikz 边界框/裁剪:曲线空间太大使用曲线的控制点时限制边界框。

我实际上是在尝试创建一个有向图,其中两个循环来自一个边,所以如果有人找到更好的解决方案,那就太好了。

我可以创建我想要的图形,但是由于控制点的原因,边界框(棕色)太大:

生成具有大边界框的图形 由代码创建:

\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}

我尝试添加边界框解决方案来删除多余的空间:

\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}

返回错误“我无法修饰空路径”。(第二段代码按预期工作,只需从两个箭头的选项中删除其中一个middlearrow={>}或即可)limit bb

我想我正在寻找一种不太技术性的方法来限制边界框大小,手动是一种我乐意使用的选项。

答案1

您的问题可以通过使用该bbox库来解决:

\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}

在此处输入图片描述

笔记:应在文档前言中加载库。

相关内容