Cómo dibujar un borde alrededor de un subconjunto de nodos

Cómo dibujar un borde alrededor de un subconjunto de nodos

Necesito diagramas como este:

ingrese la descripción de la imagen aquí

Automaticé la parte "negra" pero no pude descubrir cómo hacerlo con el borde rojo; mi versión actual es esta:

\documentclass[border=1mm,tikz,preview]{standalone}

\newcount\prevnode

\def\EDynkin#1{
\prevnode=0
\node (1) at (2,0) [circle,draw,radius=1em] {};
\node (2) at (0,1) [circle,draw,radius=1em] {};
\node (3) at (1,0) [circle,draw,radius=1em] {};
\node (4) at (0,0) [circle,draw,radius=1em] {};
\node (5) at (-1,0) [circle,draw,radius=1em] {};
\node (6) at (-2,0) [circle,draw,radius=1em] {};
\draw (1) -- (3) -- (4) -- (5) -- (6);
\draw (2) -- (4);
\foreach\kthweight[count=\k] in {#1}{
\ifnum\k=1\node at (2,0) {\scriptsize\kthweight};\fi
\ifnum\k=2\node at (0,1) {\scriptsize\kthweight};\fi
\ifnum\k>6
\node (\k) at (4-\k,0) [circle,draw,radius=1em] {};
\draw (\k) -- (\the\prevnode);
\fi
\ifnum\k>2\node at (4-\k,0) {\scriptsize\kthweight};\fi
\global\advance\prevnode by1
}
}

\begin{document}

\begin{tikzpicture}[scale=.5]
\EDynkin{2,0,1,0,2,1,0,1}
\draw [red,rounded corners] (-.5,1.5) -- (.5,1.5) -- (.5,.5) -- (1.5,.5) --
(1.5,-.5) -- (-2.5,-.5) -- (-2.5,.5) -- (-.5,.5) -- cycle;
\end{tikzpicture}

\end{document}

y no me gusta nada. Preguntar sobre mejoras en esa fea parte automatizada probablemente sería demasiado, pero lo del borde es especialmente horrible.

¿Alguien sabe cómo poner este borde rojo indicando el subconjunto de nodos que deben abarcarse?

Respuesta1

Intenté simplificar un poco tu código. (Tenga en cuenta que también cambié los nodos 1 y 2 para producir el resultado deseado). Entre otras cosas, este código ya no sobrescribe los nodos.

