% Copyright 2006 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{Specifying Coordinates}

\label{section-points}

\subsection{Overview}

Most \pgfname\ commands expect you to provide the coordinates of a
\emph{point} (also called \emph{coordinate}) inside your
picture. Points are always ``local'' to your picture, that is, they
never refer to an absolute position on the page, but to a position
inside the current |{pgfpicture}| environment. To specify a coordinate
you can use commands that start with |\pgfpoint|.


\subsection{Basic Coordinate Commands}

The following commands are the most basic  for specifying a
coordinate.

\begin{command}{\pgfpoint\marg{x coordinate}\marg{y coordinate}}
  Yields a point location. The coordinates are given as \TeX\
  dimensions.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathcircle{\pgfpoint{1cm}{1cm}} {2pt}
  \pgfpathcircle{\pgfpoint{2cm}{5pt}} {2pt}
  \pgfpathcircle{\pgfpoint{0pt}{.5in}}{2pt}
  \pgfusepath{fill}
\end{tikzpicture}   
\end{codeexample}
\end{command}

\begin{command}{\pgfpointorigin}
  Yields the origin. Same as |\pgfpoint{0pt}{0pt}|.
\end{command}

\begin{command}{\pgfpointpolar\marg{degree}{\ttfamily\char`\{}\meta{radius}\opt{|/|\meta{y-radius}}{\ttfamily\char`\}}}
  Yields a point location given in polar coordinates. You can specify
  the angle only in degrees, radians are not supported, currently.

  If the optional \meta{y-radius} is given, the polar coordinate is
  actually a coordinate on an ellipse whose $x$-radius is given by
  \meta{radius} and whose $y$-radius is given by \meta{y-radius}.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);

  \foreach \angle in {0,10,...,90}
    {\pgfpathcircle{\pgfpointpolar{\angle}{1cm}}{2pt}}
  \pgfusepath{fill}
\end{tikzpicture}
\end{codeexample}
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);

  \foreach \angle in {0,10,...,90}
    {\pgfpathcircle{\pgfpointpolar{\angle}{1cm/2cm}}{2pt}}
  \pgfusepath{fill}
\end{tikzpicture}   
\end{codeexample}
\end{command}



\subsection{Coordinates in the XY-Coordinate System}

Coordinates can also be specified as multiples of an $x$-vector and a
$y$-vector. Normally, the $x$-vector points one centimeter in the
$x$-direction and the $y$-vector points one centimeter in the
$y$-direction, but using the commands |\pgfsetxvec| and
|\pgfsetyvec| they can be changed. Note that the $x$- and
$y$-vector do not necessarily point ``horizontally'' and
``vertically.''

\begin{command}{\pgfpointxy\marg{$s_x$}\marg{$s_y$}}
  Yields a point that is situated at $s_x$ times the
  $x$-vector plus $s_y$ times the $y$-vector.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathmoveto{\pgfpointxy{1}{0}}
  \pgfpathlineto{\pgfpointxy{2}{2}}
  \pgfusepath{stroke}
\end{tikzpicture}   
\end{codeexample}
\end{command}


\begin{command}{\pgfsetxvec\marg{point}}
  Sets that current $x$-vector for usage in the $xyz$-coordinate
  system. 
  \example
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  
  \pgfpathmoveto{\pgfpointxy{1}{0}}
  \pgfpathlineto{\pgfpointxy{2}{2}}
  \pgfusepath{stroke}

  \color{red}
  \pgfsetxvec{\pgfpoint{0.75cm}{0cm}}
  \pgfpathmoveto{\pgfpointxy{1}{0}}
  \pgfpathlineto{\pgfpointxy{2}{2}}
  \pgfusepath{stroke}
\end{tikzpicture}   
\end{codeexample}
\end{command}

\begin{command}{\pgfsetyvec\marg{point}}
  Works like |\pgfsetyvec|.
\end{command}



\begin{command}{\pgfpointpolarxy\marg{degree}{\ttfamily\char`\{}\meta{radius}\opt{|/|\meta{y-radius}}{\ttfamily\char`\}}}
  This command is similar to the |\pgfpointpolar| command, but the
  \meta{radius} is now a factor to be interpreted in the
  $xy$-coordinate system. This means that a degree of |0| is the same
  as the $x$-vector of the $xy$-coordinate  system times \meta{radius}
  and a degree of |90| is the $y$-vecotr times \meta{radius}. As for
  |\pgfpointpolar|, a \meta{radius} can also be a pair separated by a
  slash. In this case, the $x$- and $y$-vectors are multiplied by
  different factors.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);

  \begin{scope}[x={(1cm,-5mm)},y=1.5cm]
    \foreach \angle in {0,10,...,90}
      {\pgfpathcircle{\pgfpointpolarxy{\angle}{1}}{2pt}}
    \pgfusepath{fill}
  \end{scope}
\end{tikzpicture}
\end{codeexample}
\end{command}



\subsection{Three Dimensional Coordinates}

It is also possible to specify a point as a multiple of three vectors,
the $x$-, $y$-, and $z$-vector. This is useful for creating simple
three dimensional graphics.

\begin{command}{\pgfpointxyz\marg{$s_x$}\marg{$s_y$}\marg{$s_z$}}
  Yields a point that is situated at $s_x$ times the
  $x$-vector plus $s_y$ times the $y$-vector plus  $s_z$ times the
  $z$-vector.
\begin{codeexample}[]
\begin{pgfpicture}
  \pgfsetarrowsend{to}
  
  \pgfpathmoveto{\pgfpointorigin}
  \pgfpathlineto{\pgfpointxyz{0}{0}{1}}
  \pgfusepath{stroke}
  \pgfpathmoveto{\pgfpointorigin}
  \pgfpathlineto{\pgfpointxyz{0}{1}{0}}
  \pgfusepath{stroke}
  \pgfpathmoveto{\pgfpointorigin}
  \pgfpathlineto{\pgfpointxyz{1}{0}{0}}
  \pgfusepath{stroke}
\end{pgfpicture}
\end{codeexample}
\end{command}

\begin{command}{\pgfsetzvec\marg{point}}
  Works like |\pgfsetzvec|.
\end{command}

Inside the $xyz$-coordinate system, you can also specify points
using spherical and cylindrical coordinates.


\begin{command}{\pgfpointcylindrical\marg{degree}\marg{radius}\marg{height}}
  This command yields the same as
\begin{verbatim}
\pgfpointadd{\pgfpointpolarxy{degree}{radius}}{\pgfpointxyz{0}{0}{height}}
\end{verbatim}
\begin{codeexample}[]
\begin{tikzpicture}
  \draw [->] (0,0) -- (1,0,0) node [right] {$x$};
  \draw [->] (0,0) -- (0,1,0) node [above] {$y$};
  \draw [->] (0,0) -- (0,0,1) node [below left] {$z$};

  \pgfpathcircle{\pgfpointcylindrical{80}{1}{.5}}{2pt}
  \pgfusepath{fill}

  \draw[red] (0,0) -- (0,0,.5) -- +(80:1);
\end{tikzpicture}
\end{codeexample}
\end{command}

\begin{command}{\pgfpointspherical\marg{longitude}\marg{latitude}\marg{radius}}
  This command yields a point ``on the surface of the earth''
  specified by the \meta{longitude} and the \marg{latitude}. The
  radius of the earth is given by \meta{radius}. The equator lies in
  the $xy$-plane.
\begin{codeexample}[]
\begin{tikzpicture}
  \pgfsetfillcolor{lightgray}

  \foreach \latitude in {-90,-75,...,30}
  {  
    \foreach \longitude in {0,20,...,360}
    {
      \pgfpathmoveto{\pgfpointspherical{\longitude}{\latitude}{1}}
      \pgfpathlineto{\pgfpointspherical{\longitude+20}{\latitude}{1}}
      \pgfpathlineto{\pgfpointspherical{\longitude+20}{\latitude+15}{1}}
      \pgfpathlineto{\pgfpointspherical{\longitude}{\latitude+15}{1}}
      \pgfpathclose
    }
    \pgfusepath{fill,stroke}
  }
\end{tikzpicture}
\end{codeexample}
\end{command}



\subsection{Building Coordinates From Other Coordinates}

Many commands allow you to construct a coordinate in terms of other
coordinates.


\subsubsection{Basic Manipulations of Coordinates}

\begin{command}{\pgfpointadd\marg{$v_1$}\marg{$v_2$}}
  Returns the sum vector $\meta{$v_1$} + \meta{$v_2$}$.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathcircle{\pgfpointadd{\pgfpoint{1cm}{0cm}}{\pgfpoint{1cm}{1cm}}}{2pt}
  \pgfusepath{fill} 
\end{tikzpicture}
\end{codeexample}
\end{command}

\begin{command}{\pgfpointscale\marg{factor}\marg{coordinate}}
  Returns the vector $\meta{factor}\meta{coordinate}$.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathcircle{\pgfpointscale{1.5}{\pgfpoint{1cm}{0cm}}}{2pt}
  \pgfusepath{fill} 
\end{tikzpicture}
\end{codeexample}
\end{command}

\begin{command}{\pgfpointdiff\marg{start}\marg{end}}
  Returns the difference vector $\meta{end} - \meta{start}$.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathcircle{\pgfpointdiff{\pgfpoint{1cm}{0cm}}{\pgfpoint{1cm}{1cm}}}{2pt}
  \pgfusepath{fill} 
\end{tikzpicture}
\end{codeexample}
\end{command}


\begin{command}{\pgfpointnormalised\marg{point}}
  This command returns a normalized version of \meta{point}, that is,
  a vector of length 1pt pointing in the direction of \meta{point}. If
  \meta{point} is the $0$-vector or extremely short, a vector of
  length 1pt pointing upwards is returned.

  This command is \emph{not} implemented by calculating the length of
  the vector, but rather by calculating the angle of the vector and
  then using (something equivalent to) the |\pgfpointpolar|
  command. This ensures that the point will really have length 1pt,
  but it is not guaranteed that the vector will \emph{precisely} point
  in the direction of \meta{point} due to the fact that the polar
  tables are accurate only up to one degree. Normally, this is not a
  problem.
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathcircle{\pgfpoint{2cm}{1cm}}{2pt}
  \pgfpathcircle{\pgfpointscale{20}
    {\pgfpointnormalised{\pgfpoint{2cm}{1cm}}}}{2pt}
  \pgfusepath{fill} 
\end{tikzpicture}
\end{codeexample}  
\end{command}


\subsubsection{Points Traveling along Lines and Curves}

\label{section-pointsattime}

The commands in this section allow you to specify points on a line or
a curve. Imaging a point ``traveling'' along a curve from some point
$p$ to another point $q$. At time $t=0$ the point is at $p$ and at
time $t=1$ it is at $q$ and at time, say, $t=1/2$ it is ``somewhere in
the middle.'' The exact location at time $t=1/2$ will not necessarily
be the ``halfway point,'' that is, the point whose distance on the
curve from $p$ and $q$ is equal. Rather, the exact location will
depend on the ``speed'' at which the point is traveling, which in
turn depends on the lengths of the support vectors in a complicated
manner. If you are interested in the details, please see a good book
on Bézier curves.



\begin{command}{\pgfpointlineattime\marg{time $t$}\marg{point $p$}\marg{point $q$}}
  Yields a point that is the $t$th fraction between $p$
  and~$q$, that is, $p + t(q-p)$. For $t=1/2$ this is the middle of
  $p$ and $q$.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathmoveto{\pgfpointorigin}
  \pgfpathlineto{\pgfpoint{2cm}{2cm}}
  \pgfusepath{stroke}
  \foreach \t in {0,0.25,...,1.25}
    {\pgftext[at=
      \pgfpointlineattime{\t}{\pgfpointorigin}{\pgfpoint{2cm}{2cm}}]{\t}}
\end{tikzpicture}    
\end{codeexample}
\end{command}

\begin{command}{\pgfpointlineatdistance\marg{distance}\marg{start point}\marg{end point}}
  Yields a point that is located \meta{distance} many units removed
  from the start point in the direction of the end point. In other
  words, this is the point that results if we travel \meta{distance}
  steps from \meta{start point} towards \meta{end point}.
  \example
\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathmoveto{\pgfpointorigin}
  \pgfpathlineto{\pgfpoint{3cm}{2cm}}
  \pgfusepath{stroke}
  \foreach \d in {0pt,20pt,40pt,70pt}
    {\pgftext[at=
      \pgfpointlineatdistance{\d}{\pgfpointorigin}{\pgfpoint{3cm}{2cm}}]{\d}}
\end{tikzpicture}    
\end{codeexample}
\end{command}

