5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TikZの導入と木構造(20160123jssac)

Last updated at Posted at 2016-03-31

日本数式処理学会合同分科会発表準備に戻る。]

TikZ を使ったことがない方に,数学的対象の表現手段としての TikZ を,木構造の描画という具体例を通して紹介する。

#はじめての TikZ

日本語 LaTeX の文書でよくある骨格は次のようなものだろう。

sample.tex
\documentclass{jsarticle}

\begin{document}
\end{document}

今回紹介する TikZ パッケージを利用するための最小限の設定。
TikZ は最新の TeXlive や w32TeX,MikTeX にはもれなくついている。
platex + dvipdfmx で使う機会が多いだろうから,グローバルオプション dvipdfmx を指定しよう。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\end{tikzpicture}

\end{document}

TikZ の機能は tikzpicture 環境で発揮される。
picture 環境の発展版と思ってよい。

#場当たり的に木構造を描いてみる

##ノードの位置決め

数式 $8 \div 2 + 1 \times 6$ の木構造を描いてみよう。
まず,ノードの位置を決める。
tikzpicture 内では,TikZ のコマンドごとにセミコロンで〆るのを忘れぬように。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node (plus)  at ( 0, 0) {$+$};
\node (div)   at (-2,-1) {$\div$};
\node (times) at ( 2,-1) {$\times$};
\node (8)     at (-3,-2) {$8$};
\node (2)     at (-1,-2) {$2$};
\node (1)     at ( 1,-2) {$1$};
\node (6)     at ( 3,-2) {$6$};
\end{tikzpicture}

\end{document}

##ノードを線でつなぐ

ノードを線でつなごう。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node (plus)  at ( 0, 0) {$+$};
\node (div)   at (-2,-1) {$\div$};
\node (times) at ( 2,-1) {$\times$};
\node (8)     at (-3,-2) {$8$};
\node (2)     at (-1,-2) {$2$};
\node (1)     at ( 1,-2) {$1$};
\node (6)     at ( 3,-2) {$6$};
\draw (div) -- (plus) -- (times);
\draw (8) -- (div) -- (2);
\draw (1) -- (times) -- (6);
\end{tikzpicture}

\end{document}

##木構造の広がる方向の設定

図は,点と線さえどうにかなれば,とりあえずはよい。
でも,もちろん,それだけでは非効率的。
たとえば,木構造を下ではなく右に広げるには? オプション rotate=90 を指定すればよい。
でも,ノード (8) が下になってしまうのが残念。
上にすることはできない? オプション x={(-1,0)} を指定するのが,ややトリッキーだが,お手軽。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[rotate=90,x={(-1,0)}]
\node (plus)  at ( 0, 0) {$+$};
\node (div)   at (-2,-1) {$\div$};
\node (times) at ( 2,-1) {$\times$};
\node (8)     at (-3,-2) {$8$};
\node (2)     at (-1,-2) {$2$};
\node (1)     at ( 1,-2) {$1$};
\node (6)     at ( 3,-2) {$6$};
\draw (div) -- (plus) -- (times);
\draw (8) -- (div) -- (2);
\draw (1) -- (times) -- (6);
\end{tikzpicture}

\end{document}

#TikZ での木構造表現

ところで,このソースコードは数学的対象を表現していると言えるだろうか。
木構造を表現していると言えるのだろうか。
このソースコードでは,そうとは言えまい。

##child オペレーション

TikZ には数学的対象を表現するさまざまな仕掛けが用意されている。
たとえば,今回の木構造を途中まで書いてみよう。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node {$+$}
  child { node {$\div$} }
  child { node {$\times$} };
\end{tikzpicture}

\end{document}

これならば木構造を表現しているといってよいだろう。何と言っても,ノードの親子関係が一目瞭然。
半角の空白文字が基本的に自由に使えるのは通常の LaTeX と同様。

##兄弟ノード間の距離

さあ,続きを書いてしまおう。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node {$+$}
  child { node {$\div$}
    child { node {$8$} }
    child { node {$2$} }
  }
  child { node {$\times$}
    child { node {$1$} }
    child { node {$6$} }
  };