\documentclass[border=1mm,tikz,preview]{standalone}
\usetikzlibrary{calc}
\newcounter{DynkinDiagram}
\tikzset{DynkinNode/.style={circle,draw,minimum size=1em,inner sep=0pt,font=\scriptsize}}
\newcommand{\EDynkin}[2][]{\stepcounter{DynkinDiagram}
\foreach\kthweight[count=\k] in {#2}{
\pgfmathtruncatemacro{\prevnode}{\k-1}
\ifnum\k=1\node[DynkinNode] (\theDynkinDiagram-\k) at (0,1) {\kthweight};\fi % exchanged 1 and 2
\ifnum\k>1
\node[DynkinNode] (\theDynkinDiagram-\k) at (4-\k,0) {\scriptsize\kthweight};
\ifnum\k>2\draw[-,#1] (\theDynkinDiagram-\k) -- (\theDynkinDiagram-\prevnode);\fi
\ifnum\k=4\draw[-,#1] (\theDynkinDiagram-\k) -- (\theDynkinDiagram-1);\fi
\fi
}
}
\newcommand{\DrawHalo}[2][]{%
\foreach \Node[count=\i] in {#2}
{
\xdef\imax{\i}
\coordinate (AuxNode-\i) at ($(\theDynkinDiagram-\Node)$);
}
\ifnum\imax=3%
\draw[#1] ($(AuxNode-1)+(-0.50,0)$) -- ($(AuxNode-1)+(-0.50,0.50)$) -|  ($(AuxNode-2)+(-0.50,0.50)$)
    -- ($(AuxNode-2)+(0.50,0.50)$) |-
    ($(AuxNode-3)+(0.50,0.50)$)
    --($(AuxNode-3)+(0.50,-0.50)$) -- ($(AuxNode-1)+(-0.50,-0.50)$) -- cycle;
\else
\ifnum\imax=2%
\draw[#1] ($(AuxNode-1)+(-0.50,0.50)$) --  ($(AuxNode-2)+(0.50,0.50)$)
    -- ($(AuxNode-2)+(0.50,-0.50)$) -- ($(AuxNode-1)+(-0.50,-0.50)$)--
    cycle;
\else
\draw[#1] ($(AuxNode-1)+(-0.50,0.50)$) --  ($(AuxNode-1)+(0.50,0.50)$)
    -- ($(AuxNode-1)+(0.50,-0.50)$) -- ($(AuxNode-1)+(-0.50,-0.50)$)--
    cycle;
\fi 
\fi 
}
\begin{document}

\begin{tikzpicture}[scale=.5]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[red,rounded corners]{6,1,3}
\begin{scope}[xshift=8cm]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[fill=red,opacity=0.3,rounded corners]{6,1,3}
\end{scope}
\end{tikzpicture}
%
\begin{tikzpicture}[scale=.5]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[red,rounded corners]{6,2}
\end{tikzpicture}
%
\begin{tikzpicture}[scale=.5]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[red,rounded corners]{4,1,4}
\end{tikzpicture}
%
\begin{tikzpicture}[scale=.5]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[red,rounded corners]{6,1,4}
\end{tikzpicture}
%
\begin{tikzpicture}[scale=.5]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[red,rounded corners]{4,1,3}
\end{tikzpicture}
%
\begin{tikzpicture}[scale=.5]
\EDynkin{0,2,1,0,2,1,0,1}
\DrawHalo[red,rounded corners]{6}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Este código viene con un marco \DrawHaloque espera una lista de 1, 2 o 3 nodos (sin los corchetes adjuntos). Si tiene tres nodos, colóquelos en el orden {nodo más a la izquierda, nodo más arriba, nodo más a la derecha}, si tiene dos nodos dispuestos horizontalmente el orden es {nodo más a la izquierda, nodo más a la derecha} y si Los dos nodos están dispuestos verticalmente, coloque tres {nodo inferior, nodo superior, nodo inferior}.

ACTUALIZAR: Se agregó el caso de un solo nodo.

SEGUNDA ACTUALIZACIÓN: Tienes razón en la \ifnumcosa. Además, previamente dibujé el nodo (4-\k)dos veces. Aproveché la oportunidad para hacer dos cambios más: agregué un contador de nodos, de modo que puedes dibujar varios diagramas en uno tikzpicturesin darle el mismo nombre a dos nodos. Tenga en cuenta, sin embargo, que esto \DrawHalosiempre se refiere al último diagrama dibujado antes. Aparte de eso, reemplacé las emunidades por expresiones adimensionales para hacerlo mejor escalable. En cuanto a las opciones, agregué un ejemplo en el que las uso para ilustrar un poco lo que puedes hacer con ellas.

Respuesta2

Podrías usar la fitbiblioteca. Si desea una forma de contorno más sofisticada, utilice backgroundstal vez:

\documentclass[border=1mm,tikz,preview]{standalone}
\usetikzlibrary{fit,backgrounds}

\newcount\prevnode

\def\EDynkin#1{
\prevnode=0
\node (1) at (2,0) [circle,draw,radius=1em] {};
\node (2) at (0,1) [circle,draw,radius=1em] {};
\node (3) at (1,0) [circle,draw,radius=1em] {};
\node (4) at (0,0) [circle,draw,radius=1em] {};
\node (5) at (-1,0) [circle,draw,radius=1em] {};
\node (6) at (-2,0) [circle,draw,radius=1em] {};
\draw (1) -- (3) -- (4) -- (5) -- (6);
\draw (2) -- (4);
\foreach\kthweight[count=\k] in {#1}{
\ifnum\k=1\node at (2,0) {\scriptsize\kthweight};\fi
\ifnum\k=2\node at (0,1) {\scriptsize\kthweight};\fi
\ifnum\k>6
\node (\k) at (4-\k,0) [circle,draw,radius=1em] {};
\draw (\k) -- (\the\prevnode);
\fi
\ifnum\k>2\node at (4-\k,0) {\scriptsize\kthweight};\fi
\global\advance\prevnode by1
}
}

\begin{document}

\begin{tikzpicture}[scale=.5]
\EDynkin{2,0,1,0,2,1,0,1}
\node (box) [draw=red,rounded corners,fit = (3) (6) (2)] {};
\end{tikzpicture}

\begin{tikzpicture}[scale=.5]
\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}

\EDynkin{2,0,1,0,2,1,0,1}
\begin{pgfonlayer}{bg}
 \node (box) [draw=red,line width=.8pt,rounded corners,fit = (3) (6)] {};
 \node (box) [draw=red,line width=.8pt,rounded corners,fit = (4) (2)] {};
 \node (box) [fill=white,rounded corners,fit = (3) (6)] {};
 \node (box) [fill=white,rounded corners,fit = (4) (2)] {};
\end{pgfonlayer}
\end{tikzpicture}

\end{document}

Esto produce:

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Respuesta3

Puede utilizar la biblioteca de adaptación tikz documentada en el pgfmanual en el capítulo 52 en la página 622. Desafortunadamente, el cuadro delimitador solo puede ser una de las formas predefinidas.

Este ejemplo es del manual:

\begin{tikzpicture}[
    inner sep=0pt,
    thick,
    dot/.style={
        fill=blue,
        circle,
        minimum size=3pt
    }
]
    \draw[help lines] (0,0) grid (3,2);
    \node[dot] (a) at (1,1) {};
    \node[dot] (b) at (2,2) {};
    \node[dot] (c) at (1,2) {};
    \node[dot] (d) at (1.25,0.25) {};
    \node[dot] (e) at (1.75,1.5) {};
    \node[draw=red,fit=(a) (b) (c) (d) (e)] {  box};
    \node[draw,circle,fit=(a) (b) (c) (d) (e)] {};
\end{tikzpicture}

Respuesta4

Puedes dibujar una línea lo suficientemente gruesa en el fondo para "resaltar" tus nodos. Si está realmente interesado en la sensación del contorno de su ejemplo, puede usar las doublelíneas, como en el siguiente ejemplo:

\documentclass[tikz]{standalone}

\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}

\begin{document}
\begin{tikzpicture}

  \tikzset{
    contour/.style={
      red, 
      double,
      double distance=7mm,
      cap=round,
    }
  }

  \node[draw](a)at(0, 0){A};
  \node[draw](b)at(1, 0){B};
  \node[draw](c)at(2, 0){C};
  \node[draw](d)at(2, 1){D};
  \node[draw](e)at(3, 0){E};

  \begin{pgfonlayer}{bg}
    \draw[contour](b.center)--(c.center)--(d.center)
    (c.center)--(e.center);
  \end{pgfonlayer}

\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada