summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-09 00:56:57 +0000
committerKarl Berry <karl@freefriends.org>2006-01-09 00:56:57 +0000
commitf07bb53970ee2ecc53f81a206a3d3a67ef665e4a (patch)
tree6f57a1d62971db79e5ff023bdfd83b22cb971dc9 /Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex
parent007f67a693e4d031fd3d792df8e4d5f43e2cb2e7 (diff)
doc 6
git-svn-id: svn://tug.org/texlive/trunk@85 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex')
-rw-r--r--Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex391
1 files changed, 391 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex
new file mode 100644
index 00000000000..6c23140fbe7
--- /dev/null
+++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-snakes.tex
@@ -0,0 +1,391 @@
+% Copyright 2003 by Till Tantau <tantau@cs.tu-berlin.de>.
+%
+% This program can be redistributed and/or modified under the terms
+% of the LaTeX Project Public License Distributed from CTAN
+% archives in directory macros/latex/base/lppl.txt.
+
+
+\section{Snakes}
+
+\label{section-base-snakes}
+
+\subsection{Overview}
+
+A \emph{snake} is a ``way of adding a winding line to a path.'' To be
+a bit more precise, you use snakes to extend the path and the
+commands for using snakes start with |\pgfpath|. However, snakes do
+not necessarily extend the path using line-to and curve-to operations;
+rather, they can also contain move-to operations and, thereby, cause
+the path to be split into many subpaths.
+
+As an example, let us consider a simple snake like the |zigzag|
+snake. It looks like this:
+
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[snake=zigzag] (0,0) -- (3,0);
+ \draw[snake=zigzag] (0,-.5) -- (3,-1);
+\end{tikzpicture}
+\end{codeexample}
+
+The above example demonstrates the two key features of snakes:
+\begin{enumerate}
+\item
+ Snakes are made up from little segments that are repeated several
+ times. For the |zigzag| snake these segements look like this:
+ \tikz{\draw[snake=zigzag] (0,0) -- (\pgfsnakesegmentlength+0.1pt,0pt);}.
+\item
+ Snakes ``follow along a straight to the target point.'' Thus, when
+ the target point is not to the right of the start point, the snake
+ is rotated appropriately.
+\end{enumerate}
+
+
+In order to use snakes, they first have to be \emph{declared}. This
+declaration contains a detailed description of how each segement of
+the snake looks like and in what ordering the different possible
+segments are used.
+
+Once a snake has been declared, it can be used. For this you specify a
+target point and a snaked line will be added from the last point
+current point to the target point.
+
+
+\subsection{Declaring a Snake}
+
+
+\subsubsection{Segments}
+
+When you declare a snake, you provide a description of how the
+different segments of the snake will be rendered. The description of
+each segment should be given in a way as if the target of the snaked
+line where at $(+\infty,0)$ and as if the segment's start where at the
+origin. Thus, for example, the segment of the |zigzag| might be
+defined using the following code:
+\begin{codeexample}[code only]
+\pgfpathlineto{\pgfpoint{5pt}{5pt}}
+\pgfpathlineto{\pgfpoint{15pt}{-5pt}}
+\pgfpathlineto{\pgfpoint{20pt}{0pt}}
+\end{codeexample}
+
+\pgfname\ will ensure that an appropriate coordinate transformation
+is in place when the snake segment is added to the path such that
+the snake segment actually points in the right direction. Also
+subsequent snake segments will be transformed such that they are
+``further along the line'' toward the target. All transformations
+are setup automatically.
+
+Note that we did not use a |\pgfpathmoveto{\pgfpointorigin}| at the
+beginning of the segment code. Doing so would subdivide the path into
+numerous subpath. Rather, we assume that the previous segment caused
+the current point to be at the origin.
+
+While we can now describe segments, we still need a way to ``stop''
+the snake. Also, \pgfname\ needs to know the width of the different
+snake segments such that it can translate the next segment correctly.
+Even though it would be possible to compute all this information
+automatically, \pgfname\ does not do so and you have to provide the
+information ``by hand'' for each segment.
+
+
+\subsubsection{Snake Automata}
+
+Up to now our snakes only have one segment that is repeated again and
+again. However, we might also like to have \emph{different} segments
+and use rules to describe which segment should be used where. For
+example, we might have special segments at the start and at the end.
+
+For snakes we use a mechanism known in computer science as
+\emph{finite automata} to describe which segment is used in each part
+of the snake. The idea is the following: For the first segment we
+start in a special \emph{state} called the \emph{initial state}. In
+this state, and also in all other state later, \pgfname\ first
+computes how much space is left on the snake. That is, \pgfname\ keeps
+track of the distance to the target. Attached to each state there is a
+set of rules of the following form: ``If the remaining distance is
+less than $x$, switch to state~$q$.'' \pgfname\ checks for each of
+these rules whether it applies and, if so, immediately switches to
+state~$q$.
+
+Only if none of the rules tell us to switch to another
+state, \pgfname\ will execute the state's code. This code will add a
+segment to the path. In addition to the rules there is also width
+parameter attached to each state. \pgfname\ then translates the
+coordinate system by this width and reduces the remaining distance.
+Then, \pgfname\ either stays in the current state or switches to
+another state, depending on yet another property attached of the
+state.
+
+The whole process stops when a special state called |final| is
+reached. The segment of this state is added to the path immediately
+(it is often empty, though) and the process ends.
+
+\subsubsection{The Snake Declaration Command}
+
+\begin{command}{\pgfdeclaresnake\marg{name}\marg{initial
+ state}\marg{states}}
+ This command declares a new snake called \meta{name}. The
+ \meta{states} argument contains a description of the snake
+ automaton's states and the transitions between them. The
+ \meta{initial state} is the state in which the automaton starts.
+
+ The \meta{states} argument should consist of |\state| commands, one
+ for each state of the snake automaton. The |\state| command is
+ defined only when the \meta{states} argument is executed.
+
+\begin{codeexample}[]
+\pgfdeclaresnake{example snake}{initial}
+{
+ \state{initial}[width=10pt]
+ {
+ \pgfpathlineto{\pgfpoint{0pt}{5pt}}
+ \pgfpathlineto{\pgfpoint{5pt}{5pt}}
+ \pgfpathlineto{\pgfpoint{5pt}{-5pt}}
+ \pgfpathlineto{\pgfpoint{10pt}{-5pt}}
+ \pgfpathlineto{\pgfpoint{10pt}{0pt}}
+ }
+ \state{final}
+ {
+ \pgfpathlineto{\pgfpoint{\pgfsnakeremainingdistance}{0pt}}
+ }
+}
+\tikz{\draw[snake=example snake] (0,0) -- (3,0);
+ \draw[snake=example snake] (0,-1) -- (3,-3);}
+\end{codeexample}
+
+ The |\state| command works as follows:
+ \begin{command}{\state\marg{name}\oarg{options}\marg{code}}
+ This command declares a new state inside the current snake
+ automaton. The state is names \meta{name}.
+
+ When \pgfname\ is in state \meta{name}, the following things
+ happen:
+ \begin{enumerate}
+ \item
+ The \meta{options} are parsed. This may lead, see below, to a
+ state switch. When this happens, the following steps are not
+ executed. The \meta{options} are executed one after the other in
+ the given order. If an option causes a state switch, the switch
+ is immediate, even if later options might cause a different
+ state switch.
+ \item
+ The \meta{code} is executed. When this happens, the coordinate
+ transformation will be setup such that the origin is at the
+ start of the segment and such that the target lies in the
+ direction ``east.''
+ \item
+ After the \meta{code} has been executed, the state switches to
+ whatever state has been specified inside the \meta{options}
+ using the |next state| option. If no |next state| has been
+ specified, the state stays the same.
+ \end{enumerate}
+
+ The following options are allowed inside the \meta{options}:
+ \begin{itemize}
+ \itemoption{switch if less than}|=|\meta{dimension}| to |\meta{new state}
+ When this option is encountered, \pgfname\ checks whether the
+ remaining distance to the target is less than
+ \meta{dimension}. If so, an immediate state switch to \meta{new
+ state} occurs.
+ \itemoption{width}|=|\meta{dimension}
+ This option tells \pgfname\ the width of the segment if it is
+ appended to the path. The coordinate system will, afterward, be
+ translated by \meta{dimension} to ensure that the next segment
+ starts where the current one ended.
+
+ In addition, this option will cause an immediate switch to the
+ state |final| if the remaining distance is less than
+ \meta{dimension}. The effect is the same as if you had said
+ |switch if less than=|\meta{dimension}| to final| just before
+ the |width| option.
+ \itemoption{next state}=\meta{new state}
+ After the segment has been added to the path, a state switch to
+ \meta{new state} is performed. If this option is not given, the
+ next state is the same as the current state.
+ \end{itemize}
+
+ There are two dimensions that are useful inside snake automata:
+ \begin{command}{\pgfsnakeremainingdistance}
+ This \TeX\ dimension holds the remaining distance to the target.
+ \end{command}
+ \begin{command}{\pgfsnakecompleteddistance}
+ This \TeX\ dimension holds the distance already completed on the
+ snake.
+ \end{command}
+ \end{command}
+
+ As a final example we present a more complicated snake that makes
+ use of the different options:
+\begin{codeexample}[]
+\pgfdeclaresnake{complicated example snake}{initial}
+{
+ \state{initial}[width=5pt,next state=up]
+ { \pgfpathlineto{\pgfpoint{5pt}{0pt}} }
+
+ \state{up}[width=5pt,next state=down]
+ {
+ \ifdim\pgfsnakeremainingdistance>\pgfsnakecompleteddistance
+ % Growing
+ \pgfpathlineto{\pgfpoint{0pt}{\pgfsnakecompleteddistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{\pgfsnakecompleteddistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{0pt}}
+ \else
+ % Shrinking
+ \pgfpathlineto{\pgfpoint{0pt}{\pgfsnakeremainingdistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{\pgfsnakeremainingdistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{0pt}}
+ \fi%
+ }
+ \state{down}[width=5pt,next state=up]
+ {
+ \ifdim\pgfsnakeremainingdistance>\pgfsnakecompleteddistance
+ % Growing
+ \pgfpathlineto{\pgfpoint{0pt}{-\pgfsnakecompleteddistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{-\pgfsnakecompleteddistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{0pt}}
+ \else
+ % Shrinking
+ \pgfpathlineto{\pgfpoint{0pt}{-\pgfsnakeremainingdistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{-\pgfsnakeremainingdistance}}
+ \pgfpathlineto{\pgfpoint{5pt}{0pt}}
+ \fi%
+ }
+ \state{final}
+ {
+ \pgfpathlineto{\pgfpoint{\pgfsnakeremainingdistance}{0pt}}
+ }
+}
+\begin{tikzpicture}[snake=complicated example snake]
+ \draw[snake] (0,0) -- (3,0);
+ \fill[red!50,snake,rounded corners=2pt] (.5,-2) -- ++(2.5,-2.5)
+ [snake=none] -- ++(0,-.5) -| (0,-2) -- cycle;
+\end{tikzpicture}
+\end{codeexample}
+\end{command}
+
+
+\subsubsection{Predefined Snakes}
+
+Only two very simple and basic snakes are predefined when you load
+\pgfname. For more interesting snakes you can use the package
+|pgflibrarysnakes|.
+
+\begin{snake}{lineto}
+ This most trivial of all snakes is simply a straight line. This
+ snake is typically not used in a ``stand alone'' fashion. Rather, it
+ is useful as a ``subsnake'' of the |\pgfsnakesto| command.
+\end{snake}
+
+\begin{snake}{moveto}
+ Arguably, this snake is even simpler than the previous snake. This
+ snake consists of a simple move-to operation. Like the |lineto|
+ snake, it is useful as a ``subsnake'' of the |\pgfsnakesto|
+ command.
+\end{snake}
+
+
+
+\subsection{Using Snakes}
+
+Three commands can be used to use a snake.
+
+\begin{command}{\pgfpathsnakealongvector\marg{snake}\marg{length}\marg{vector}}
+ This command will append the \meta{snake} to the current path. The
+ length of the snake is given by \meta{length}. The \meta{vector}
+ should be a normalizes vector (a vector having length |1pt|)
+ pointing in the direction in which the snake should grow.
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \pgfpathmoveto{\pgfpoint{1cm}{1cm}}
+ \pgfpathsnakealongvector{zigzag}{2cm}{\pgfpointpolar{30}{1pt}}
+ \pgfusepath{stroke}
+\end{tikzpicture}
+\end{codeexample}
+\end{command}
+
+\begin{command}{\pgfpathsnakesto\marg{snake list}\marg{target}}
+ This command will append the snakes in the \meta{snake list} to the
+ current path such that it ends at \meta{point}. This command calls the previous
+ one (repeatedly, possibly) after having computed the distance from
+ the current point to \meta{target} and normalized the vector
+ connecting the current point to the target.
+
+ The \meta{snake list} is a comma-separated list of pairs consisting
+ of a snake name in curly braces and a distance in curly braces. For
+ example, a snake list might be |{lineto}{1cm},{moveto}{2cm}|. This
+ is interpreted as follows: Use a |lineto| snake for the first
+ centimeter of the way to the \meta{target}, then use the |moveto|
+ snake for the next two centimeters.
+
+ No attempt is made to check or ensure that the distances of the
+ ``subsnakes' add up to the distnace from the current point to the
+ \meta{target}. However, it is possible to refer to this distance
+ inside the \meta{snake list}: While the snake list is processed, the
+ two \TeX-dimensions |\pgfsnakeremainingdistance| and
+ |\pgfsnakecompleteddistance| will be set to the correct values. For
+ example, consider the example from a above, consisting of a |lineto|
+ and a |moveto| snake. Suppose the distance to \meta{target} where
+ 5cm. Then, when the length of the first subsnake is computed, the
+ remaining distance willbe set to 5cm and the completed distance to
+ 0cm. When the length of the second subsnake is computed, the
+ remaining distance wil be 4cm and the completed distance will be
+ 1cm.
+
+ Here are some useful examles: |{zigzag}{\pgfsnakeremainingdistance}|
+ is a \meta{snake list} that consists only of a |zigzag| snake whose
+ length is the total distance from the current point to the
+ \meta{target}. Next, to get a snake that is a |zigzag| snake that is
+ preceeded and succeeded by 3mm of |lineto|, you can use the
+ following:
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines](0,0) grid (3,2);
+ \pgfpathmoveto{\pgfpointorigin}
+ \pgfpathsnakesto{%
+ {lineto}{3mm},%
+ {zigzag}{\pgfsnakeremainingdistance-6mm},%
+ {lineto}{3mm}}
+ {\pgfpoint{3cm}{2cm}}
+ \pgfusepath{stroke}
+\end{tikzpicture}
+\end{codeexample}
+
+ Note that the computation of the distance may be imprecise. In
+ general, the placement precision of the snakes will not be perfect.
+\end{command}
+
+\begin{command}{\pgfpathsnaketo\marg{snake}\marg{target}}
+ This command is just a shortcut for calling |\pgfpathsnakesto| for a
+ single snake whose length is |\pgfsnakeremainingdistance|.
+\begin{codeexample}[]
+\begin{tikzpicture}
+ \draw[help lines] (0,0) grid (3,2);
+ \pgfpathmoveto{\pgfpoint{1cm}{1cm}}
+ \pgfpathsnaketo{zigzag}{\pgfpoint{3cm}{2cm}}
+ \pgfusepath{stroke}
+\end{tikzpicture}
+\end{codeexample}
+\end{command}
+
+As was already mentioned, when each segment of the snake is added to
+the path, an appropriate coordinate transformation will be in
+force. It is sometimes useful to add an additional transformation
+locally. For example, by reflecting everything around the $x$-axis
+right before each segment is added, the snake will effectively be
+mirrored along the path. The following command allows you to install
+such a ``last minute transformation.''
+
+\begin{command}{\pgfsetsnakesegmenttransformation\marg{code}}
+ The \meta{code} will be executed at the very beginning of each
+ segment. Normally, this be a transformation command that changes the
+ $y$-axis in some way.
+\end{command}
+
+
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "~/texmf/tex/generic/pgf/doc/pgf/version-for-pdftex/en/pgfmanual"
+%%% End: