Редактировать:Как предполагает ответ percusse, я могу использовать transform shape
option. Мой первый вопрос теперь решен. Но хотя второй ограничивающий прямоугольник теперь локально выровнен, это не правильно. Фактически, 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
И сброс ротации кажется решением.
EDIT: Надеюсь, на этот раз я понял вашу точку зрения. Если нет, я был бы очень признателен, если бы вы объяснили это в терминах повернутых прямоугольников и фигур, а неместныйиГлобальныйкоторые являются относительной терминологией по отношению к повернутой среде изображения 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}