TikZ 提供了两个键execute at end picture={<code>}
和,分别execute at end scope={<code>}
可用于执行图片末尾和当前的任何代码scope
。
我现在喜欢在图片末尾执行一些代码,如果我定义的 TikZ 键在环境之外使用scope
,即在 的可选参数中;tikzpicture
或者在 内部使用时,即在其可选参数中,则在范围末尾执行scope
一些代码。我还喜欢分别访问该区域的边界框,即完整的边界框或仅访问范围的边界框。
有没有简单的方法可以做到这一点?还应该支持级联范围。我认为没有可能检测我是否在范围内。理论上,整体本身tikzpicture
就是一个范围,execute at end scope
似乎可以工作,但手册明确指出它只能在scope
环境的可选参数中使用。我知道“本地边界框”,但这样我就必须对每个范围使用不同的名称来避免冲突。
答案1
这是跟踪局部边界框问题的部分解决方案。也许你可以从这个想法中得到一些启发(请注意,这个想法还没有经过很好的测试)。
\documentclass{article}
\usepackage{tikz}
\makeatletter
\tikzset{every scope/.append style={
execute at begin scope={
% save the bounding box
\pgfpointanchor{current bounding box}{south west}
\pgfgetlastxy\tsx@outerbb@minx\tsx@outerbb@miny
\pgfpointanchor{current bounding box}{north east}
\pgfgetlastxy\tsx@outerbb@maxx\tsx@outerbb@maxy
% clear the bounding box
\pgfresetboundingbox
},
execute at end scope={
% do something useful with the scope bounding box
\draw (current bounding box.south west) rectangle (current bounding box.north east);
% reestablish the outer bounding box.
\expandafter\ifdim\tsx@outerbb@minx<16000pt
\path (\tsx@outerbb@minx, \tsx@outerbb@miny) rectangle (\tsx@outerbb@maxx,\tsx@outerbb@maxy);
\fi
}}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\fill[red] (0,0) circle (2cm);
\begin{scope}[xshift=3cm,scale=0.8,blue]
\fill[blue] (0,0) circle (1cm);
\begin{scope}[green]
\fill (0,0.5) circle (0.3cm);
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
每当 PGF 停止跟踪边界框时(例如在clip
或 之后transform canvas
),这种情况就会有所中断。为了防止它在这些情况下(以及当存在空范围时)严重中断,至少应在当前边界框过大时禁用“绘制当前边界框”。
还值得注意的是,任何与范围边界框配合使用的代码都必须在重新建立外部边界框之前执行。不幸的是,我不知道有哪个版本execute at end scope
添加了新代码前已经在结束范围钩子中的代码。(当然,通过排列定义中的代码来编写这样的键并不难execute at end scope
。)