# persp3d: Surface plots In rgl: 3D Visualization Using OpenGL

## Description

This function draws plots of surfaces in 3-space. `persp3d` is a generic function.

## Usage

 ```1 2 3 4 5 6 7``` ```persp3d(x, ...) ## Default S3 method: persp3d(x = seq(0, 1, len = nrow(z)), y = seq(0, 1, len = ncol(z)), z, xlim = NULL, ylim = NULL, zlim = NULL, xlab = NULL, ylab = NULL, zlab = NULL, add = FALSE, aspect = !add, forceClipregion = FALSE, ...) ```

## Arguments

 `x, y, z` points to plot on surface. See Details below. `xlim, ylim, zlim` x-, y- and z-limits. If present, the plot is clipped to this region. `xlab, ylab, zlab` titles for the axes. N.B. These must be character strings; expressions are not accepted. Numbers will be coerced to character strings. `add` whether to add the points to an existing plot. `aspect` either a logical indicating whether to adjust the aspect ratio, or a new ratio. `forceClipregion` force a clipping region to be used, whether or not limits are given. `...` additional material parameters to be passed to `surface3d` and `decorate3d`.

## Details

The default method plots a surface defined as a grid of `(x,y,z)` locations in space. The grid may be specified in several ways:

• As with `persp`, `x` and `y` may be given as vectors in ascending order, with `z` given as a matrix. There should be one `x` value for each row of `z` and one `y` value for each column. The surface drawn will have `x` constant across rows and `y` constant across columns. This is the most convenient format when `z` is a function of `x` and `y` which are measured on a regular grid.

• `x` and `y` may also be given as matrices, in which case they should have the same dimensions as `z`. The surface will combine corresponding points in each matrix into locations `(x,y,z)` and draw the surface through those. This allows general surfaces to be drawn, as in the example of a spherical Earth shown below.

• If `x` is a `list`, its components `x\$x`, `x\$y` and `x\$z` are used for `x`, `y` and `z` respectively, though an explicitly specified `z` value will have priority.

One difference from `persp` is that colors are specified on each vertex, rather than on each facet of the surface. To emulate the `persp` color handling, you need to do the following. First, convert the color vector to an `(nx - 1)` by `(ny - 1)` matrix; then add an extra row before row 1, and an extra column after the last column, to convert it to `nx` by `ny`. (These extra colors will not be used). For example, `col <- rbind(1, cbind(matrix(col, nx - 1, ny - 1), 1))`. Finally, call `persp3d` with material property `smooth = FALSE`.

See the “Clipping” section in `plot3d` for more details on `xlim, ylim, zlim` and `forceClipregion`.

## Value

This function is called for the side effect of drawing the plot. A vector of shape IDs is returned invisibly.

## Author(s)

Duncan Murdoch

`plot3d`, `persp`. There is a `persp3d.function` method for drawing functions, and `persp3d.deldir` can be used to draw surfaces defined by an irregular collection of points. A formula method `persp3d.formula` draws surfaces using this method.
The `surface3d` function is used to draw the surface without the axes etc.
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71``` ```# (1) The Obligatory Mathematical surface. # Rotated sinc function. x <- seq(-10, 10, length = 30) y <- x f <- function(x, y) { r <- sqrt(x^2 + y^2); 10 * sin(r)/r } z <- outer(x, y, f) z[is.na(z)] <- 1 open3d() # Draw the surface twice: the first draws the solid part, # the second draws the grid. Offset the first so it doesn't # obscure the lines. persp3d(x, y, z, aspect = c(1, 1, 0.5), col = "lightblue", xlab = "X", ylab = "Y", zlab = "Sinc( r )", polygon_offset = 1) persp3d(x, y, z, front = "lines", back = "lines", lit = FALSE, add = TRUE) highlevel() # trigger the plot # (2) Add to existing persp plot: xE <- c(-10, 10); xy <- expand.grid(xE, xE) points3d(xy[, 1], xy[, 2], 6, col = "red") lines3d(x, y = 10, z = 6 + sin(x), col = "green") phi <- seq(0, 2*pi, len = 201) r1 <- 7.725 # radius of 2nd maximum xr <- r1 * cos(phi) yr <- r1 * sin(phi) lines3d(xr, yr, f(xr, yr), col = "pink", lwd = 2) # (3) Visualizing a simple DEM model z <- 2 * volcano # Exaggerate the relief x <- 10 * (1:nrow(z)) # 10 meter spacing (S to N) y <- 10 * (1:ncol(z)) # 10 meter spacing (E to W) open3d() invisible(bg3d("slategray")) # suppress display material3d(col = "black") persp3d(x, y, z, col = "green3", aspect = "iso", axes = FALSE, box = FALSE) # (4) A globe lat <- matrix(seq(90, -90, len = 50)*pi/180, 50, 50, byrow = TRUE) long <- matrix(seq(-180, 180, len = 50)*pi/180, 50, 50) r <- 6378.1 # radius of Earth in km x <- r*cos(lat)*cos(long) y <- r*cos(lat)*sin(long) z <- r*sin(lat) open3d() persp3d(x, y, z, col = "white", texture = system.file("textures/worldsmall.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z) if (!rgl.useNULL()) play3d(spin3d(axis = c(0, 0, 1), rpm = 16), duration = 2.5) ## Not run: # This looks much better, but is slow because the texture is very big persp3d(x, y, z, col = "white", texture = system.file("textures/world.png", package = "rgl"), specular = "black", axes = FALSE, box = FALSE, xlab = "", ylab = "", zlab = "", normal_x = x, normal_y = y, normal_z = z) ## End(Not run) ```