20 Specifying Coordinates

20.1 Overview

Most PGF commands expect you to provide the coordinates of a point (also called 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.

20.2 Basic Coordinate Commands

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

\pgfpoint{<x coordinate>}{<y coordinate>}

Yields a point location. The coordinates are given as TEX dimensions.

 

SVG-Viewer needed.

 

\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}

\pgfpointorigin

Yields the origin. Same as \pgfpoint{0pt}{0pt}.

\pgfpointpolar{<degree>}{<radius>}

Yields a point location given in polar coordinates. You can specify the angle only in degrees, radians are not supported, currently.

 

SVG-Viewer needed.

 

\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}

20.3 Coordinates in the Xy- and Xyz-Coordinate Systems

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.”

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.

\pgfpointxy{<sx>}{<sy>}

Yields a point that is situated at sx times the x-vector plus sy times the y-vector.

 

SVG-Viewer needed.

 

\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathmoveto{\pgfpointxy{1}{0}}
  \pgfpathlineto{\pgfpointxy{2}{2}}
  \pgfusepath{stroke}
\end{tikzpicture}

\pgfpointxyz{<sx>}{<sy>}{<sz>}

Yields a point that is situated at sx times the x-vector plus sy times the y-vector plus sz times the z-vector.

 

SVG-Viewer needed.

 

\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}

\pgfsetxvec{<point>}

Sets that current x-vector for usage in the xyz-coordinate system.

Example:

 

SVG-Viewer needed.

 

\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}

\pgfsetyvec{<point>}

Works like \pgfsetyvec.

\pgfsetzvec{<point>}

Works like \pgfsetzvec.

20.4 Building Coordinates From Other Coordinates

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

20.4.1 Basic Manipulations of Coordinates

\pgfpointadd{<v1>}{<v2>}

Returns the sum vector <v1> + <v2>.

 

SVG-Viewer needed.

 

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

\pgfpointscale{<factor>}{<coordinate>}

Returns the vector <factor><coordinate>.

 

SVG-Viewer needed.

 

\begin{tikzpicture}
  \draw[help lines] (0,0) grid (3,2);
  \pgfpathcircle{\pgfpointscale{1.5}{\pgfpoint{1cm}{0cm}}}{2pt}
  \pgfusepath{fill}
\end{tikzpicture}

\pgfpointdiff{<start>}{<end>}

Returns the difference vector <end>-<start>.

 

SVG-Viewer needed.

 

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

\pgfpointnormalised{<point>}

This command returns a normalized version of <point>, that is, a vector of length 1pt pointing in the direction of <point>. If <point> is the 0-vector or extremely short, a vector of length 1pt pointing upwards is returned.

This command is 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 precisely point in the direction of <point> due to the fact that the polar tables are accurate only up to one degree. Normally, this is not a problem.

 

SVG-Viewer needed.

 

\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}

20.4.2 Points Traveling along Lines and Curves

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.

\pgfpointlineattime{<time t>}{<point p>}{<point q>}

Yields a point that is the tth fraction between p and q, that is, p + t(q - p). For t = 1/2 this is the middle of p and q.

 

SVG-Viewer needed.

 

\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}

\pgfpointlineatdistance{<distance>}{<start point>}{<end point>}

Yields a point that is located <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 <distance> steps from <start point> towards <end point>.

Example:

 

SVG-Viewer needed.

 

\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}

\pgfpointcurveattime{<time t>}{<point p>}{<point s1>}{<point s2>}{<point q>}

Yields a point that is on the Bézier curve from p to q with the support points s1 and s2. The time t is used to determine the location, where t = 0 yields p and t = 1 yields q.

 

SVG-Viewer needed.

 

\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}

20.4.3 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.

\pgfpointborderrectangle{<direction point>}{<corner>}

This command returns a point that lies on the intersection of a line starting at the origin and going towards the point <direction point> and a rectangle whose center is in the origin and whose upper right corner is at <corner>.

The <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.

 

SVG-Viewer needed.

 

\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}

\pgfpointborderellipse{<direction point>}{<corner>}

This command works like the corresponding command for rectangles, only this time the <corner> is the corner of the bounding rectangle of an ellipse.

 

SVG-Viewer needed.

 

\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}

20.4.4 Points on the Intersection of Lines

\pgfpointintersectionoflines{<p>}{<q>}{<s>}{<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.

 

SVG-Viewer needed.

 

\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}

20.5 Extracting Coordinates

There are two commands that can be used to “extract” the x- or y-coordinate of a coordinate.

\pgfextractx{<dimension>}{<point>}

Sets the TEX-<dimension> to the x-coordinate of the point.


\newdimen\mydim
\pgfextractx{\mydim}{\pgfpoint{2cm}{4pt}}
%% \mydim is now 2cm

\pgfextracty{<dimension>}{<point>}

Like \pgfextractx, except for the y-coordinate.

20.6 Internals of How Point Commands Work

As a normal user of PGF 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:


...
{ % 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

Since this situation arises very often, the macro \pgf@process can be used to perform the above code:

\pgf@process{<code>}

Executes the <code> in a scope and then makes \pgf@x and \pgf@y global.

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:


\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}