8

I'm trying to plot a grid network in TikZ. But I'm not able to get the required plot, even after many attempts. Here is my MWE:

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usepackage{scalerel}
\usepackage{ifthen}
\usetikzlibrary{decorations.markings}

\tikzset{
    mynode/.style = {circle, draw, thick, fill = white, inner sep=0pt},
    type1/.style = {mynode},
    type2/.style = {mynode}
}
\begin{document}
    \begin{tikzpicture}[>=stealth]
    \draw[step=3cm,color=white] grid (2,2);
    \begin{scope}[rotate=45]
    \foreach \x in {-3,...,1}
    \foreach \y in {-3,...,1} {
        \pgfmathsetmacro{\type}{int(mod(abs(\x+\y),2)+1)};
        \pgfmathsetmacro{\pos}{int(mod(abs(\y),2)+1)};
        \pgfmathsetmacro{\post}{int(mod(abs(\x),2)+1)};
        \draw[blue, -] (\x-0.6, \y) -- (\x+0.6, \y);
        \ifthenelse{\type=2 and \pos=2 and \post=1}{\node[black,below] at (\x-0.3, \y+0.3) {{\tiny$b$}};}{\node[black,below] at (\x-0.3, \y+0.3)  {{\tiny $r$}};}
        % 
        \draw[red,  -] (\x, \y-0.6) -- (\x, \y+0.6);
        \ifthenelse{\type=1 \and \pos=1}{\node[type\type] at (\x,\y) {\color{orange}$K_{\type a}$};}{}
        \ifthenelse{\type=1 \and \pos=2}{\node[type\type] at (\x,\y) {\color{orange}$K_{\type b}$};}{}
        \ifthenelse{\type=2 \and \pos=1}{\node[type\type] at (\x,\y) {\color{black}$K_{\type a}$};}{}
        \ifthenelse{\type=2 \and \pos=2}{\node[type\type] at (\x,\y) {\color{black}$K_{\type b}$};}{}
    }
    \end{scope}
    \end{tikzpicture}

\end{document}

This is what I actual want: enter image description here

Logic behind the network:

  • You can think $ K_{1a} $ splits in to $K_{2b}$ along left with left branch $r$ and on the right with $K_{2a}$.
  • Similarly, $ K_{1b} $ splits in to $K_{2a}$ along left with left branch $b$ and on the right with $K_{2b}$.

Only left arrows carries the labels $r$ and $b$.

  • All circular boxes with label $a$ i.e. $ K_{1a} $ and $K_{2a}$ have left branch always $r$,
  • likewise, label $b$ i.e. $ K_{1b} $ and $K_{2b}$ have left branch always $b$.

Also, vertically all the circular boxes are same. Like a unit cell repeating.

  • 1
    If you use \begin{scope}[rotate=135] \foreach \x in {-3,...,1} \foreach \y in {-3,...,\x} you will be a bit closer to the desired result. – marmot Jan 28 at 17:14
  • Thanks @marmot I'm not suppose to change the orientation of the figure, unfortunately. If it can be done without the rotation part, it will resolve my problem, I guess. – Shamina Jan 28 at 17:18
  • Not supposed? Is this home work? – Thruston Jan 28 at 17:25
  • @Thruston No this is just a part of the actual stuff. Whole stuff will change drastically. Just to avoid that! – Shamina Jan 28 at 17:26
  • What is the logic in the notation of the nodes and branches of your graph? I can't see one. The first 4 are numbered alternately 1 and 2, but not the fifth. And how about a and b? – AndréC Jan 28 at 20:41
12
+50

Of course one can keep your document and truncate the diagram with a simple \ifnum statement.

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usepackage{scalerel}
\usepackage{ifthen}
\usetikzlibrary{decorations.markings}

\tikzset{
    mynode/.style = {circle, draw, thick, fill = white, inner sep=0pt},
    type1/.style = {mynode},
    type2/.style = {mynode}
}
\begin{document}
    \begin{tikzpicture}[>=stealth]
    \draw[step=3cm,color=white] grid (2,2);
    \begin{scope}[rotate=45]
    \foreach \x in {-3,...,1}
    {\foreach \y [evaluate=\y as \z using {int(-\x-\y)}] in {-3,...,1} {
        \pgfmathsetmacro{\type}{int(mod(abs(\x+\y),2)+1)};
        \pgfmathsetmacro{\pos}{int(mod(abs(\y),2)+1)};
        \pgfmathsetmacro{\post}{int(mod(abs(\x),2)+1)};
        \ifnum\z<3
        \draw[blue, -] (\x-0.6, \y) -- (\x+0.6, \y);
        \ifthenelse{\type=2 and \pos=2 and \post=1}{\node[black,below] at (\x-0.3, \y+0.3) {{\tiny$b$}};}{\node[black,below] at (\x-0.3, \y+0.3)  {{\tiny $r$}};}
        % 
        \draw[red,  -] (\x, \y-0.6) -- (\x, \y+0.6);
        \ifthenelse{\type=1 \and \pos=1}{\node[type\type] at (\x,\y) {\color{orange}$K_{\type a}$};}{}
        \ifthenelse{\type=1 \and \pos=2}{\node[type\type] at (\x,\y) {\color{orange}$K_{\type b}$};}{}
        \ifthenelse{\type=2 \and \pos=1}{\node[type\type] at (\x,\y) {\color{black}$K_{\type a}$};}{}
        \ifthenelse{\type=2 \and \pos=2}{\node[type\type] at (\x,\y) {\color{black}$K_{\type b}$};}{}
        \fi
    }}
    \end{scope}
 \end{tikzpicture}

