summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/doc/pgfmanual-en-base-matrices.tex
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/base/doc/pgfmanual-en-base-matrices.tex')
-rw-r--r--graphics/pgf/base/doc/pgfmanual-en-base-matrices.tex437
1 files changed, 437 insertions, 0 deletions
diff --git a/graphics/pgf/base/doc/pgfmanual-en-base-matrices.tex b/graphics/pgf/base/doc/pgfmanual-en-base-matrices.tex
new file mode 100644
index 0000000000..c35a345753
--- /dev/null
+++ b/graphics/pgf/base/doc/pgfmanual-en-base-matrices.tex
@@ -0,0 +1,437 @@
+% Copyright 2019 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Free Documentation License.
+%
+% See the file doc/generic/pgf/licenses/LICENSE for more details.
+
+
+\section{Matrices}
+\label{section-base-matrices}
+
+\begin{pgfmodule}{matrix}
+The present section documents the commands of this module.
+\end{pgfmodule}
+
+\subsection{Overview}
+
+Matrices are a mechanism for aligning several so-called cell pictures
+horizontally and vertically. The resulting alignment is placed in a normal node
+and the command for creating matrices, |\pgfmatrix|, takes options very similar
+to the |\pgfnode| command.
+
+In the following, the basic idea behind the alignment mechanism is explained
+first. Then the command |\pgfmatrix| is explained. At the end of the section,
+additional ways of modifying the width of columns and rows are discussed.
+
+
+\subsection{Cell Pictures and Their Alignment}
+
+A matrix consists of rows of \emph{cells}. Cells are separated using the
+special command |\pgfmatrixnextcell|, rows are ended using the command
+|\pgfmatrixendrow| (the command |\\| is set up to mean the same as
+|\pgfmatrixendrow| by default). Each cell contains a \emph{cell picture},
+although cell pictures are not complete pictures as they lack layers. However,
+each cell picture has its own bounding box like a normal picture does. These
+bounding boxes are important for the alignment as explained in the following.
+
+Each cell picture will have an origin somewhere in the picture (or even outside
+the picture). The position of these origins are important for the alignment: On
+each row the origins will be on the same horizontal line and for each column
+the origins will also be on the same vertical line. These two requirements mean
+that the cell pictures may need to be shifted around so that the origins wind
+up on the same lines. The top of a row is given by the top of the cell picture
+whose bounding box's maximum $y$-position is largest. Similarly, the bottom of
+a row is given by the bottom of the cell picture whose bounding box's minimum
+$y$-position is the most negative. Similarly, the left end of a column is given
+by the left end of the cell whose bounding box's $x$-position is the most
+negative; and similarly for the right end of a column.
+%
+\begin{codeexample}[]
+\begin{tikzpicture}[x=3mm,y=3mm,fill=blue!50]
+ \def\atorig#1{\node[black] at (0,0) {\tiny #1};}
+
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{}
+ {
+ \fill (0,-3) rectangle (1,1);\atorig1 \pgfmatrixnextcell
+ \fill (-1,0) rectangle (1,1);\atorig2 \pgfmatrixnextcell
+ \fill (-1,-2) rectangle (0,0);\atorig3 \pgfmatrixnextcell
+ \fill (-1,-1) rectangle (0,3);\atorig4 \\
+ \fill (-1,0) rectangle (4,1);\atorig5 \pgfmatrixnextcell
+ \fill (0,-1) rectangle (1,1);\atorig6 \pgfmatrixnextcell
+ \fill (0,0) rectangle (1,4);\atorig7 \pgfmatrixnextcell
+ \fill (-1,-1) rectangle (0,0);\atorig8 \\
+ }
+\end{tikzpicture}
+\end{codeexample}
+
+
+\subsection{The Matrix Command}
+
+All matrices are typeset using the following command:
+
+\begin{command}{\pgfmatrix\marg{shape}\marg{anchor}\marg{name}\marg{usage}\marg{shift}\marg{pre-code}\marg{matrix cells}}
+ This command creates a node that contains a matrix. The name of the node is
+ \meta{name}, its shape is \meta{shape} and the node is anchored at
+ \meta{anchor}.
+
+ The \meta{matrix cell} parameter contains the cells of the matrix. In each
+ cell drawing commands may be given, which create a so-called cell picture.
+ For each cell picture a bounding box is computed and the cells are aligned
+ according to the rules outlined in the previous section.
+
+ The resulting matrix is used as the |text| box of the node. As for a normal
+ node, the \meta{usage} commands are applied, so that the path(s) of the
+ resulting node is (are) stroked or filled or whatever.
+
+
+ \medskip
+ \textbf{Specifying the cells and rows.\ }
+ Even though this command uses |\halign| internally, there are two special
+ rules for indicating cells:
+ %
+ \begin{enumerate}
+ \item Cells in the same row must be separated using the macro
+ |\pgfmatrixnextcell| rather than |&|. Using |&| will result in an
+ error message.
+
+ However, you can make |&| an active character and have it expand to
+ |\pgfmatrixnextcell|. This way, it will ``look'' as if |&| is used.
+ \item Rows are ended using the command |\pgfmatrixendrow|, but |\\| is
+ set up to mean the same by default. However, some environments like
+ |{minipage}| redefine |\\|, so it is good to have
+ |\pgfmatrixendrow| as a ``fallback''.
+ \item Every row \emph{including the last row} must be ended using the
+ command |\\| or |\pgfmatrixendrow|.
+ \end{enumerate}
+
+ Both |\pgfmatrixnextcell| and |\pgfmatrixendrow| (and, thus, also |\\|)
+ take an optional argument as explained in the
+ Section~\ref{section-matrix-spacing}
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{}
+ {
+ \node {a}; \pgfmatrixnextcell \node {b}; \pgfmatrixendrow
+ \node {c}; \pgfmatrixnextcell \node {d}; \pgfmatrixendrow
+ }
+\end{tikzpicture}
+\end{codeexample}
+
+
+ \medskip
+ \textbf{Anchoring matrices at nodes inside the matrix.\ }
+ The parameter \meta{shift} is an additional negative shift for the node.
+ Normally, such a shift could be given beforehand (that is, the shift could
+ be preapplied to the current transformation matrix). However, when
+ \meta{shift} is evaluated, you can refer to \emph{temporary} positions of
+ nodes inside the matrix. In detail, the following happens: When the matrix
+ has been typeset, all nodes in the matrix temporarily get assigned their
+ positions in the matrix box. The origin of this coordinate system is at the
+ left baseline end of the matrix box, which corresponds to the |text|
+ anchor. The position \meta{shift} is then interpreted inside this
+ coordinate system and then used for shifting.
+
+ This allows you to use the parameter \meta{shift} in the following way: If
+ you use |text| as the \meta{anchor} and specify
+ |\pgfpointanchor{inner node}{some anchor}| for the parameter \meta{shift},
+ where |inner node| is a node that is created in the matrix, then the whole
+ matrix will be shifted such that |inner node.some anchor| lies at the
+ origin of the whole picture.
+
+
+ \medskip
+ \textbf{Rotations and scaling.\ }
+ The matrix node is never rotated or scaled, because the current coordinate
+ transformation matrix is reset (except for the translational part) at the
+ beginning of |\pgfmatrix|. This is intentional and will not change in the
+ future. If you need to rotate or scale the matrix, you must install an
+ appropriate canvas transformation yourself.
+
+ However, nodes and stuff inside the cell pictures can be rotated and scaled
+ normally.
+
+
+ \medskip
+ \textbf{Callbacks.\ }
+ At the beginning and at the end of each cell the special macros
+ |\pgfmatrixbegincode|, |\pgfmatrixendcode| and possibly
+ |\pgfmatrixemptycode| are called. The effect is explained in
+ Section~\ref{section-matrix-callbacks}.
+
+
+ \medskip
+ \textbf{Executing extra code.\ }
+ The parameter \meta{pre-code} is executed at the beginning of the outermost
+ \TeX-group enclosing the matrix node. It is inside this \TeX-group, but
+ outside the matrix itself. It can be used for different purposes:
+ %
+ \begin{enumerate}
+ \item It can be used to simplify the next cell macro. For example,
+ saying |\let\&=\pgfmatrixnextcell| allows you to use |\&| instead
+ of |\pgfmatrixnextcell|. You can also set the catcode of |&| to
+ active.
+ \item It can be used to issue an |\aftergroup| command. This allows you
+ to regain control after the |\pgfmatrix| command. (If you do not
+ know the |\aftergroup| command, you are probably blessed with a
+ simple and happy life.)
+ \end{enumerate}
+
+
+ \medskip
+ \textbf{Special considerations concerning macro expansion.\ }
+ As said before, the matrix is typeset using |\halign| internally. This
+ command does a lot of strange and magic things like expanding the first
+ macro of every cell in a most unusual manner. Here are some effects you may
+ wish to be aware of:
+ %
+ \begin{itemize}
+ \item It is not necessary to actually mention |\pgfmatrixnextcell| or
+ |\pgfmatrixendrow| inside the \meta{matrix cells}. It suffices that
+ the macros inside \meta{matrix cells} expand to these macros
+ sooner or later.
+ \item In particular, you can define clever macros that insert columns
+ and rows as needed for special effects.
+ \end{itemize}
+\end{command}
+
+
+\subsection{Row and Column Spacing}
+\label{section-matrix-spacing}
+
+It is possible to control the space between columns and rows rather detailedly.
+Two commands are important for the row spacing and two commands for the column
+spacing.
+
+\begin{command}{\pgfsetmatrixcolumnsep\marg{sep list}}
+ This macro sets the default separation list for columns. The details of the
+ format of this list are explained in the description of the next command.
+\end{command}
+
+\begin{command}{\pgfmatrixnextcell\opt{\oarg{additional sep list}}}
+ This command has two purposes: First, it is used to separate cells. Second,
+ by providing the optional argument \meta{additional sep list} you can
+ modify the spacing between the columns that are separated by this command.
+
+ The optional \meta{additional sep list} may only be provided when the
+ |\pgfmatrixnextcell| command starts a new column. Normally, this will only
+ be the case in the first row, but sometimes a later row has more elements
+ than the first row. In this case, the |\pgfmatrixnextcell| commands that
+ start the new columns in the later row may also have the optional argument.
+ Once a column has been started, subsequent uses of this optional argument
+ for the column have no effect.
+
+ To determine the space between the two columns that are separated by
+ |\pgfmatrixnextcell|, the following algorithm is executed:
+ %
+ \begin{enumerate}
+ \item Both the default separation list (as set up by
+ |\pgfsetmatrixcolumnsep|) and the \meta{additional sep list} are
+ processed, in this order. If the \meta{additional sep list}
+ argument is missing, only the default separation list is processed.
+ \item Both lists may contain dimensions, separated by commas, as well
+ as occurrences of the keywords |between origins| and
+ |between borders|.
+ \item All dimensions occurring in either list are added together to
+ arrive at a dimension $d$.
+ \item The last occurrence of either of the keywords is located. If
+ neither keyword is present, we proceed as if |between borders| were
+ present.
+ \end{enumerate}
+ %
+ At the end of the algorithm, a dimension $d$ has been computed and one of
+ the two \emph{modes} |between borders| and |between origins| has been
+ determined. Depending on which mode has been determined, the following
+ happens:
+ %
+ \begin{itemize}
+ \item For the |between borders| mode, an additional horizontal space of
+ $d$ is added between the two columns. Note that $d$ may be
+ negative.
+ \item For the |between origins| mode, the spacing between the two
+ columns is computed differently: Recall that the origins of the
+ cell pictures in both pictures lie on two vertical lines. The
+ spacing between the two columns is set up such that the horizontal
+ distance between these two lines is exactly $d$.
+
+ This mode may only be used between columns \emph{already introduced
+ in the first row}.
+ \end{itemize}
+ %
+ All of the above rules boil down to the following effects:
+ %
+ \begin{itemize}
+ \item A default spacing between columns should be set up using
+ |\pgfsetmatrixcolumnsep|. For example, you might say
+ |\pgfsetmatrixcolumnsep{5pt}| to have columns spaced apart by
+ |5pt|. You could say
+ %
+\begin{verbatim}
+\pgfsetmatrixcolumnsep{1cm,between origins}
+\end{verbatim}
+ %
+ to specify that horizontal space between the origins of cell
+ pictures in adjacent columns should be 1cm by default -- regardless
+ of the actual size of the cell pictures.
+ \item You can now use the optional argument of |\pgfmatrixnextcell| to
+ locally overrule the spacing between two columns. By saying
+ |\pgfmatrixnextcell[5pt]| you \emph{add} 5pt to the space between
+ of the two columns, regardless of the mode.
+
+ You can also (locally) change the spacing mode for these two
+ columns. For example, even if the normal spacing mode is
+ |between origins|, you can say
+ %
+\begin{verbatim}
+\pgfmatrixnextcell[5pt,between borders]
+\end{verbatim}
+ %
+ to locally change the mode for these columns to |between borders|.
+ \end{itemize}
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[every node/.style=draw]
+ \pgfsetmatrixcolumnsep{1mm}
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
+ {
+ \node {8}; \&[2mm] \node{1}; \&[-1mm] \node {6}; \\
+ \node {3}; \& \node{5}; \& \node {7}; \\
+ \node {4}; \& \node{9}; \& \node {2}; \\
+ }
+\end{tikzpicture}
+\end{codeexample}
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[every node/.style=draw]
+ \pgfsetmatrixcolumnsep{1mm}
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
+ {
+ \node {8}; \&[2mm] \node(a){1}; \&[1cm,between origins] \node(b){6}; \\
+ \node {3}; \& \node {5}; \& \node {7}; \\
+ \node {4}; \& \node {9}; \& \node {2}; \\
+ }
+ \draw [<->,red,thick,every node/.style=] (a.center) -- (b.center)
+ node [above,midway] {11mm};
+\end{tikzpicture}
+\end{codeexample}
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[every node/.style=draw]
+ \pgfsetmatrixcolumnsep{1cm,between origins}
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
+ {
+ \node (a) {8}; \& \node (b) {1}; \&[between borders] \node (c) {6}; \\
+ \node {3}; \& \node {5}; \& \node {7}; \\
+ \node {4}; \& \node {9}; \& \node {2}; \\
+ }
+ \begin{scope}[every node/.style=]
+ \draw [<->,red,thick] (a.center) -- (b.center) node [above,midway] {10mm};
+ \draw [<->,red,thick] (b.east) -- (c.west) node [above,midway]
+ {10mm};
+ \end{scope}
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{command}
+
+The mechanism for the between-row-spacing is the same, only the commands are
+called differently.
+
+\begin{command}{\pgfsetmatrixrowsep\marg{sep list}}
+ This macro sets the default separation list for rows.
+\end{command}
+
+\begin{command}{\pgfmatrixendrow\opt{\oarg{additional sep list}}}
+ This command ends a line. The optional \meta{additional sep list} is used
+ to determine the spacing between the row being ended and the next row. The
+ modes and the computation of $d$ is done in the same way as for columns.
+ For the last row the optional argument has no effect.
+
+ Inside matrices (and only there) the command |\\| is set up to mean the
+ same as this command.
+\end{command}
+
+
+\subsection{Callbacks}
+\label{section-matrix-callbacks}
+
+There are three macros that get called at the beginning and end of cells. By
+redefining these macros, which are empty by default, you can change the
+appearance of cells in a very general manner.
+
+\begin{command}{\pgfmatrixemptycode}
+ This macro is executed for empty cells. This means that \pgfname\ uses some
+ macro magic to determine whether a cell is empty (it immediately ends with
+ |\pgfmatrixemptycode| or |\pgfmatrixendrow|) and, if so, put this macro
+ inside the cell.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \def\pgfmatrixemptycode{\node{empty};}
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
+ {
+ \node {a}; \& \& \node {b}; \\
+ \& \node{c}; \& \node {d}; \& \\
+ }
+\end{tikzpicture}
+\end{codeexample}
+ %
+ As can be seen, the macro is not executed for empty cells at the end of row
+ when columns are added only later on.
+\end{command}
+
+\begin{command}{\pgfmatrixbegincode}
+ This macro is executed at the beginning of non-empty cells.
+ Correspondingly, |\pgfmatrixendcode| is added at the end of every non-empty
+ cell.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \def\pgfmatrixbegincode{\node[draw]\bgroup}
+ \def\pgfmatrixendcode{\egroup;}
+ \pgfmatrix{rectangle}{center}{mymatrix}
+ {\pgfusepath{}}{\pgfpointorigin}{\let\&=\pgfmatrixnextcell}
+ {
+ a \& b \& c \\
+ d \& \& e \\
+ }
+\end{tikzpicture}
+\end{codeexample}
+ %
+ Note that between |\pgfmatrixbegincode| and |\pgfmatrixendcode| there will
+ \emph{not} only be the contents of the cell. Rather, \pgfname\ will add
+ some (invisible) commands for book-keeping purposes that involve |\let| and
+ |\gdef|. In particular, it is not a good idea to have |\pgfmatrixbegincode|
+ end with |\csname| and |\pgfmatrixendcode| start with |\endcsname|.
+\end{command}
+
+\begin{command}{\pgfmatrixendcode}
+ See the explanation above.
+\end{command}
+
+The following two counters allow you to access the current row and current
+column in a callback:
+
+\begin{command}{\pgfmatrixcurrentrow}
+ This counter stores the current row of the current cell of the matrix. Do
+ not even think about changing this counter.
+\end{command}
+
+\begin{command}{\pgfmatrixcurrentcolumn}
+ This counter stores the current column of the current cell of the matrix.
+\end{command}
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "pgfmanual"
+%%% End: