Editar:Como lo sugiere la respuesta de percusse, puedo usar transform shape
la opción. Mi primera pregunta ya está resuelta. Pero aunque el segundo cuadro delimitador ahora está alineado localmente, no es correcto. De hecho, local bounding box
siempre calcula unglobalmentecuadro delimitador alineado (puntos verdes) y fit
encierra north
, east
, south
y west
anclajes de este cuadro delimitador.
Mi pregunta ahora es: ¿cómo calcular unlocal bounding box
en la zona¿alineado?
Nuevo ejemplo (el rectángulo azul de la derecha no se ajusta al trazado rojo):
\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}
Pregunta original:
Quiero calcular algunos cuadros delimitadores. Aquí están mis dos casos:
- Para ajustar algunos nodos (o coordenadas), puedo usar
fit
la biblioteca. - para ajustarse a rutas arbitrarias, puedo usar un alcance con
local bounding box=bb
.
El siguiente código muestra estos dos casos:
\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}
Ahora quiero hacer las mismas cosas.dentro de una imagen rotada!
Mis dos preguntas:
En mi primer caso (algunos nodos), tengo que agregar
rotate
una opción a mi nodo de ajuste (ya querotate
la opción no rota los nodos).¿Cómo encontrar automáticamente el valor correcto para esta opción (por ejemplo, el ángulo entre el sistema de coordenadas actual y el sistema de coordenadas del lienzo)?En mi segundo caso (rutas arbitrarias), puedo calcular el cuadro delimitador local pero alineado globalmente.¿Cómo calcular el cuadro delimitador local alineado localmente de una ruta arbitraria?
Aquí está mi intento:
\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}
Respuesta1
¿Me estoy perdiendo el punto? transform shape
y restablecer la rotación parece una solución.
EDITAR: Espero que esta vez haya entendido tu punto. Si no, realmente agradecería que me lo explicaran en términos de rectángulos y formas rotados, en lugar delocalyglobalque son terminología relativa con respecto al entorno de imagen Tikz rotada.
\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}
Respuesta2
Nota:Finalmente encontré una solución por mí mismo... pero no puedo darme mi propia recompensa. ;-)
Defino tres estilos:
memoize points
nombra cada punto de una ruta (con la ayuda dememoizepoints
un contador) y acumula estos nombres en una macro global (su argumento).cont memoize points
es igual quememoize points
, pero sin resetear la macro global (su argumento).init memoize points
restablece la macro global (su argumento) y elmemoizepoints
contador.
Aquí está el preámbulo:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit,intersections,decorations.pathreplacing,decorations.markings}
El memoizepoints
mostrador y los tres estilos:
\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},
}
Luego un ejemplo seguido de su código:
\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}