Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
add comment

3 Answers

up vote 10 down vote accepted

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

share|improve this answer
    
Thank you for your answer :) –  tikzlearner Aug 17 '12 at 0:03
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
add comment

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}
share|improve this answer
add comment

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

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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