\end{document}

enter image description here

As for your updated question: isn't that just some modulo arithmetic? (I acknowledge a lot of help by KJO!)

\documentclass[tikz,border=1mm]{standalone}
\tikzset{
    mynode/.style = {circle, draw, thick, fill = white, inner sep=0pt},
    type1/.style = {mynode,text=orange},
    type2/.style = {mynode}
}
\begin{document}
    \begin{tikzpicture}[>=stealth]
    \def\mylst{{"1b","2b","1a","2a"}}
    \def\mylstsmall{{"r","b"}}
    \draw[step=3cm,color=white] grid (2,2);
    \begin{scope}[rotate=45]
    \foreach \x in {-3,...,1}
    {\foreach \y [evaluate=\y as \z using {int(-\x-\y)}] in {-3,...,1} {
        \pgfmathsetmacro{\mylabel}{\mylst[mod(\x-\y+8,4)]}
        \pgfmathsetmacro{\myrb}{\mylstsmall[mod(int(\x/2-\y/2+5),2)]}
        \pgfmathsetmacro{\type}{int(mod(abs(\x+\y),2)+1)};
        \pgfmathsetmacro{\pos}{int(mod(abs(\y),2)+1)};
        \pgfmathsetmacro{\post}{int(mod(abs(\x),2)+1)};
        \ifnum\z<3
        \draw[blue, -] (\x-0.6, \y) -- (\x+0.6, \y);
        \draw[red,  -] (\x, \y-0.6) -- (\x, \y+0.6);
        \node[type\type] at (\x, \y){$K_{\mylabel}$};
        \node[black,below,font=\tiny] at (\x-0.3, \y+0.3)  {$\myrb$};
        % 
        \fi
    }}
    \end{scope}
 \end{tikzpicture}
\end{document}

enter image description here

How does that work? By the algorithm you get cycles of length 4 along the diagonals. So if you read it from the top going down right you will get the sequence {"1b","2b","1a","2a"}, which gets stored in the macro \mylst. These operations on arrays are described in detail on p. 999 of thee pgfmanual. This corresponds to the negative y direction, therefore we assign the labels \pgfmathsetmacro{\mylabel}{\mylst[mod(\x-\y+8,4)]}. Here two amazing features of the TikZ parser were exploited:

  • You can access elements of a list with \mylst[<index>] (where the index starts at 0, i.e. \mylst[0] gives you the first element.
  • The index can be an integer, or, some expression that evaluates to an integer, which if why \pgfmathsetmacro{\mylabel}{\mylst[mod(\x-\y+8,4)]} works.

Here, the \x part is due to the fact that the list keeps repeating in the positive \x direction with the same pattern, and mod makes sure that the list really repeats. The offset +8 makes sure that top node is what it is, if you change this, the top node label will change, and the pattern will get shifted. You could have chosen 12, 4, 0, or any number that equals 8 modulo 4. For the edge labels, a similar logic is applied. To condense things to a list of length 2, the coordinates get divided by 2, which is why the pattern, if read along a diagonal is something like r,r,b,b. If you do not like these divisions by 2, you could make the list longer, \def\mylstsmall{{"r","r","b","b"}}.

  • 2
    Thanks for the answer! But it's similar to mine. I think the problem is not yet resolved :( – Shamina Jan 28 at 20:11
  • 2
    @Shamina Well, I took your comment "'I'm not suppose to change the orientation of the figure, unfortunately. " as the requirement to do minimal surgery only. Could you perhaps edit your question to make clear what you want and what the constraints are? – marmot Jan 28 at 20:15
  • Sorry for the late! I edited my question. – Shamina Jan 29 at 11:49
  • @Shamina Sorry, didn't see the edit. (Sometimes I do not see the messages in my inbox...) I added something. And I believe you do not need ifthenelse here. – marmot Jan 30 at 20:39
  • @marmot thanks again. No problem. But I guess this is quite different from my picture. I mean the order or sequence is not correct as pointed out by KJO already. – Shamina Jan 30 at 21:05
4

I took over the problem completely and solved it in another way.

I wrote an algorithm that replicates the logic of your network. For this, there are two variables \etat (state in english) that is a or b and \parite (parity in english) that is 2 or 1.

\n represents the depth of the graph. Below n=5. Of course, you can choose whether the root node is 1a; 1b; 2a or 2b by initializing the state (\etat) and parity (\parite) variables. Here \etat = b and \parite = 1

reseau 5

\documentclass[border=1mm,tikz]{standalone}
%\usepackage{tikz}
\usepackage{scalerel}
\usepackage{ifthen}
\usetikzlibrary{decorations.markings}

\tikzset{
    mynode/.style = {circle, draw, thick, fill = white, inner sep=0pt},
    type1/.style = {mynode},
    type2/.style = {mynode}
}
%\def\n{3}% #1 depth
%\def\parite{1}% #2 = 1 ou 2
%\def\etat{a}% #3 = a ou b

\newcommand\reseau[3]{
    \begin{tikzpicture}[>=stealth]
    \draw[step=3cm,color=white] grid (2,2);
    \begin{scope}[rotate=-45,every label/.style={outer sep=1pt,inner sep=0pt,font=\scriptsize}]
          \gdef\paritex{#2};
          \gdef\etatx{#3};
           \gdef\paritey{#2};
          \gdef\etaty{#3};
     % début de graphique       
    \foreach \x  in {0,...,#1}{
        \foreach \y in {0,...,-#1+\x}{
            \ifthenelse {\equal{\paritey}{2}} %rang pair
                    {\ifthenelse {\equal{\etaty}{a}} %A
                                {
                                \gdef\paritey{1};
                                \gdef\etaty{a};
                                \pgfmathparse {int(subtract(\x,\y))}
                                \ifthenelse {\equal{\pgfmathresult}{#1}}
                                {\node[type2] at (\x,\y)(\x\y){\color{black}$K_{2 a}$};}
                                {\node[type2,label=200:r] at (\x,\y)(\x\y){\color{black}$K_{2 a}$};}
                                        }
                                {
                                \gdef\paritey{1};
                                \gdef\etaty{b};
                                \pgfmathparse {int(subtract(\x,\y))}
                                \ifthenelse {\equal{\pgfmathresult}{#1}}
                                {\node[type2] at (\x,\y)(\x\y){\color{black}$K_{2 b}$};}
                                {\node[type2,label=200:b] at (\x,\y)(\x\y){\color{black}$K_{2 b}$};}
                                }
                    }           
                  {% rang impair
                    \ifthenelse {\equal{\etaty}{a}} 
                                {
                                \gdef\paritey{2};
                                \gdef\etaty{b};
                                \pgfmathparse {int(subtract(\x,\y))}
                                \ifthenelse {\equal{\pgfmathresult}{#1}}
                                {\node[type1] at (\x,\y)(\x\y){\color{orange}$K_{1 a}$};}
                                {\node[type1,label=200:r] at (\x,\y)(\x\y){\color{orange}$K_{1 a}$};}
                                }
                            { 
                            \gdef\paritey{2};
                            \gdef\etaty{a};
                            \pgfmathparse {int(subtract(\x,\y))}
                            \ifthenelse {\equal{\pgfmathresult}{#1}}
                            {\node[type1] at (\x,\y)(\x\y){\color{orange}$K_{1 b}$};}
                            {\node[type1,label=200:b] at (\x,\y)(\x\y){\color{orange}$K_{1 b}$};}
                            }
                    }


            }

            \ifthenelse {\equal{\paritex}{2}} %rang pair
                    {\ifthenelse {\equal{\etatx}{a}} %A
                                {
                                \gdef\paritex{1};
                                \gdef\etatx{b};
                                        }
                                {
                                \gdef\paritex{1};
                                \gdef\etatx{a};
                                }
                    }           
                  {% rang impair
                    \ifthenelse {\equal{\etatx}{a}} 
                                {
                                \gdef\paritex{2};
                                \gdef\etatx{a};
                                }
                            { 
                            \gdef\paritex{2};
                            \gdef\etatx{b};
                            }
                    }   
          \gdef\paritey{\paritex};
          \gdef\etaty{\etatx};

        }

            % construction des traits bleu et rouges

        \foreach \x [evaluate=\x as \xx using int(\x+1)] in {0,...,#1-1}{
        \foreach \y [evaluate=\y as \yy using int(\y-1)]
        in {0,...,-#1+\x+1}{
            \draw[blue] (\x\yy) edge (\x\y);
            \draw[red] (\x\y)edge(\xx\y);
            }
            }

    \end{scope}
       \end{tikzpicture}
       }
\begin{document} 
%\def\n{3}% #1 depth
%\def\parite{1}% #2 = 1 ou 2
%\def\etat{a}% #3 = a ou b


 \reseau{5}{1}{b}

\end{document}

Other examples

first example:

%\def\n{3}% #1 depth
%\def\parite{1}% #2 = 1 ou 2
%\def\etat{a}% #3 = a ou b
\reseau{3}{2}{a} % 2a

reseau 1


second example:

%\def\n{3}% #1 depth
%\def\parite{1}% #2 0=even et 1 = odd
%\def\etat{1}% #3 0=A et 1=B
 \reseau{2}{1}{b}% 1b

reseau 2


third example:

\reseau{1}{2}{b}% 2b

reseau 3


fourth example:

\reseau{4}{2}{a}% 2a

reseau 4

  • there is a slight flaw somewhere in the logic as once you get down to fourth example the r&b rhythm is gone. – user170109 Jan 31 at 21:06
  • @KJO Thank you, it was a typographical error that I just corrected – AndréC Feb 1 at 4:38
  • I just renamed the parameters to make them more user-friendly – AndréC Feb 1 at 5:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.