\end{tikzpicture}

\end{document}

ところが,残念。ノード (2) とノード (1) が重なってしまった!

ノードの間隔を調整するために,オプション sibling distance を指定する。
レベルごとに指定する必要あり。さもなくば,同じ失敗をする。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
  level 1/.style={sibling distance=30mm},
  level 2/.style={sibling distance=10mm}
]
\node {$+$}
  child { node {$\div$}
    child { node {$8$} }
    child { node {$2$} }
  }
  child { node {$\times$}
    child { node {$1$} }
    child { node {$6$} }
  };
\end{tikzpicture}

\end{document}

##木を伸ばす方向

木を伸ばす方向はオプション grow で指定する。
子ノードの順番をひっくり返すには,オプション grow' を指定する。
たとえば,右に伸びる木として自然に表現するならば,オプション grow'=right を指定。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
  level 1/.style={sibling distance=30mm},
  level 2/.style={sibling distance=10mm}
]
\node {$+$} [grow'=right]
  child { node {$\div$}
    child { node {$8$} }
    child { node {$2$} }
  }
  child { node {$\times$}
    child { node {$1$} }
    child { node {$6$} }
  };
\end{tikzpicture}

\end{document}

##ノードの修飾

さて,ここで,欲が出てきた。すべてのノードを丸囲みにしよう。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
  level 1/.style={sibling distance=30mm},
  level 2/.style={sibling distance=10mm}
]
\node[circle,draw] {$+$}
  child { node {$\div$}
    child { node {$8$} }
    child { node {$2$} }
  }
  child { node {$\times$}
    child { node {$1$} }
    child { node {$6$} }
  };
\end{tikzpicture}

\end{document}

すべてのノードにいちいちオプション circle,draw をつけるのではなく,一括して指定できないか。
オプション every node/.style で指定すればよい。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
  level 1/.style={sibling distance=30mm},
  level 2/.style={sibling distance=10mm},
  every node/.style={circle,draw}
]
\node {$+$}
  child { node {$\div$}
    child { node {$8$} }
    child { node {$2$} }
  }
  child { node {$\times$}
    child { node {$1$} }
    child { node {$6$} }
  };
\end{tikzpicture}

\end{document}

##自前オプションの設定

数値は四角,演算子は丸にしたい,というのであれば,自分でオプションを導入することもできる。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
  level 1/.style={sibling distance=30mm},
  level 2/.style={sibling distance=10mm},
  enzanshi/.style={circle,draw},
  suuchi/.style={rectangle,draw}
]
\node[enzanshi] {$+$}
  child { node[enzanshi] {$\div$}
    child { node[suuchi] {$8$} }
    child { node[suuchi] {$2$} }
  }
  child { node[enzanshi] {$\times$}
    child { node[suuchi] {$1$} }
    child { node[suuchi] {$6$} }
  };
\end{tikzpicture}

\end{document}

##ノードの参照

おまけとして,根ノードに参照名をつけておけば,子ノードは適当な番号付きで参照できる。

sample.tex
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[
  level 1/.style={sibling distance=30mm},
  level 2/.style={sibling distance=10mm},
  enzanshi/.style={circle,draw},
  suuchi/.style={rectangle,draw}
]
\node (myexpr) [enzanshi] {$+$}
  child { node[enzanshi] {$\div$}
    child { node[suuchi] {$8$} }
    child { node[suuchi] {$2$} }
  }
  child { node[enzanshi] {$\times$}
    child { node[suuchi] {$1$} }
    child { node[suuchi] {$6$} }
  };
\draw (myexpr-1) node[above=1.5ex,red] {$4$};
\draw (myexpr-1-2) node[right=0.5em,red] {two};
\end{tikzpicture}

\end{document}

##さらに

さて,さらなる望みとして,sibling distance などの設定も TikZ にまかせたい。
これについては LuaTeX で TikZ ライブラリ graphdrawing を利用する方法があることを指摘するにとどめる。

#おしまい

具体例で TikZ を紹介,ここまで。
残りの時間で TikZ の概要を紹介。

日本数式処理学会合同分科会発表準備に戻る。]

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?