8

I know how to draw automaton in tikz. But how to use complex nodes in that? I want draw something like this in tikz:

enter image description here

11

Probably you can do it with the matrix library:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzpicture}
[   mymatrix/.style={draw,thick,minimum width=1.0cm,minimum height=1.0cm,inner sep=0,anchor=south west}
]
    \matrix[matrix of nodes, nodes=mymatrix] (firstmatrix) at (0,0)
    {   q & w & e \\
        a & s & d \\ 
    };
    \matrix[matrix of nodes, nodes=mymatrix] (secondmatrix) at (10,0)
    {   i & o & p \\
        j & k & l \\ 
    };
    \draw[-latex] (firstmatrix.20) -- (secondmatrix.200);
\end{tikzpicture}

\end{document}

enter image description here


Edit 1: As Altermundus stated, the inner lines are double lines which is not desirable, so here's a solution using nodes and manually drawn lines (I'll try to automate this):

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzpicture}
[   mynode/.style={thick,minimum width=1.0cm,minimum height=1.0cm,inner sep=0,anchor=south west},
    mymatrix/.style={draw,inner sep=0}
]
    \matrix[matrix of nodes, nodes=mynode, mymatrix] (firstmatrix) at (0,0)
    {   \node (q) {q}; & w & \node (e) {e}; \\
        \node (a) {a}; & s & \node (d) {d}; \\ 
    };
    \draw (q.south west) -- (e.south east);
    \draw (q.north east) -- (a.south east);
    \draw (e.north west) -- (d.south west);

    \matrix[matrix of nodes, nodes=mynode, mymatrix] (secondmatrix) at (10,0)
    {   \node (i) {i}; & o & \node (p) {p}; \\
        \node (j) {j}; & k & \node (l) {l}; \\ 
    };
    \draw (i.south west) -- (p.south east);
    \draw (i.north east) -- (j.south east);
    \draw (p.north west) -- (l.south west);

    \draw[-latex] (firstmatrix.20) -- (secondmatrix.200);
\end{tikzpicture}

\end{document}

enter image description here

Edit 1.1: As Andrew Stacey remarked, it is of cause not neccessary to explicitely put nodes. You're in a matrix of nodes Neo, and not a slave. The individual cells all have names of the form matrixname-rownumber-columnnumber, and one can use this. The following produces exactly the same result as before:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzpicture}
[   mynode/.style={thick,minimum width=1.0cm,minimum height=1.0cm,inner sep=0,anchor=south west},
    mymatrix/.style={draw,inner sep=0},
    myline/.style={shorten <=0.2pt, shorten >=0.2pt},
]
    \matrix[matrix of nodes, nodes=mynode, mymatrix] (firstmatrix) at (0,0)
    {   q & w & e \\
        a & s & d \\ 
    };
    \draw[myline] (firstmatrix-1-1.south west) -- (firstmatrix-1-3.south east);
    \draw[myline] (firstmatrix-1-1.north east) -- (firstmatrix-2-1.south east);
    \draw[myline] (firstmatrix-1-3.north west) -- (firstmatrix-2-3.south west);

    \matrix[matrix of nodes, nodes=mynode, mymatrix] (secondmatrix) at (10,0)
    {   i & o & p \\
        j & k & l \\ 
    };
    \draw[myline] (secondmatrix-1-1.south west) -- (secondmatrix-1-3.south east);
    \draw[myline] (secondmatrix-1-1.north east) -- (secondmatrix-2-1.south east);
    \draw[myline] (secondmatrix-1-3.north west) -- (secondmatrix-2-3.south west);

    \draw[-latex] (firstmatrix.20) -- (secondmatrix.200);
\end{tikzpicture}

\end{document}

Edit 2: Another way to "avoid" the double outline is to draw both the nodes and the matrix, but the latter with the double line width:

\tikzset{
    mynode/.style={line width=0.25pt, draw, minimum width=1.0cm, minimum height=1.0cm, inner sep=0, anchor=south west},
    mymatrix/.style={line width=0.5pt, draw, inner sep=0},
    myline/.style={shorten <=0.2pt, shorten >=0.2pt},
}

\begin{tikzpicture}
    \matrix[matrix of nodes, nodes=mynode, mymatrix] (firstmatrix) at (0,0)
    {   q & w & e \\
        a & s & d \\ 
    };

\end{tikzpicture}

enter image description here

|improve this answer|||||
  • 1
    There is a little problem with the linewidth between the nodes. You get double lines. – Alain Matthes Aug 17 '12 at 6:50
  • Hmmm. Curious as to why you're using matrix of nodes and explicitly putting in the nodes. Also, your lines will be off if the nodes are of noticeably different sizes. See tex.stackexchange.com/a/21178/86 for a similar issue. – Andrew Stacey Aug 17 '12 at 9:41
  • Dammit, it just struck me like a lightning: of cause the nodes are named name-row-column! D'oh! Thanks @AndrewStacey :D – Tom Bombadil Aug 17 '12 at 9:47
8

You can also use the infamous \tikzmark solution which allows one to compose the tables outside (or inside) of the tikzpicture environment, and mark the two points you want to connect, and then draw the arrow between them.

So, with the c data entry defined as c\tikzmark{left}, and the j data entry is defined as \tikzmark{right}j, one can use \DrawArrow[<draw_options>]{left}{right} with different draw options to obtain:

enter image description here

Note:

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\newcommand*{\DrawArrow}[3][]{%
    % #1 = draw options
    % #2 = left point
    % #3 = right point
    \begin{tikzpicture}[overlay,remember picture]
        \draw [-latex, shorten <= 0.25cm, shorten >= 0.30cm, #1] ($(#2)+(0,0.5ex)$) to ($(#3)+(0,0.25ex)$);
    \end{tikzpicture}%
}%

\begin{document}
\begin{tabular}{| c | c | c |}\hline
    a & b & c\tikzmark{left} \\\hline
    d & e & f \\\hline
\end{tabular}
\hspace*{2.0cm}
\begin{tabular}{| c | c | c |}\hline
    g & h & i \\\hline
    \tikzmark{right}j & k & l \\\hline
\end{tabular}
%
\DrawArrow{left}{right}
\end{document}
|improve this answer|||||
3

This is an other idea based on Peter Grill's answer (I didn't even think of using a tabular when writing my first answer, so thanks for reminding me that there are some non-TikZ constructs one could use). It doesn't use \tikzmark (which otherwise is awesome, but in my humble opinion not needed here) and puts the tabulars in nodes instead, so you can use the degree notion (node.degree) to specify where to draw your arrows:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,arrows}

\newcommand{\mytab}[2]% alignment, content
{   \begin{tabular}{#1}
        #2
    \end{tabular}
}

\begin{document}

\begin{tikzpicture}
    \node[inner sep=0] (one) {\mytab{|c|c|c|}{\hline g & h & i \\ \hline j & k & l \\ \hline}};
    \node[inner sep=0,right=2cm of one.east] (two) {\mytab{|c|c|c|}{\hline a & b & c \\ \hline d & e & f \\ \hline}};
    \draw[-latex] (one.15) to[out=0,in=180] (two.195);
\end{tikzpicture}

\end{document}

enter image description here

|improve this answer|||||

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.