该\DrawBoundingBox
宏在具有 1pt 边框的图形周围绘制边界框。
在使用 生成的第一个图中\MyNode\MyNode
,没有对 的边界框进行任何调整tikz
。由于循环的控制点,这会导致左侧和右侧的边界框略宽,顶部的边界框大得多。底部的间距似乎是正确的。在这种情况下,使用默认边界框,两个图形按需要彼此相邻放置。
在第二幅图中,我使用\MyNode*
中断循环的边界框并手动调整高度以获得正确的边界框。此图显示边界框调整是正确的,因为它具有所需的1pt
间距全部四边。
但是,当我将两个带有边界框调整的图形放在一起时,\MyNode*\MyNode*
它们似乎重叠了(第三个图形)。似乎宏use as bounding box
中的第二个实例\DrawBoundingBox
已被忽略。
我希望分两步完成此操作,因为这样每个图形都可以在调用之前调整自己的边界框,\DrawBoundingBox
并根据需要添加额外的调整。
我需要做哪些更改,以便调整边界框后的图形可以彼此相邻放置,而不会与边界框重叠。
代码:
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\newcommand*{\DrawBoundingBox}[1][]{%
\draw [
use as bounding box,% <-- this seems to have no effect
draw=gray,
]
([shift={(-1pt,-1pt)}]current bounding box.south west)
rectangle
([shift={(1pt,1pt)}]current bounding box.north east);
}
\tikzset{Loop Style/.style={loop above, ultra thick, red, distance=1.0cm, ->}}
\newcommand*{\BBoxTweakForLoopDistance}{0.75cm}%
\NewDocumentCommand{\MyNode}{s}{%
\begin{tikzpicture}[baseline]
\node [draw=black, circle] (A) at (0,0) {a};
\IfBooleanTF{#1}{% Interrupt bounding box for * variant
\begin{pgfinterruptboundingbox}
\path (A) edge[Loop Style] (A);
\end{pgfinterruptboundingbox}
\path [use as bounding box]%% Expand bounding box to include the loop path
(current bounding box.south west)
rectangle
([shift={(0pt,\BBoxTweakForLoopDistance)}]current bounding box.north east);
}{%
\path (A) edge[Loop Style] (A);
}%
\DrawBoundingBox
\end{tikzpicture}%
}
\begin{document}
\MyNode\MyNode
\quad
\MyNode*
\quad
\MyNode*\MyNode*
\end{document}
答案1
这不是问题的答案,我还没有完全理解重置边界框的工作原理。然而,在我看来,你想在贝塞尔曲线周围画一个紧密的边界框,不幸的是 Ti钾Z 考虑了控制点,因此会放大边界框。这已经讨论过了这里在本例中,可以用一个简单的技巧来建立紧密的边界框:
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\newcommand*{\DrawBoundingBox}[1][]{%
\draw [
draw=gray,
]
([shift={(-1pt,-1pt)}]current bounding box.south west)
rectangle ([shift={(1pt,1pt)}]current bounding box.north east);
}
\tikzset{Loop Style/.style={loop above, ultra thick, red, distance=1.0cm, ->}}
\newcommand*{\BBoxTweakForLoopDistance}{0.75cm}%
\NewDocumentCommand{\MyNode}{s}{%
\begin{tikzpicture}[baseline]
\node [draw=black, circle] (A) at (0,0) {a};
\IfBooleanTF{#1}{% Interrupt bounding box for * variant
\path[overlay] (A) edge[Loop Style] coordinate[midway](X) (A) ;
\path (X);
}{%
\path (A) edge[Loop Style] (A);
}%
\DrawBoundingBox
\end{tikzpicture}%
}
\begin{document}
\MyNode\MyNode
\quad
\MyNode*
\quad
\MyNode*\MyNode*
\end{document}
我知道这并不能真正回答您的问题,但可能会让您更简单地实现我认为的目标。
答案2
正如 marmot 指出的那样,第 15.8 节:建立边界框(第 175 页)指出use as bounding box
:
...当前路径的边界框用于确定图片的大小,所有后续路径的大小将被忽略。但是,如果先前的路径操作已经建立了更大的边界框,则此操作不会使其变小(考虑
\pgfresetboundingbox
重置先前边界框的命令)。从某种意义上说,用作边界框与根据当前路径剪切所有后续绘图具有相同的效果 - 无需实际进行剪切,仅使 pgf 将所有内容视为已剪切。
这与我的想法相反,我的想法是,这将设置当前边界框,而未来的路径将改变边界框,就像没有一样use as bounding box
。
然而,文档中进一步指出
注意:如果在 TEX 组 ( ) 内的路径上使用此选项
scope
,则效果仅“持续”到 结束scope
。同样,此行为与剪辑相同。考虑\useasboundingbox
与 一起使用\pgfresetboundingbox
,以便用新边界框替换边界框。
因此,如果我总是use as bounding box
在scope
\begin{scope}
\path [use as bounding box]%% Expand bounding box to include the loop path
(current bounding box.south west)
rectangle
([shift={(0pt,\BBoxTweakForLoopDistance)}]current bounding box.north east);
\end{scope}
我得到的行为与我认为use as bounding box
应该做的行为一致:
代码:
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\newcommand*{\DrawBoundingBox}[1][]{%
\draw [
use as bounding box,% <-- this seems to have no effect
draw=gray,
]
([shift={(-1pt,-1pt)}]current bounding box.south west)
rectangle
([shift={(1pt,1pt)}]current bounding box.north east);
}
\tikzset{Loop Style/.style={loop above, ultra thick, red, distance=1.0cm, ->}}
\newcommand*{\BBoxTweakForLoopDistance}{0.75cm}%
\NewDocumentCommand{\MyNode}{s}{%
\begin{tikzpicture}[baseline]
\node [draw=black, circle] (A) at (0,0) {a};
\IfBooleanTF{#1}{% Interrupt bounding box for * variant
\begin{pgfinterruptboundingbox}
\path (A) edge[Loop Style] (A);
\end{pgfinterruptboundingbox}
\begin{scope}
\path [use as bounding box]%% Expand bounding box to include the loop path
(current bounding box.south west)
rectangle
([shift={(0pt,\BBoxTweakForLoopDistance)}]current bounding box.north east);
\end{scope}
}{%
\path (A) edge[Loop Style] (A);
}%
\DrawBoundingBox
\end{tikzpicture}%
}
\begin{document}
\MyNode\MyNode
\quad
\MyNode*
\quad
\MyNode*\MyNode*
\end{document}