summaryrefslogtreecommitdiff
path: root/graphics/pgf/base/doc/pgfmanual-en-tikz-transformations.tex
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/base/doc/pgfmanual-en-tikz-transformations.tex')
-rw-r--r--graphics/pgf/base/doc/pgfmanual-en-tikz-transformations.tex499
1 files changed, 499 insertions, 0 deletions
diff --git a/graphics/pgf/base/doc/pgfmanual-en-tikz-transformations.tex b/graphics/pgf/base/doc/pgfmanual-en-tikz-transformations.tex
new file mode 100644
index 0000000000..baa38cb438
--- /dev/null
+++ b/graphics/pgf/base/doc/pgfmanual-en-tikz-transformations.tex
@@ -0,0 +1,499 @@
+% Copyright 2018 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{Transformations}
+
+\pgfname\ has a powerful transformation mechanism that is similar to the
+transformation capabilities of \textsc{metafont}. The present section explains
+how you can access it in \tikzname.
+
+
+\subsection{The Different Coordinate Systems}
+
+It is a long process from a coordinate like, say, $(1,2)$ or
+$(1\mathrm{cm},5\mathrm{pt})$, to the position a point is finally placed on the
+display or paper. In order to find out where the point should go, it is
+constantly ``transformed'', which means that it is mostly shifted around and
+possibly rotated, slanted, scaled, and otherwise mutilated.
+
+In detail, (at least) the following transformations are applied to a coordinate
+like $(1,2)$ before a point on the screen is chosen:
+%
+\begin{enumerate}
+ \item \pgfname\ interprets a coordinate like $(1,2)$ in its
+ $xy$-coordinate system as ``add the current $x$-vector once and the
+ current $y$-vector twice to obtain the new point''.
+ \item \pgfname\ applies its coordinate transformation matrix to the
+ resulting coordinate. This yields the final position of the point
+ inside the picture.
+ \item The backend driver (like |dvips| or |pdftex|) adds transformation
+ commands such that the coordinate is shifted to the correct position in
+ \TeX's page coordinate system.
+ \item \textsc{pdf} (or PostScript) apply the canvas transformation matrix
+ to the point, which can once more change the position on the page.
+ \item The viewer application or the printer applies the device
+ transformation matrix to transform the coordinate to its final pixel
+ coordinate on the screen or paper.
+\end{enumerate}
+
+In reality, the process is even more involved, but the above should give the
+idea: A point is constantly transformed by changes of the coordinate system.
+
+In \tikzname, you only have access to the first two coordinate systems: The
+$xy$-coordinate system and the coordinate transformation matrix (these will be
+explained later). \pgfname\ also allows you to change the canvas transformation
+matrix, but you have to use commands of the core layer directly to do so and
+you ``better know what you are doing'' when you do this. The moment you start
+modifying the canvas matrix, \pgfname\ immediately loses track of all
+coordinates and shapes, anchors, and bounding box computations will no longer
+work.
+
+
+\subsection{The XY- and XYZ-Coordinate Systems}
+\label{section-xyz}
+
+The first and easiest coordinate systems are \pgfname's $xy$- and
+$xyz$-coordinate systems. The idea is very simple: Whenever you specify a
+coordinate like |(2,3)| this means $2v_x + 3v_y$, where $v_x$ is the current
+\emph{$x$-vector} and $v_y$ is the current \emph{$y$-vector}. Similarly, the
+coordinate |(1,2,3)| means $v_x + 2v_y + 3v_z$.
+
+Unlike other packages, \pgfname\ does not insist that $v_x$ actually has a
+$y$-component of $0$, that is, that it is a horizontal vector. Instead, the
+$x$-vector can point anywhere you want. Naturally, \emph{normally} you will
+want the $x$-vector to point horizontally.
+
+One undesirable effect of this flexibility is that it is not possible to
+provide mixed coordinates as in $(1,2\mathrm{pt})$. Life is hard.
+
+To change the $x$-, $y$-, and $z$-vectors, you can use the following options:
+
+\begin{key}{/tikz/x=\meta{value} (initially 1cm)}
+ If \meta{value} is a dimension, the $x$-vector of \pgfname's
+ $xyz$-coordinate system is set up to point \meta{value} to the right, that
+ is, to $(\meta{value},0pt)$.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw (0,0) -- +(1,0);
+ \draw[x=2cm,color=red] (0,0.1) -- +(1,0);
+\end{tikzpicture}
+\end{codeexample}
+
+\begin{codeexample}[]
+\tikz \draw[x=1.5cm] (0,0) grid (2,2);
+\end{codeexample}
+
+ The last example shows that the size of steppings in grids, just like all
+ other dimensions, are not affected by the $x$-vector. After all, the
+ $x$-vector is only used to determine the coordinate of the upper right
+ corner of the grid.
+
+ If \meta{value} is a coordinate, the $x$-vector of \pgfname's
+ $xyz$-coordinate system is set to the specified coordinate. If \meta{value}
+ contains a comma, it must be put in braces.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw (0,0) -- (1,0);
+ \draw[x={(2cm,0.5cm)},color=red] (0,0) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+
+ You can use this, for example, to exchange the meaning of the $x$- and
+ $y$-coordinate.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[smooth]
+ \draw plot coordinates{(1,0) (2,0.5) (3,0) (3,1)};
+ \draw[x={(0cm,1cm)},y={(1cm,0cm)},color=red]
+ plot coordinates{(1,0) (2,0.5) (3,0) (3,1)};
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/y=\meta{value} (initially 1cm)}
+ Works like the |x=| option, only if \meta{value} is a dimension, the
+ resulting vector points to $(0,\meta{value})$.
+\end{key}
+
+\begin{key}{/tikz/z=\meta{value} (initially \normalfont$-3.85$mm)}
+ Works like the |y=| option, but now a dimension is the point
+ $(\meta{value},\meta{value})$.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[z=-1cm,->,thick]
+ \draw[color=red] (0,0,0) -- (1,0,0);
+ \draw[color=blue] (0,0,0) -- (0,1,0);
+ \draw[color=orange] (0,0,0) -- (0,0,1);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+
+\subsection{Coordinate Transformations}
+
+\pgfname\ and \tikzname\ allow you to specify \emph{coordinate
+transformations}. Whenever you specify a coordinate as in |(1,0)| or
+|(1cm,1pt)| or |(30:2cm)|, this coordinate is first ``reduced'' to a position
+of the form ``$x$ points to the right and $y$ points upwards''. For example,
+|(1in,5pt)| is reduced to ``$72\frac{72}{100}$ points to the right and 5 points
+upwards'' and |(90:100pt)| means ``0pt to the right and 100 points upwards''.
+
+The next step is to apply the current \emph{coordinate transformation matrix}
+to the coordinate. For example, the coordinate transformation matrix might
+currently be set such that it adds a certain constant to the $x$ value. Also,
+it might be set up such that it, say, exchanges the $x$ and $y$ value. In
+general, any ``standard'' transformation like translation, rotation, slanting,
+or scaling or any combination thereof is possible. (Internally, \pgfname\ keeps
+track of a coordinate transformation matrix very much like the concatenation
+matrix used by \textsc{pdf} or PostScript.)
+%
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) rectangle (1,0.5);
+ \begin{scope}[xshift=1cm]
+ \draw [red] (0,0) rectangle (1,0.5);
+ \draw[yshift=1cm] [blue] (0,0) rectangle (1,0.5);
+ \draw[rotate=30] [orange] (0,0) rectangle (1,0.5);
+ \end{scope}
+\end{tikzpicture}
+\end{codeexample}
+
+The most important aspect of the coordinate transformation matrix is \emph{that
+it applies to coordinates only!} In particular, the coordinate transformation
+has no effect on things like the line width or the dash pattern or the shading
+angle. In certain cases, it is not immediately clear whether the coordinate
+transformation matrix \emph{should} apply to a certain dimension. For example,
+should the coordinate transformation matrix apply to grids? (It does.) And what
+about the size of arced corners? (It does not.) The general rule is: ``If there
+is no `coordinate' involved, even `indirectly', the matrix is not applied.''.
+However, sometimes, you simply have to try or look it up in the documentation
+whether the matrix will be applied.
+
+Setting the matrix cannot be done directly. Rather, all you can do is to
+``add'' another transformation to the current matrix. However, all
+transformations are local to the current \TeX-group. All transformations are
+added using graphic options, which are described below.
+
+Transformations apply immediately when they are encountered ``in the middle of
+a path'' and they apply only to the coordinates on the path following the
+transformation option.
+%
+\begin{codeexample}[]
+\tikz \draw (0,0) rectangle (1,0.5) [xshift=2cm] (0,0) rectangle (1,0.5);
+\end{codeexample}
+
+A final word of warning: You should refrain from using ``aggressive''
+transformations like a scaling of a factor of 10\,000. The reason is that all
+transformations are done using \TeX, which has a fairly low accuracy.
+Furthermore, in certain situations it is necessary that \tikzname\
+\emph{inverts} the current transformation matrix and this will fail if the
+transformation matrix is badly conditioned or even singular (if you do not know
+what singular matrices are, you are blessed).
+
+\begin{key}{/tikz/shift={\ttfamily\char`\{}\meta{coordinate}{\ttfamily\char`\}}}
+ Adds the \meta{coordinate} to all coordinates.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[shift={(1,1)},blue] (0,0) -- (1,1) -- (1,0);
+ \draw[shift={(30:1cm)},red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/shift only}
+ This option does not take any parameter. Its effect is to cancel all
+ current transformations except for the shifting. This means that the origin
+ will remain where it is, but any rotation around the origin or scaling
+ relative to the origin or skewing will no longer have an effect.
+
+ This option is useful in situations where a complicated transformation is
+ used to ``get to a position'', but you then wish to draw something
+ ``normal'' at this position.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[rotate=30,xshift=2cm,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[rotate=30,xshift=2cm,shift only,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/xshift=\meta{dimension}}
+ Adds \meta{dimension} to the $x$ value of all coordinates.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[xshift=2cm,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[xshift=-10pt,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/yshift=\meta{dimension}}
+ Adds \meta{dimension} to the $y$ value of all coordinates.
+\end{key}
+
+\begin{key}{/tikz/scale=\meta{factor}}
+ Multiplies all coordinates by the given \meta{factor}. The \meta{factor}
+ should not be excessively large in absolute terms or very close to zero.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[scale=2,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[scale=-1,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/scale around={\ttfamily\char`\{}\meta{factor}|:|\meta{coordinate}{\ttfamily\char`\}}}
+ Scales the coordinate system by \meta{factor}, with the ``origin of
+ scaling'' centered on \meta{coordinate} rather than the origin.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[scale=2,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[scale around={2:(1,1)},red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/xscale=\meta{factor}}
+ Multiplies only the $x$-value of all coordinates by the given
+ \meta{factor}.
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[xscale=2,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[xscale=-1,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/yscale=\meta{factor}}
+ Multiplies only the $y$-value of all coordinates by \meta{factor}.
+\end{key}
+
+\begin{key}{/tikz/xslant=\meta{factor}}
+ Slants the coordinate horizontally by the given \meta{factor}:
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[xslant=2,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[xslant=-1,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/yslant=\meta{factor}}
+ Slants the coordinate vertically by the given \meta{factor}:
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[yslant=2,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[yslant=-1,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/rotate=\meta{degree}}
+ Rotates the coordinate system by \meta{degree}:
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[rotate=40,blue] (0,0) -- (1,1) -- (1,0);
+ \draw[rotate=-20,red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/rotate around={\ttfamily\char`\{}\meta{degree}|:|\meta{coordinate}{\ttfamily\char`\}}}
+ Rotates the coordinate system by \meta{degree} around the point
+ \meta{coordinate}.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[rotate around={40:(1,1)},blue] (0,0) -- (1,1) -- (1,0);
+ \draw[rotate around={-20:(1,1)},red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/rotate around x=\meta{angle}}
+ This key sets the $x$, $y$ and $z$ vectors of the \pgfname\
+ $xyz$-coordinate system so that they are rotated by \meta{angle} around the
+ axis corresponding to the $x$-vector. The rotation is applied so that when
+ looking towards the origin along this axis, positive angles result in an
+ anticlockwise rotation.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[>=stealth]
+ \draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$x$};
+ \draw [->] (0,0,0) -- (0,2,0) node [at end, left] {$y$};
+ \draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$};
+
+ \draw [red, rotate around x=0] (0,0,0) -- (1,1,0) -- (1,0,0);
+ \draw [green, rotate around x=45] (0,0,0) -- (1,1,0) -- (1,0,0);
+ \draw [blue, rotate around x=90] (0,0,0) -- (1,1,0) -- (1,0,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/rotate around y=\meta{angle}}
+ This key sets the $x$, $y$ and $z$ vectors of the \pgfname\
+ $xyz$-coordinate system so that they are rotated by \meta{angle} around
+ the axis corresponding to the $y$-vector. The rotation is applied so that
+ when looking towards the origin along this axis, positive angles result in
+ an anticlockwise rotation.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[>=stealth]
+ \draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$x$};
+ \draw [->] (0,0,0) -- (0,2,0) node [at end, left] {$y$};
+ \draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$};
+
+ \draw [red, rotate around y=0] (0,0,0) -- (1,1,0) -- (1,0,0);
+ \draw [green, rotate around y=-45] (0,0,0) -- (1,1,0) -- (1,0,0);
+ \draw [blue, rotate around y=-90] (0,0,0) -- (1,1,0) -- (1,0,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/rotate around z=\meta{angle}}
+ This key sets the $x$, $y$ and $z$ vectors of the \pgfname\
+ $xyz$-coordinate system so that they are rotated by \meta{angle} around the
+ axis corresponding to the $z$-vector. The rotation is applied so that when
+ looking towards the origin along this axis, positive angles result in an
+ anticlockwise rotation.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}[>=stealth]
+ \draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$x$};
+ \draw [->] (0,0,0) -- (0,2,0) node [at end, left] {$y$};
+ \draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$};
+
+ \draw [red, rotate around z=0] (0,0) -- (1,1) -- (1,0);
+ \draw [green, rotate around z=45] (0,0) -- (1,1) -- (1,0);
+ \draw [blue, rotate around z=90] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/cm={\ttfamily\char`\{}\meta{$a$}|,|\meta{$b$}|,|\meta{$c$}|,|\meta{$d$}|,|\meta{coordinate}{\ttfamily\char`\}}}
+ applies the following transformation to all coordinates: Let $(x,y)$ be the
+ coordinate to be transformed and let \meta{coordinate} specify the point
+ $(t_x,t_y)$. Then the new coordinate is given by
+ $\left(\begin{smallmatrix} a & c \\ b & d\end{smallmatrix}\right)
+ \left(\begin{smallmatrix} x \\ y \end{smallmatrix}\right) +
+ \left(\begin{smallmatrix} t_x \\ t_y \end{smallmatrix}\right)$.
+ Usually, you do not use this option directly.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[cm={1,1,0,1,(0,0)},blue] (0,0) -- (1,1) -- (1,0);
+ \draw[cm={0,1,1,0,(1cm,1cm)},red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}
+
+\begin{key}{/tikz/reset cm}
+ Completely resets the coordinate transformation matrix to the identity
+ matrix. This will destroy not only the transformations applied in the
+ current scope, but also all transformations inherited from surrounding
+ scopes. Do not use this option, unless you really, really know what you are
+ doing.
+\end{key}
+
+
+\subsection{Canvas Transformations}
+
+A \emph{canvas transformation}, see
+Section~\ref{section-design-transformations} for details, is best thought of as
+a transformation in which the drawing canvas is stretched or rotated. Imaging
+writing something on a balloon (the canvas) and then blowing air into the
+balloon: Not only does the text become larger, the thin lines also become
+larger. In particular, if you scale the canvas by a factor of two, all lines
+are twice as thick.
+
+Canvas transformations should be used with great care. In most circumstances
+you do \emph{not} want line widths to change in a picture as this creates
+visual inconsistency.
+
+Just as important, when you use canvas transformations \emph{\pgfname\ loses
+track of positions of nodes and of picture sizes} since it does not take the
+effect of canvas transformations into account when it computes coordinates of
+nodes (do not, however, rely on this; it may change in the future).
+
+Finally, note that a canvas transformation always applies to a path as a whole,
+it is not possible (as for coordinate transformations) to use different
+transformations in different parts of a path.
+
+In short, you should not use canvas transformations unless you really know what
+you are doing.
+
+\begin{key}{/tikz/transform canvas=\meta{options}}
+ The \meta{options} should contain coordinate transformations options like
+ |scale| or |xshift|. Multiple options can be given, their effects
+ accumulate in the usual manner. The effect of these \meta{options}
+ (immediately) changes the current canvas transformation matrix. The
+ coordinate transformation matrix is not changed. Tracking of the picture
+ size is (locally) switched off and the node coordinate will no longer be
+ correct.
+ %
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \draw (0,0) -- (1,1) -- (1,0);
+ \draw[transform canvas={scale=2},blue] (0,0) -- (1,1) -- (1,0);
+ \draw[transform canvas={rotate=180},red] (0,0) -- (1,1) -- (1,0);
+\end{tikzpicture}
+\end{codeexample}
+ %
+\end{key}