\begin{command}{\pgfpointcurveattime\marg{time $t$}\marg{point
      $p$}\marg{point $s_1$}\marg{point $s_2$}\marg{point $q$}} 
  Yields a point that is on the Bézier curve from $p$ to $q$ with the
  support points $s_1$ and $s_2$. The time $t$ is used to determine
  the location, where $t=0$ yields $p$ and $t=1$ yields $q$.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathmoveto{\pgfpointorigin}
  \pgfpathcurveto
    {\pgfpoint{0cm}{2cm}}{\pgfpoint{0cm}{2cm}}{\pgfpoint{3cm}{2cm}}
  \pgfusepath{stroke}
  \foreach \t in {0,0.25,0.5,0.75,1}
    {\pgftext[at=\pgfpointcurveattime{\t}{\pgfpointorigin}
                                         {\pgfpoint{0cm}{2cm}}
                                         {\pgfpoint{0cm}{2cm}}
                                         {\pgfpoint{3cm}{2cm}}]{\t}}
\end{tikzpicture}    
\end{codeexample}
\end{command}

\subsubsection{Points on Borders of Objects}

The following commands are useful for specifying a point that lies on
the border of special shapes. They are used, for example, by the shape
mechanism to determine border points of shapes.

\begin{command}{\pgfpointborderrectangle\marg{direction point}\marg{corner}}
  This command returns a point that lies on the intersection of a line
  starting at the origin and going towards the point \meta{direction
    point} and a rectangle whose center is in the origin and whose
  upper right corner is at \meta{corner}.

  The \meta{direction point} should have length ``about 1pt,'' but it
  will be normalized automatically. Nevertheless, the ``nearer'' the
  length is to 1pt, the less rounding errors.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (2,1.5);
  \pgfpathrectanglecorners{\pgfpoint{-1cm}{-1.25cm}}{\pgfpoint{1cm}{1.25cm}}
  \pgfusepath{stroke}

  \pgfpathcircle{\pgfpoint{5pt}{5pt}}{2pt}
  \pgfpathcircle{\pgfpoint{-10pt}{5pt}}{2pt}
  \pgfusepath{fill}
  \color{red}
  \pgfpathcircle{\pgfpointborderrectangle
    {\pgfpoint{5pt}{5pt}}{\pgfpoint{1cm}{1.25cm}}}{2pt}
  \pgfpathcircle{\pgfpointborderrectangle
    {\pgfpoint{-10pt}{5pt}}{\pgfpoint{1cm}{1.25cm}}}{2pt}
  \pgfusepath{fill}
\end{tikzpicture}    
\end{codeexample}
\end{command}


\begin{command}{\pgfpointborderellipse\marg{direction point}\marg{corner}}
  This command works like the corresponding command for rectangles,
  only this time the \meta{corner} is the corner of the bounding
  rectangle of an ellipse.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (2,1.5);
  \pgfpathellipse{\pgfpointorigin}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1.25cm}}
  \pgfusepath{stroke}

  \pgfpathcircle{\pgfpoint{5pt}{5pt}}{2pt}
  \pgfpathcircle{\pgfpoint{-10pt}{5pt}}{2pt}
  \pgfusepath{fill}
  \color{red}
  \pgfpathcircle{\pgfpointborderellipse
    {\pgfpoint{5pt}{5pt}}{\pgfpoint{1cm}{1.25cm}}}{2pt}
  \pgfpathcircle{\pgfpointborderellipse
    {\pgfpoint{-10pt}{5pt}}{\pgfpoint{1cm}{1.25cm}}}{2pt}
  \pgfusepath{fill}
\end{tikzpicture}    
\end{codeexample}
\end{command}


\subsubsection{Points on the Intersection of Lines}


\begin{command}{\pgfpointintersectionoflines\marg{$p$}\marg{$q$}\marg{$s$}\marg{$t$}}
  This command returns the intersection of a line going through $p$
  and $q$ and a line going through $s$ and $t$. If the lines do not
  intersection, an arithmetic overflow will occur.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (2,2);
  \draw (.5,0) -- (2,2);
  \draw (1,2) -- (2,0);
  \pgfpathcircle{%
    \pgfpointintersectionoflines
      {\pgfpointxy{.5}{0}}{\pgfpointxy{2}{2}}
      {\pgfpointxy{1}{2}}{\pgfpointxy{2}{0}}}
    {2pt}
  \pgfusepath{stroke}
