[日本数式処理学会合同分科会発表準備に戻る。]
TikZ を使ったことがない方に,数学的対象の表現手段としての TikZ を,木構造の描画という具体例を通して紹介する。
#はじめての TikZ
日本語 LaTeX の文書でよくある骨格は次のようなものだろう。
\documentclass{jsarticle}
\begin{document}
\end{document}
今回紹介する TikZ パッケージを利用するための最小限の設定。
TikZ は最新の TeXlive や w32TeX,MikTeX にはもれなくついている。
platex + dvipdfmx で使う機会が多いだろうから,グローバルオプション dvipdfmx
を指定しよう。
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\end{tikzpicture}
\end{document}
TikZ の機能は tikzpicture
環境で発揮される。
picture
環境の発展版と思ってよい。
#場当たり的に木構造を描いてみる
##ノードの位置決め
数式 $8 \div 2 + 1 \times 6$ の木構造を描いてみよう。
まず,ノードの位置を決める。
tikzpicture
内では,TikZ のコマンドごとにセミコロンで〆るのを忘れぬように。
\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}
##ノードを線でつなぐ
ノードを線でつなごう。
\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)}
を指定するのが,ややトリッキーだが,お手軽。
\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 には数学的対象を表現するさまざまな仕掛けが用意されている。
たとえば,今回の木構造を途中まで書いてみよう。
\documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node {$+$}
child { node {$\div$} }
child { node {$\times$} };
\end{tikzpicture}
\end{document}
これならば木構造を表現しているといってよいだろう。何と言っても,ノードの親子関係が一目瞭然。
半角の空白文字が基本的に自由に使えるのは通常の LaTeX と同様。
##兄弟ノード間の距離
さあ,続きを書いてしまおう。
\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
を指定する。
レベルごとに指定する必要あり。さもなくば,同じ失敗をする。
\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
を指定。
\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}
##ノードの修飾
さて,ここで,欲が出てきた。すべてのノードを丸囲みにしよう。
\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
で指定すればよい。
\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}
##自前オプションの設定
数値は四角,演算子は丸にしたい,というのであれば,自分でオプションを導入することもできる。
\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}
##ノードの参照
おまけとして,根ノードに参照名をつけておけば,子ノードは適当な番号付きで参照できる。
\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 の概要を紹介。
[日本数式処理学会合同分科会発表準備に戻る。]