Мне нужны такие диаграммы:
Я автоматизировал «черную» часть, но не могу понять, как сделать то же самое с красной границей; моя текущая версия такова:
\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}
и мне это совсем не нравится. Спрашивать об улучшениях в этой уродливой автоматизированной части, наверное, было бы слишком, но граница — это особенно ужасно.
Кто-нибудь знает, как поставить эту красную границу, указав подмножество узлов, которые должны быть охвачены?
решение1
Я попытался несколько упростить ваш код. (Обратите внимание, что я также поменял местами узлы 1 и 2, чтобы получить желаемый результат.) Помимо прочего, этот код больше не перезаписывает узлы.
\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}
Этот код поставляется с marco \DrawHalo
, который ожидает список из 1, 2 или 3 узлов (без закрывающих скобок). Если у вас три узла, расположите их в порядке {самый левый узел, самый верхний узел, самый правый узел}, если у вас два узла, расположенных горизонтально, порядок будет {самый левый узел, самый правый узел}, а если два узла расположены вертикально, расположите три {нижний узел, верхний узел, нижний узел}.
ОБНОВЛЯТЬ: Добавлен случай с одним узлом.
ВТОРОЕ ОБНОВЛЕНИЕ: Вы правы \ifnum
. Кроме того, я ранее рисовал узел (4-\k)
дважды. Я воспользовался возможностью, чтобы сделать еще два изменения: я добавил счетчик узлов, так что вы можете рисовать несколько диаграмм в одной, tikzpicture
не давая двум узлам одно и то же имя. Обратите внимание, однако, что это \DrawHalo
всегда относится к последней диаграмме, нарисованной перед ней. Помимо этого я заменил em
единицы измерения безразмерными выражениями, чтобы сделать это более масштабируемым. Что касается опций, я добавил пример, в котором я использую их, чтобы немного проиллюстрировать, что вы можете с ними сделать.
решение2
Вы могли бы использовать fit
библиотеку. Если вам нужна более сложная форма контура, используйте, backgrounds
возможно:
\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}
Это дает:
решение3
Вы можете использовать библиотеку подгонки tikz, описанную в pgfmanual в главе 52 на странице 622. К сожалению, ограничивающая рамка может быть только одной из предопределенных форм.
Этот пример взят из руководства:
\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}
решение4
Вы можете нарисовать достаточно толстую линию на фоне, чтобы "выделить" ваши узлы. Если вы действительно заинтересованы в ощущении контура из вашего примера, вы можете использовать линии double
, как в примере ниже:
\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}