Solución:
JLDiaz le explicó cómo arreglar su código, pero el resultado podría mejorarse. La solución que sugiero quizás no sea perfecta porque es algo que requiere un poco de cuidado, pero proporciona un mejor resultado en mi humilde opinión.
Se basa en el paquete. textpos
para colocar los bloques, en Cambiar el ancho predeterminado de los bloques en el proyector para personalizar el ancho del bloque y en el tikzmark
macro para identificar bloques.
En realidad, lo interesante de tu solución es el mecanismo en el que identificaste bloques poniéndolos dentro de un nodo TikZ para luego conectarlos usando los anclajes del nodo. Esta solución, sin embargo, utiliza textpos
así: ¿cómo identificar todo el bloque? Esa es la razón por la cual tikzmark
es necesario. Tenga en cuenta que el uso de textpos
ayuda a no tener tales problemas de desalineación vertical.
los tikzmark
está construido de tal manera que el nodo podría extenderse en su ancho y en su altura (esa es la parte que requiere un poco de cuidado): observe que la altura del bloque depende en última instancia de su contenido, por lo que mi sugerencia es 1) primero escribe el contenido 2) arregla su altura después.
El punto de la mark
identificado está exactamente en el centro del título del bloque y el nodo identifica un área más grande que el bloque:
Como puede ver en la imagen, la mitad del nodo construido a través de tikzmark
está vacío: esto se hace para asegurar que la conexión de bloques paralelos la flecha se pueda realizar por medio de algo como
path[line width=0.2cm](n2.east)edge[bend left](n1.west);
Como consecuencia, la parte superior permanece vacía y debe tener en cuenta este comportamiento en caso de que dibuje conexiones comenzando / terminando en la parte superior del bloque. Este problema se ha solucionado de una manera particular con un ancla especial.
El código que muestra todas las cosas:
documentclass[aspectratio=169]{beamer}
usepackage{lmodern}
usepackage{tikz}
usepackage[overlay]{textpos}
usetheme{Frankfurt}
newcommand{tikzmark}[2][minimum width=6cm,minimum height=1.5cm]{
tikz[remember picture,overlay]
node[anchor=west,
inner sep=0pt,
outer sep=6pt,
xshift=-0.5em,
yshift=-3ex,
#1](#2){};
}
newcommand{shownode}[1]{
tikz[remember picture,overlay]draw[red](#1.south east)rectangle(#1.north west);
}
newcommand{showanchor}[1]{
tikz[remember picture,overlay]draw[red,thick,mark=x] plot coordinates{(#1)};
}
% original code from Stefan Kottwitz
% https://tex.stackexchange.com/a/12551/13304
newenvironment<>{varblock}[2][.9textwidth]{%
setlength{textwidth}{#1}
begin{actionenv}#3%
definsertblocktitle{#2}%
par%
usebeamertemplate{block begin}%
}
{par%
usebeamertemplate{block end}%
end{actionenv}}
newenvironment{myblock}[1]{begin{textblock*}{500pt}(#1)}{end{textblock*}}
% special way to reach the top of the block
defnewabove(#1){
([yshift=1.5ex]#1.center)
}
begin{document}
begin{frame}
begin{myblock}{0.55textwidth, -0.2textheight}
tikzmark{n1}
shownode{n1}
%remove the previous line: just used to see where the invisible node is placed
begin{varblock}[6cm]{title1}
text1
end{varblock}
showanchor{n1}
%remove also this: just used to see where n1 is positioned
end{myblock}
begin{myblock}{0em, -0.2textheight}
tikzmark{n2}
shownode{n2}
begin{varblock}[6cm]{title2}
text2
end{varblock}
showanchor{n2}
end{myblock}
begin{myblock}{0.3textwidth, 0.2textheight}
tikzmark[minimum width=5cm,minimum height=2.25cm]{n3} % customization of width and height
shownode{n3}
begin{varblock}[5cm]{title3}
text3\
text
end{varblock}
showanchor{n3}
end{myblock}
begin{tikzpicture}[remember picture,overlay,-stealth]
path[line width=0.2cm](n2.east)edge[bend left](n1.west);
path[line width=0.2cm](n1.south)edge[bend left](n3.east);
path[line width=0.2cm](n3.west)edge[bend left](n2.south);
% in case you need to connect some block from ``north''
%path[line width=0.2cm](n3.north)edge[bend left](n1.south west); % is wrong
path[line width=0.2cm]newabove(n3) edge[bend left](n1.south west);
end{tikzpicture}
end{frame}
end{document}
Eliminando todas las cosas para hacer visibles los nodos y anclas y la ruta especial que muestra cómo llegar a la parte superior del bloque, terminas con:
que supongo que es lo que querías.
Cómo lidiar con el problema de la altura de los bloques.
Dado que esto podría ser una desventaja del procedimiento, veamos un ejemplo.
Al principio, uno debe preocuparse por el contenido de los bloques sin considerar la altura u otras cosas. Por ejemplo:
documentclass[aspectratio=169]{beamer}
usepackage{lmodern}
usepackage{tikz}
usetheme{Frankfurt}
usepackage[overlay]{textpos}
newcommand{tikzmark}[2][minimum width=6cm,minimum height=1.5cm]{
tikz[remember picture,overlay]
node[anchor=west,
inner sep=0pt,
outer sep=6pt,
xshift=-0.5em,
yshift=-3ex,
#1](#2){};
}
newcommand{shownode}[1]{
tikz[remember picture,overlay]draw[red](#1.south east)rectangle(#1.north west);
}
newcommand{showanchor}[1]{
tikz[remember picture,overlay]draw[red,thick,mark=x] plot coordinates{(#1)};
}
% original code from Stefan Kottwitz
% https://tex.stackexchange.com/a/12551/13304
newenvironment<>{varblock}[2][.9textwidth]{%
setlength{textwidth}{#1}
begin{actionenv}#3%
definsertblocktitle{#2}%
par%
usebeamertemplate{block begin}%
}
{par%
usebeamertemplate{block end}%
end{actionenv}}
newenvironment{myblock}[1]{begin{textblock*}{500pt}(#1)}{end{textblock*}}
% special way to reach the top of the block
defnewabove(#1){
([yshift=1.5ex]#1.center)
}
begin{document}
begin{frame}
begin{myblock}{0cm,-2.5cm}
tikzmark{n1}
begin{varblock}[6cm]{title1}
Hello! :) This is the text of my block. Here I want to say
that the height of the blocks is not so problematic.
end{varblock}
end{myblock}
begin{myblock}{8cm,-2.5cm}
tikzmark{n2}
begin{varblock}[6cm]{title2}
This is my very long block with even an equation:
[Delta_n=
begin{cases}
1 quad q_n>0\
0 quad q_n=0
end{cases}
]
end{varblock}
end{myblock}
% I can leave all blank lines I want
begin{myblock}{8cm,2cm}
tikzmark{n3}
begin{varblock}[6cm]{title3}
Short text
end{varblock}
end{myblock}
begin{myblock}{0cm,2cm}
tikzmark{n4}
begin{varblock}[6cm]{title4}
Short text
end{varblock}
end{myblock}
begin{tikzpicture}[remember picture,overlay,-stealth,line width=0.2cm]
draw (n1.east)--(n2.west);
draw (n2.south)--newabove(n3);
draw (n3.west)--(n4.east);
draw newabove(n4)--(n1.south);
end{tikzpicture}
end{frame}
end{document}
Observe que dejé intencionalmente algunas líneas en blanco. Después de dos ejecuciones de compilación obtenemos:
Oh … hay un problema con los bloques 1 y 2. ¿Por qué? Porque la altura es incorrecta; usando nuestro shownode
y showanchor
es posible entender la razón:
Observe ahora que el valor predeterminado es 1.5cm
por la altura. Por lo tanto, algo como 0.75cm
para un bloque con el título y una línea en el cuerpo.
En el bloque 1 tenemos 4 líneas + el título, por lo que, a grandes rasgos, tenemos tres veces la altura estándar: 0.75cm x 3=2.25cm
. Sin embargo, este es solo el bloque, por lo que para tener el nodo completo debemos multiplicar por dos nuevamente. Totalmente: 4.5cm
.
Mire ahora el segundo bloque: está un poco más alto que el bloque 1. Supongo que es 1cm
más alto, así que pongamos 5.5cm
.
Entonces tenemos que actualizar:
begin{myblock}{0cm,-2.5cm}
tikzmark[minimum width=6cm, minimum height=4.5cm]{n1}
shownode{n1}
begin{varblock}[6cm]{title1}
Hello! :) This is the text of my block. Here I want to say
that the height of the blocks is not so problematic.
end{varblock}
showanchor{n1}
end{myblock}
begin{myblock}{8cm,-2.5cm}
tikzmark[minimum width=6cm, minimum height=5.5cm]{n2}
shownode{n2}
begin{varblock}[6cm]{title2}
This is my very long block with even an equation:
[Delta_n=
begin{cases}
1 quad q_n>0\
0 quad q_n=0
end{cases}
]
end{varblock}
showanchor{n2}
end{myblock}
Esto proporciona:
Más o menos hemos terminado. Pero todavía estoy insatisfecho con el bloque 2: no es muy preciso. Supongo que necesitamos 0.25cm
más. Entonces:
begin{myblock}{8cm,-2.5cm}
tikzmark[minimum width=6cm, minimum height=5.75cm]{n2}
shownode{n2}
begin{varblock}[6cm]{title2}
This is my very long block with even an equation:
[Delta_n=
begin{cases}
1 quad q_n>0\
0 quad q_n=0
end{cases}
]
end{varblock}
showanchor{n2}
end{myblock}
Esto da:
Oh .. mal. ¡Demasiado! Ok, acortémoslo un poco a 5.7cm
. Seguro que esto será correcto. En conclusión:
Arreglé tu código en algunos puntos:
- Lo más importante, tienes que dar también la
remember picture
opción a sus superposiciones. Sin él, el nombre de cada nodo no se refiere a las coordenadas adecuadas, ya que son nodos en una imagen tikz diferente. -
baseline
La opción no es realmente necesaria en este caso. -
inner sep
puesto a cero para los nodos del bloque -
%
agregado al final de algunas líneas para evitar el espacio vertical (lo que todavía sucede, no sé por qué, y se puede hacer visible descomentando la primera línea de laevery overlay node
estilo.
El código resultante es:
documentclass[aspectratio=169]{beamer}
usepackage{tikz}
usetheme{Frankfurt}
tikzset{
every overlay node/.style={
%draw=black,fill=white,rounded corners,
anchor=north west, inner sep=0pt,
},
}
% Usage:
% tikzoverlay at (-1cm,-5cm) {content};
% or
% tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
deftikzoverlay{%
tikz[remember picture, overlay]node[every overlay node]
}%
begin{document}
begin{frame}
tikzoverlay (n1) at (8cm,2cm) {%
begin{minipage}{0.4textwidth}%
begin{block}{title1}%
{Text1}
end{block}
end{minipage}
};
tikzoverlay (n2) at (0cm,2cm) {%
begin{minipage}{0.4textwidth}%
begin{block}{title2}%
Text2
end{block}
end{minipage}
};
tikzoverlay (n3) at (5cm,0cm) {%
begin{minipage}{0.4textwidth}%
begin{block}{Title3}%
Text3
end{block}
end{minipage}
};
begin{tikzpicture}[remember picture, overlay]
path [line width=0.3cm,->] (n1.south) edge (n3.south);
path [line width=0.3cm,->] (n3.north) edge (n2.south);
path [line width=0.3cm,->] (n2.east) edge (n1.west);
end{tikzpicture}
end{frame}
end{document}
Que produce (después compilando dos veces):
Lo cual es feo, en mi humilde opinión, pero supongo que es lo que estabas pidiendo.
Editar:
Cuando escribí el código anterior, no presté atención a los valores de las coordenadas donde se dibujó cada nodo. Supuse que el resultado con el nodo2 en un nivel diferente al del nodo1 fue intencional. Pero el comentario de OP me hizo darme cuenta de que, de hecho, ambos nodos usan la misma coordenada y, entonces, ¿por qué no están alineados?
La razón es que no están dibujados en el mismo tikzpicture
, por lo que no comparten el espacio de coordenadas. Cada tikzpicture
(o tikz
comando) inicia su propio sistema de coordenadas. Entonces, la nueva pregunta es “¿por qué entonces casi ¿trabajó?”.
La razón de esto es que cada figura tiene la opción overlay
, lo que significa que independientemente de lo que realmente dibuje la imagen, el espacio reservado por tex para esa imagen es cero. Es un punto adimensional. Ese punto es entonces el origen de la figura.
Entonces, si tuviéramos tres figuras sin espacio entremedias, ya que cada una es vista por tex como un punto adimensional, las tres se dibujarán “en el mismo punto” y, por lo tanto, sus sistemas de coordenadas coincidirán. Pero si las figuras están separadas por palabras, entonces cada una tendrá su propio origen.
Sucede que en tu caso las cifras están separados por espacios en blanco e incluso por ` par, porque hay líneas vacías en el código fuente y finales de línea entre las cifras.
Entonces, la solución es eliminar todo este espacio no deseado, eliminando las líneas en blanco entre las figuras y comentando los retornos de carro al final de cada figura (que de otro modo producirían un espacio):
documentclass[aspectratio=169]{beamer}
usepackage{tikz}
usetheme{Frankfurt}
tikzset{
every overlay node/.style={
%draw=black,fill=white,rounded corners,
anchor=north west, inner sep=0pt,
},
}
% Usage:
% tikzoverlay at (-1cm,-5cm) {content};
% or
% tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
deftikzoverlay{%
tikz[remember picture, overlay]node[every overlay node]
}%
begin{document}
begin{frame}
tikzoverlay (n1) at (8cm,2cm) {%
begin{minipage}{0.4textwidth}%
begin{block}{title1}%
{Text1}
end{block}
end{minipage}
};%
tikzoverlay (n2) at (0cm,2cm) {%
begin{minipage}{0.4textwidth}%
begin{block}{title2}%
Text2
end{block}
end{minipage}
};%
tikzoverlay (n3) at (5cm,0cm) {%
begin{minipage}{0.4textwidth}%
begin{block}{Title3}%
Text3
end{block}
end{minipage}
};%
%
begin{tikzpicture}[remember picture, overlay]
path [line width=0.3cm,->] (n1.south) edge (n3.south);
path [line width=0.3cm,->] (n3.north) edge (n2.south);
path [line width=0.3cm,->] (n2.east) edge (n1.west);
end{tikzpicture}
end{frame}
end{document}
Resultado: