编辑:正如 percusse 的回答所建议的,我可以使用transform shape
选项。我的第一个问题现在已经解决了。但是,尽管第二个边界框现在是局部对齐的,但它并不正确。事实上,local bounding box
总是计算一个全球对齐的边界框(绿点)并fit
包围该边界框的north
、、和east
锚点。south
west
我现在的问题是:如何计算local bounding box
本地对齐?
新示例(右侧的蓝色矩形不适合红色路径):
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
pt/.style={circle,minimum size=3pt,fill=#1,inner sep=0},
red pt/.style={pt=red},
green pt/.style={pt=green},
every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}[rotate=20]
\draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
% first case: fitting some nodes
\node[red pt] (a) at (.5,.5){};
\node[red pt] (b) at (.5,2){};
\node[red pt] (c) at (3,.5){};
\node[red pt] (d) at (2,2.2){};
\begin{scope}[transform shape]
\node[fit=(a)(b)(c)(d),draw=blue]{};
\end{scope}
% second case: fitting arbitrary path
\begin{scope}[local bounding box=bb]
\draw[red] (4,1) to[bend right] (6,1) -- (5,2);
\end{scope}
\node[green pt] at (bb.north west){};
\node[green pt] at (bb.north east){};
\node[green pt] at (bb.south west){};
\node[green pt] at (bb.south east){};
% how to find correct bounding box locally aligned ?
\begin{scope}[transform shape]
\node[fit=(bb),draw=blue]{};
\end{scope}
\end{tikzpicture}
\end{document}
原始问题:
我想计算一些边界框。以下是我的两个案例:
- 为了适应一些节点(或坐标),我可以使用
fit
库。 - 为了适应任意路径,我可以使用带有的范围
local bounding box=bb
。
下面的代码展示了这两种情况:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
red pt/.style={circle,minimum size=3pt,fill=red,inner sep=0},
every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}
\draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
% first case: fitting some nodes
\node[red pt] (a) at (.5,.5){};
\node[red pt] (b) at (.5,2){};
\node[red pt] (c) at (3,.5){};
\node[red pt] (d) at (2,2.2){};
\node[fit=(a)(b)(c)(d),draw=blue]{};
% second case: fitting arbitrary path
\begin{scope}[local bounding box=bb]
\draw[red] (4,1) to[bend right] (6,1) -- (5,2);
\end{scope}
\node[fit=(bb),draw=blue]{};
\end{tikzpicture}
现在,我想做同样的事情在旋转的图片中!
我的两个问题:
在我的第一个案例(某些节点)中,我必须
rotate
向我的拟合节点添加选项(因为rotate
选项不会旋转节点)。如何自动找到此选项的正确值(例如:当前坐标系和画布坐标系之间的角度)?在我的第二种情况下(任意路径),我可以计算局部边界框但全局对齐。如何计算任意路径局部对齐的局部边界框?
这是我的尝试:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
red pt/.style={circle,minimum size=3pt,fill=red,inner sep=0},
every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}[rotate=20]
\draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
% first case: fitting some nodes
\node[red pt] (a) at (.5,.5){};
\node[red pt] (b) at (.5,2){};
\node[red pt] (c) at (3,.5){};
\node[red pt] (d) at (2,2.2){};
% how to find the good value for rotate (here 20)?
\node[rotate=20,fit=(a)(b)(c)(d),draw=blue]{};
% second case: fitting arbitrary path
\begin{scope}[local bounding box=bb]
\draw[red] (4,1) to[bend right] (6,1) -- (5,2);
\end{scope}
% how to find bounding box locally aligned ?
\node[rotate=20,rotate fit=-20,fit=(bb),draw=blue]{};
\end{tikzpicture}
\end{document}
答案1
我是不是错过了重点?transform shape
重置旋转似乎是一个解决方案。
编辑:我希望这次我明白你的意思了。如果没有,我真的很感激你能用旋转的矩形和形状来解释,而不是当地的和全球的这是相对于旋转的 Tikz 图片环境的相对术语。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
pt/.style={circle,minimum size=3pt,fill=#1,inner sep=0},
red pt/.style={pt=red},
green pt/.style={pt=green},
every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}[rotate=20]
\draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
% first case: fitting some nodes
\node[red pt] (a) at (.5,.5){};
\node[red pt] (b) at (.5,2){};
\node[red pt] (c) at (3,.5){};
\node[red pt] (d) at (2,2.2){};
\begin{scope}[transform shape]
\node[fit=(a)(b)(c)(d),draw=blue]{};
\end{scope}
\pgfgettransform{\currtrafo} %Save the current trafo
% second case: fitting arbitrary path
\begin{scope}[local bounding box=bb]
\pgftransformresetnontranslations % Now there is no rotation and it doesn't know
% things are going to be rotated
\begin{scope} % We open a new scope and restore the outer trafo
\pgfsettransform{\currtrafo} % inside the scope
\draw[red] (4,1) to[bend right] (6,1) -- (5,2); % Draw anything
\end{scope} % Now the trafo is reset again
\node[fit=(bb),draw=blue]{}; % Externally it doesn't know the content is
% rotated or not
\end{scope} % Back to original trafo.
\end{tikzpicture}
\end{document}
答案2
笔记:我终于自己找到了解决方案......但我不能给我自己的赏金。;-)
我定义了三种风格:
memoize points
命名路径的每个点(借助memoizepoints
计数器)并将这些名称累积到全局宏(其参数)中。cont memoize points
与 相同memoize points
,但不重置全局宏(其参数)。init memoize points
重置全局宏(其参数)和memoizepoints
计数器。
以下是序言:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit,intersections,decorations.pathreplacing,decorations.markings}
柜台memoizepoints
和三种风格:
\newcounter{memoizepoints}
\tikzset{
init memoize points/.code={\xdef#1{}\setcounter{memoizepoints}{0}},
cont memoize points/.style={postaction={
decorate,decoration={show path construction,
moveto code={},
lineto code={
\foreach \coord in {\tikzinputsegmentfirst,\tikzinputsegmentlast}{
\addtocounter{memoizepoints}{1}
\coordinate(memoizepoints-\arabic{memoizepoints}) at (\coord);
\xdef#1{#1 (memoizepoints-\arabic{memoizepoints})}
}
},
curveto code={
\foreach \coord in {\tikzinputsegmentfirst,\tikzinputsegmentsupporta,%
\tikzinputsegmentsupportb,\tikzinputsegmentlast}{
\addtocounter{memoizepoints}{1}
\coordinate(memoizepoints-\arabic{memoizepoints}) at (\coord);
\xdef#1{#1 (memoizepoints-\arabic{memoizepoints})}
}
},
closepath code={
\foreach \coord in {\tikzinputsegmentfirst,\tikzinputsegmentlast}{
\addtocounter{memoizepoints}{1}
\coordinate(memoizepoints-\arabic{memoizepoints}) at (\coord);
\xdef#1{#1 (memoizepoints-\arabic{memoizepoints})}
}
},
},
},
},
memoize points/.style={init memoize points=#1,cont memoize points=#1},
}
然后是一个例子,后面是它的代码:
\begin{document}
\begin{tikzpicture}[rotate=30,inner sep=0pt,line width=1pt]
\tikzset{
pt/.style={circle,minimum size=3pt,fill=#1,inner sep=0},
red pt/.style={pt=red},
}
\draw[gray,line width=.4pt] (0,0) grid (9.5,5.5);
% first case: fitting some nodes
\node[red pt] (a) at (.5,.5){};
\node[red pt] (b) at (.5,2){};
\node[red pt] (c) at (3,.5){};
\node[red pt] (d) at (2,2.2){};
\begin{scope}[transform shape]
\node[fit=(a)(b)(c)(d),draw=blue]{};
\end{scope}
% second case: fitting arbitrary path
\draw[red,memoize points=\allpoints] (4,1) to[bend right] (6,1) -- (5,2);
\begin{scope}[transform shape]
\node[fit=\allpoints,draw=blue]{};
\end{scope}
% another example of fitting arbitrary path
\draw[red,memoize points=\allpoints] (8,1.2) circle ();
\begin{scope}[transform shape]
\node[fit=\allpoints,draw=blue]{};
\end{scope}
% another example of fitting arbitrary paths
\begin{scope}[yshift=2cm]
\draw[red,memoize points=\allpoints]
plot[domain=4:8,samples=100] (\x,{2+sin(3 * \x r)});
\draw[red,cont memoize points=\allpoints]
plot[domain=4:8,samples=100] (\x,{2.1+cos(3 * \x r)});
\end{scope}
\begin{scope}[transform shape]
\node[fit=\allpoints,draw=blue]{};
\end{scope}
\end{tikzpicture}