\end{tikzpicture}    
\end{codeexample}
\end{command}


\subsubsection{Points on the Intersection of Two Circles}


\begin{command}{\pgfpointintersectionofcircles\marg{$p_1$}\marg{$p_2$}\marg{$r_1$}\marg{$r_2$}\marg{solution}}
  This command returns the intersection of the two circles centered at
  $p_1$ and $p_2$ with radii $r_1$ and $r_2$. If \meta{solution} is
  |1|, the first intersection is returned, otherwise the second one is
  returned.

\begin{codeexample}[]
\begin{tikzpicture}
  \draw[help lines] (0,0) grid (2,2);
  \draw (0.5,0) circle (1);
  \draw (1.5,1) circle (.8);
  \pgfpathcircle{%
    \pgfpointintersectionofcircles
      {\pgfpointxy{.5}{0}}{\pgfpointxy{1.5}{1}}
      {1cm}{0.8cm}{1}}
    {2pt}
  \pgfusepath{stroke}
\end{tikzpicture}    
\end{codeexample}
\end{command}


\subsection{Extracting Coordinates}

There are two commands that can be used to ``extract'' the $x$- or
$y$-coordinate of a coordinate. 

\begin{command}{\pgfextractx\marg{dimension}\marg{point}}
  Sets the \TeX-\meta{dimension} to the $x$-coordinate of the point.

\begin{codeexample}[code only]
\newdimen\mydim
\pgfextractx{\mydim}{\pgfpoint{2cm}{4pt}}
%% \mydim is now 2cm
\end{codeexample}
\end{command}

\begin{command}{\pgfextracty\marg{dimension}\marg{point}}
  Like |\pgfextractx|, except for the $y$-coordinate.
\end{command}




\subsection{Internals of How Point Commands Work}

As a normal user of \pgfname\ you do not need to read this section. It
is relevant only if you need to understand how the point commands work
internally. 

When a command like |\pgfpoint{1cm}{2pt}| is called, all that happens
is that the two \TeX-dimension variables |\pgf@x| and |\pgf@y| are set
to |1cm| and |2pt|, respectively. A command like |\pgfpathmoveto| that
takes a coordinate as parameter will just execute this parameter and
then use the values of |\pgf@x| and |\pgf@y| as the coordinates to
which it will move the pen on the current path.

since commands like |\pgfpointnormalised| modify other variables
besides |\pgf@x| and |\pgf@y| during the computation of the final values of
|\pgf@x| and |\pgf@y|, it is a good idea to enclose a call of a
command like |\pgfpoint| in a \TeX-scope and then make the changes of
|\pgf@x| and |\pgf@y| global as in the following example:
\begin{codeexample}[code only]
...
{ % open scope
  \pgfpointnormalised{\pgfpoint{1cm}{1cm}}
  \global\pgf@x=\pgf@x % make the change of \pgf@x persist past the scope
  \global\pgf@y=\pgf@y % make the change of \pgf@y persist past the scope
}
% \pgf@x and \pgf@y are now set correctly, all other variables are
% unchanged 
\end{codeexample}

\makeatletter
Since this situation arises very often, the macro |\pgf@process| can
be used to perform the above code:
\begin{command}{\pgf@process\marg{code}}
  Executes the \meta{code} in a scope and then makes |\pgf@x| and
  |\pgf@y| global.
\end{command}

Note that this macro is used often internally. For this reason, it is
not a good idea to keep anything important in the variables |\pgf@x|
and |\pgf@y| since they will be overwritten and changed
frequently. Instead, intermediate values can ge stored in the
\TeX-dimensions |\pgf@xa|, |\pgf@xb|, |\pgf@xc| and their
|y|-counterparts |\pgf@ya|, |\pgf@yb|, |pgf@yc|. For example, here is
the code of the command |\pgfpointadd|:
\begin{codeexample}[code only]
\def\pgfpointadd#1#2{%
  \pgf@process{#1}%
  \pgf@xa=\pgf@x%
  \pgf@ya=\pgf@y%
  \pgf@process{#2}%
  \advance\pgf@x by\pgf@xa%
  \advance\pgf@y by\pgf@ya}
\end{codeexample}



%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "pgfmanual"
%%% End: 
