\documentclass[a4paper]{article}
%\VignetteIndexEntry{Non-finite values}
%\VignettePackage{grid}
\newcommand{\grid}{{\tt grid}}
\newcommand{\R}{{\tt R}}
\setlength{\parindent}{0in}
\setlength{\parskip}{.1in}
\setlength{\textwidth}{140mm}
\setlength{\oddsidemargin}{10mm}
\title{How \grid{} Responds to Non-Finite Values}
\author{Paul Murrell}

\begin{document}
\maketitle

<<echo=FALSE, results=hide>>=
library(grDevices)
library(grid)
ps.options(pointsize=12)
options(width=60)

@
It is possible to include non-finite values,
{\tt NA}, {\tt NaN}, {\tt Inf}, and {\tt -Inf},
in specifications of locations and sizes in
\grid{} functions.  This document describes how
\grid{} responds to non-finite values in different cases.

{\bf viewports} {~} \\
Non-finite values are not permitted in the location, size, or
scales of a viewport.  Viewport scales are checked
when a viewport is created.  It is very hard to be certain that
locations and sizes are not non-finite when the viewport is created
so this is only checked
when the viewport is pushed.
Non-finite values result in error messages.

{\bf lines},
{\bf segments},
{\bf rectangles},
{\bf text},
{\bf points},
{\bf circles} {~} \\
For all of these primitives, non-finite values for locations or
sizes result in the corresponding primitive not being drawn.
The following image provides a simple demonstration.  Each primitive
is drawn at seven x-locations, with the fourth location made non-finite
 (as indicated by a grey {\tt "NA"}).

<<prim1, echo=FALSE, fig=TRUE, results=hide, width=4, height=2, include=FALSE>>=
pushViewport(viewport(layout=grid.layout(1, 2,
  widths=unit(c(1, 1), c("inches", "null")))))
grid.rect(gp=gpar(col="grey"))
pushViewport(viewport(layout.pos.col=1))
grid.text(c("segments", "text", "lines", "rectangles",
  "circles", "points"),
  x=1, just="right", y=c(0.75, 6:2/10), gp=gpar(col="grey"))
popViewport()
pushViewport(viewport(layout.pos.col=2))
x <- 1:7/8
x[4] <- NA
grid.lines(x, 0.5)
grid.text(letters[1:5], x, 0.6)
grid.segments(x, 0.7, x, 0.8)
grid.points(x, rep(0.2, 7))
grid.rect(x, 0.4, 0.02, 0.02)
grid.circle(x, 0.3, 0.02)
grid.text("NA", 0.5, 2:8/10, gp=gpar(col="grey"))
popViewport(2)

@

\vspace{.5in}
\includegraphics{nonfinite-prim1}

\newpage

{\bf lineTo} {~} \\
A line segment is only drawn if the previous location and the
new location are both not non-finite.

{\bf polygon} {~} \\
A non-finite value breaks the polygon into two separate polygons.
NOTE that this break happens within the current polygon as specified
by the {\tt id} argument.  All polygons with the same {\tt id}
receive the same {\tt gp} settings.

{\bf arrows} {~} \\
An arrow head is only drawn if the first or last line segment is
drawn.

The following image demonstrates the behaviour of these primitives
where x- and y-locations are seven equally-spaced locations around
the perimeter of a circle.  In the top-left figure, all locations
are not non-finite.  In each of the other figures, two locations have
been made non-finite (indicated in each case by grey text).

<<prim2, echo=FALSE, fig=TRUE, results=hide, include=FALSE>>=
n <- 7
primtest2 <- function(nas, na) {
  t <- seq(0, 2*pi, length=n+1)[-(n+1)]
  y <- 0.5 + 0.4*sin(t)
  x <- 0.5 + 0.4*cos(t)
  if (any(nas))
    grid.text(paste("NA", (1:n)[nas], sep=""),
              x[nas], y[nas], gp=gpar(col="grey"))
  x[nas] <- na
  y[nas] <- na
  grid.move.to(x[1], y[1])
  for (i in 2:n) {
    grid.line.to(x[i], y[i], gp=gpar(lty="dashed", lwd=5))
  }
  grid.polygon(x, y, gp=gpar(fill="grey", col=NULL))
  grid.lines(x, y, arrow=arrow())
}
celltest <- function(r, c, nas, na) {
  pushViewport(viewport(layout.pos.col=c,
                        layout.pos.row=r))
  primtest2(nas, na)
  grid.rect(gp=gpar(col="grey"))
  popViewport()
}
cellnas <- function(i) {
  temp <- rep(FALSE, n)
  temp[i] <- TRUE
  temp[n-3+i] <- TRUE
  temp
}
pushViewport(viewport(layout=grid.layout(2, 2)))
celltest(1, 1, rep(FALSE, n), NA)
celltest(1, 2, cellnas(1), NA)
celltest(2, 1, cellnas(2), NA)
celltest(2, 2, cellnas(3), NA)
popViewport()


@

\vspace{.5in}
\includegraphics{nonfinite-prim2}

% Start a new page
% Not echoed, not evaluated
% ONLY here for checkVignettes so that all output doesn't
% end up on one enormous page

<<eval=FALSE, echo=FALSE>>=
grid.newpage()

@
\end{document}

