## Warning: These vignettes assume pandoc version 1.13.1; older versions may
## give poor formatting.
The rgl
package is used to produce interactive 3-D plots. It contains
high-level graphics commands modelled loosely after classic R graphics,
but working in three dimensions. It also contains low level structure
inspired by the grid
package.
This document gives an overview. See the help pages for details.
This document was written in R Markdown, using the knitr
package
for production. It corresponds to rgl version
0.95.1367.
Most of the highlighted function names are HTML links. The internal links should work in any browser; the links to help topics should work if you view the vignette from within the R help system.
The document includes WebGL figures. To view these, you must have Javascript and WebGL enabled in your browser. Some older browsers may not support this – see http://get.webgl.org for tests and links to a discussion.
The plot3d
function
plots points within an rgl window. It is similar to the classic
plot
function,
but works in 3 dimensions.
For example
with(iris, plot3d(Sepal.Length, Sepal.Width, Petal.Length,
type="s", col=as.numeric(Species)))
You must enable Javascript to view this page properly.
can be used to plot three columns of the iris
data.
Allowed plot types include "p", "l", "h", "s"
,
meaning points, lines, segments from z=0, and spheres. There's
a lot of flexibility in specifying the coordinates; the
xyz.coords
function
from the grDevices
package is used for this.
You can use your mouse to manipulate the plot. The default is that if you click and hold with the left mouse button, you can rotate the plot by dragging it. The right mouse button is used to resize it, and the middle button changes the perspective in the point of view.
If you call plot3d
again, it will overwrite the current plot.
To open a new graphics window, use open3d
.
The other high level function is persp3d
to draw surfaces.
It is
similar to the classic persp
function, but with greater flexibility.
First, any of x
, y
or z
can be specified using matrices, not just z
. This allows parametric
surfaces to be plotted.
An even simpler specification is possible: x
may be a function,
in which case persp3d
will work out the grid itself. See
?persp3d.function
for details. For example, the MASS
package estimates
Gamma parameters using maximum likelihood in a
?MASS::fitdistr example.
Here we show the log likelihood surface.
library(MASS)
# from the fitdistr example
set.seed(123)
x <- rgamma(100, shape = 5, rate = 0.1)
fit <- fitdistr(x, dgamma, list(shape = 1, rate = 0.1), lower = 0.001)
loglik <- function(shape, rate) sum(dgamma(x, shape=shape, rate=rate,
log=TRUE))
loglik <- Vectorize(loglik)
xlim <- fit$estimate[1]+4*fit$sd[1]*c(-1,1)
ylim <- fit$estimate[2]+4*fit$sd[2]*c(-1,1)
mfrow3d(1, 2, sharedMouse = TRUE)
persp3d(loglik,
xlim = xlim, ylim = ylim,
n = 30)
zlim <- fit$loglik + c(-qchisq(0.99, 2)/2, 0)
next3d()
persp3d(loglik,
xlim = xlim, ylim = ylim, zlim = zlim,
n = 30)
You must enable Javascript to view this page properly.
On the left, the whole surface over a range of the parameters; on the right, only the parts of the surface with log likelihood values near the maximum.
Just as we have points
and
lines
in classic graphics, there are a number
of low level functions in rgl
to add graphical elements to the
currently active plot. The “primitive” shapes are those that are
native to OpenGL:
—————————– | ———–
points3d
: | adds points
lines3d
: | adds lines
segments3d
: | adds line segments
triangles3d
: | adds triangles
quads3d
: | adds quadrilaterals
Each of the above functions takes arguments x
, y
and z
, again
using xyz.coords
for flexibility.
They group successive entries
as necessary. For example, the triangles3d
function takes each
successive triple of points as the vertices of a triangle.
You can use these functions to annotate the current graph, or to construct a figure from scratch.
rgl
also has a number of objects which it constructs
from the primitives.
—————————– | ———–
text3d
, texts3d
: | adds text
abclines3d
: | adds straight lines to plot (like abline
)
planes3d
: | adds planes to plot
clipplanes3d
: | add clipping planes to plot
sprites3d
, particles3d
: | add sprites (fixed shapes or images) to plot
spheres3d
: | adds spheres
surface3d
, terrain3d
: | a surface (as used in persp3d
)
The following low-level functions control the look of the graph:
———————————— | ———–
axes3d
, axis3d
: | add axes to plot
box3d
, bbox3d
: | add box around plot
title3d
: | add title to plot
mtext3d
: | add marginal text to plot
decorate3d
: | add multiple “decorations” (scales, etc.) to plot
aspect3d
: | set the aspect ratios for the plot
bg3d
, bgplot3d
: | set the background of the scene
show2d
: | show a 2D plot or image in a 3D scene
legend3d
: | set a legend for the scene
grid3d
: | add a reference grid to a graph
For example, to plot three random triangles, one could use
triangles3d(cbind(x=rnorm(9), y=rnorm(9), z=rnorm(9)), col = "green")
decorate3d()
bg3d("lightgray")
aspect3d(1,1,1)
You must enable Javascript to view this page properly.
Besides the *3d
functions mentioned above, there are even lower-level
functions
rgl.primitive
, rgl.points
, rgl.linestrips
, rgl.lines
, rgl.triangles
, rgl.quads
, rgl.texts
, rgl.abclines
, rgl.planes
, rgl.bg
, rgl.clipplanes
, rgl.bbox
, rgl.spheres
, rgl.sprites
, rgl.surface
.
You should avoid using these functions, which do not
work well with the higher level *3d
functions. See the
?r3d help
topic for details.
In most scenes, objects are “lit”, meaning that their appearance depends on their position and orientation relative to lights in the scene. The lights themselves don't normally show up, but their effect on the objects does.
Use the light3d
function to
specify the position and characteristics of a light.
Lights may be infinitely distant, or may be embedded
within the scene. Their characteristics include
ambient
, diffuse
, and specular
components, all
defaulting to white. The ambient
component appears
the same from any direction. The diffuse
component
depends on the angle between the surface and the light,
while the specular
component also takes the viewer's
position into account.
The rgl.light
function is a lower-level
function with different defaults; users should normally
use light3d
.
The mental model used in rgl
is that the objects being shown
in scenes are physical objects in space, with material properties
that affect how light reflects from them (or is emitted by them).
These are mainly controlled by the material3d
function,
or by arguments to other functions that are passed to it.
The material properties that can be set by calls to material3d
are
described in detail in the
?material3d help page.
Here we give an overview.
Property | Default | Meaning |
---|---|---|
color | white | vector of surface colors to apply to successive vertices for diffuse light |
alpha | 1 | transparency: 0 is invisible, 1 is opaque |
lit | TRUE | whether lighting calculations should be done |
ambient | black | color in ambient light |
specular | white | color in specular light |
emission | black | color emitted by the surface |
shininess | 50 | controls the specular lighting: high values look shiny |
smooth | TRUE | whether shading should be interpolated between vertices |
texture | NULL | optional path to a “texture” bitmap to be displayed on the surface |
front, back | fill | should polygons be filled, or outlined? |
size | 3 | size of points in pixels |
lwd | 1 | width of lines in pixels |
Other properties include “texmipmap”, “texmagfilter”, “texminfilter”, “texenvmap”, “fog”, “point_antialias”, “line_antialias”, “depth_mask”, and “depth_test”; see the help page for details.
There is also an rgl.material
function that works
at a lower level; users should normally avoid it.
The par3d
function, modelled after the classic
graphics par
function, sets or reads
a variety of different rgl
internal
parameters. Some parameters are completely read-only; others are
fixed at the time the window is opened, and others may be changed
at any time.
Name | Changeable? | Description |
---|---|---|
antialias | fixed | Amount of hardware antialiasing |
cex | Default size for text | |
family | Device-independent font family name; see ?text3d | |
font | Integer font number | |
useFreeType | Should FreeType fonts be used if available? | |
fontname | read-only | System-dependent font name set by rglFonts |
FOV | Field of view, in degrees. Zero means isometric perspective | |
ignoreExtent | Should rgl ignore the size of new objects when computing the bounding box? |
|
skipRedraw | Should rgl suppress updates to the display? |
|
maxClipPlanes | read-only | How many clip planes can be defined? |
modelMatrix | read-only | The OpenGL ModelView matrix; partly set by view3d or the obsolete rgl.viewpoint |
projMatrix | read-only | The OpenGL Projection matrix |
bbox | read-only | Current bounding-box of the scene |
viewport | Dimensions in pixels of the scene within the window | |
windowRect | Dimensions in pixels of the window on the whole screen | |
listeners | Which subscenes respond to mouse actions in the current one | |
mouseMode | What the mouse buttons do. See "mouseMode" |
|
observer | read-only | The position of the observer; set by observer3d |
scale | Rescaling for each coordinate; see aspect3d |
|
zoom | Magnification of the scene |
The r3dDefaults
list and the getr3dDefaults
function control defaults in new windows opened by open3d
.
The function looks for the variable in the user's global environment,
and if not found there, finds the one in the rgl
namespace. This
allows the user to override the default settings for new windows.
Once found, the r3dDefaults
list provides initial values for par3d
parameters, as well as defaults for material3d
and bg3d
in components "material"
and "bg"
respectively.
rgl
includes a number of functions to construct and display
various solid shapes. These generate objects of class "shape3d"
,
"mesh3d"
or "shapelist3d"
. The details of the classes are
described below. We start with functions to generate them.
These functions generate specific shapes. Optional arguments allow attributes such as colour or transformations to be specified.
———————————— | ———–
tetrahedron3d
, cube3d
, octahedron3d
, dodecahedron3d
, icosahedron3d
: | Platonic solids
cuboctahedron3d
, oh3d
: | other solids
open3d()
cols <- rainbow(7)
layout3d(matrix(1:16, 4,4), heights=c(1,3,1,3))
text3d(0,0,0,"tetrahedron3d"); next3d()
shade3d(tetrahedron3d(col=cols[1])); next3d()
text3d(0,0,0,"cube3d"); next3d()
shade3d(cube3d(col=cols[2])); next3d()
text3d(0,0,0,"octahedron3d"); next3d()
shade3d(octahedron3d(col=cols[3])); next3d()
text3d(0,0,0,"dodecahedron3d"); next3d()
shade3d(dodecahedron3d(col=cols[4])); next3d()
text3d(0,0,0,"icosahedron3d"); next3d()
shade3d(icosahedron3d(col=cols[5])); next3d()
text3d(0,0,0,"cuboctahedron3d"); next3d()
shade3d(cuboctahedron3d(col=cols[6])); next3d()
text3d(0,0,0,"oh3d"); next3d()
shade3d(oh3d(col=cols[7]))
You must enable Javascript to view this page properly.
These functions generate new shapes:
———————————— | ———–
cylinder3d
: | generate a tube or cylinder
polygon3d
: | generate a flat polygon by triangulation
extrude3d
: | generate an “extrusion” of a polygon
turn3d
: | generate a solid of rotation
ellipse3d
: | generate an ellipsoid in various ways
tmesh3d
, qmesh3d
: | generate a shape from vertices and faces
shapelist3d
: | generate a shape by combining other shapes
A related function is triangulate
, which takes a
two dimensional polygon and divides it up into triangles using the
“ear-clipping” algorithm.
"shape3d"
is the basic abstract type. Objects of this class can be
displayed by shade3d
(which shades faces),
wire3d
(which draws edges), or dot3d
(which draws points at each vertex.) Note that wire3d
and dot3d
only work within R; in HTML output from writeWebGL
only
shade3d
is supported.
"mesh3d"
is a descendant type. Objects of this type contain the following
fields:
Field | Meaning |
---|---|
vb | A 4 by n matrix of vertices in homogeneous coordinates. Each column is a point. |
it | (optional) A 3 by t matrix of vertex indices. Each column is a triangle. |
ib | (optional) A 4 by q matrix of vertex indices. Each column is a quadrilateral. |
material | (optional) A list of material properties. |
normals | (optional) A matrix of the same shape as vb, containing normal vectors at each vertex. |
texcoords | (optional) A 2 by n matrix of texture coordinates corresponding to each vertex. |
The final set of functions manipulate and modify mesh objects:
———————————— | ———–
addNormals
: | add normal vectors to make a shape look smooth
subdivision3d
: | add extra vertices to make it look even smoother
rgl
has several functions to support displaying multiple different
“subscenes” in the same window. The high level functions are
———————————— | ———–
mfrow3d
: | Multiple figures (like par(“mfrow”)
layout3d
: | Multiple figures (like layout
)
next3d
: | Move to the next figure (like plot.new
or frame
)
subsceneList
: | List all the subscenes in the current layout
clearSubsceneList
| Clear the current list and revert to the previous one
There are also lower level functions.
———————————— | ———–
newSubscene3d
: | Create a new subscene, with fine control over what is inherited from the parent
currentSubscene3d
: | Report on the active subscene
subsceneInfo
: | Get information on current subscene
useSubscene3d
: | Make a different subscene active
addToSubscene3d
, delFromSubscene3d
: | Add objects to a subscene, or delete them
gc3d
: | Do “garbage collection”: delete objects that are not displayed in any subscene
By default, rgl
detects and handles mouse clicks within your scene,
and uses these to control its appearance. You can find out the current
handlers using the following code:
par3d("mouseMode")
## left right middle wheel
## "trackball" "zoom" "fov" "pull"
The labels c("left", "right", "middle")
refer to the buttons on
a three button mouse, or simulations of them on other mice. "wheel"
refers to the mouse wheel.
The button actions generally correspond to click and drag operations.
Possible values for "mouseMode"
for buttons or the wheel are as follows:
——– | ———
"none"
| No action
"trackball"
| The mouse acts as a virtual trackball. Clicking and dragging rotates the scene
"xAxis"
, "yAxis"
, "zAxis"
| Like "trackball"
, but restricted to rotation about one axis
"polar"
| The mouse affects rotations by controlling polar coordinates directly
"selecting"
| The mouse is being used by the select3d
function
"zoom"
| The mouse zooms the display
"fov"
| The mouse affects perspective by changing the field of view
"pull"
| Rotating the mouse wheel towards the user “pulls the scene closer”
"push"
| The same rotation “pushes the scene away”
"user"
| A user action set by rgl.setMouseCallbacks
, rgl.setWheelCallback
. Use rgl.getMouseCallbacks
and rgl.getWheelCallback
to retrieve
The following functions make use of the mouse for selection within a scene.
—————————- | ———–
identify3d
| like the classic graphics identify
function
select3d
| returns a function that tests whether a coordinate was selected
selectpoints3d
| selects from specific objects
The rgl.select3d
function is an obsolete version of
select3d
, and rgl.select
is a low-level support
function.
rgl
has several functions that can be used to construct
animations. These are based on functions that update the
scene according to the current real-world time, and repeated
calls to those. The functions are:
———————- | ————-
play3d
| Repeatedly call the update function
spin3d
| Update the display by rotating at a constant rate
par3dinterp
| Compute new values of some par3d
parameters by interpolation over time
See the movie3d
function for a way to output an animation
to a file on disk.
Animations are not currently supported
in the HTML written by writeWebGL
.
rgl
contains several functions to write scenes to disk for use
by other software, or to read them in.
In order from highest fidelity to lowest, the functions are:
———– | ————-
scene3d
| Save a scene to an R variable, which can be saved and reloaded
writeWebGL
| Write HTML and Javascript to display a scene in a web browser. (This vignette uses writeWebGL
; see also User Interaction in WebGL.)
writePLY
| Write PLY files (commonly used in 3D printing)
readOBJ
, writeOBJ
| Read or write OBJ files (commonly used in 3D graphics)
readSTL
, writeSTL
| Read or write STL files (also common in 3D printing)
rgl.useNULL
| A helper function for setting a NULL device
See the help page rgl.useNULL
for instructions on how
to use rgl
on a “headless” system.
There are also functions to save snapshots or other recordings of a scene, without any 3D information being saved:
———— | ————-
snapshot3d
| Save a PNG file bitmap of the scene
rgl.postscript
| Save a Postscript, LaTeX, PDF, SVG or PGF vector rendering of the scene
movie3d
| Save a series of bitmaps to be assembled into a movie
rgl.pixels
| Obtain pixel-level information about the scene in an R variable
rgl.Sweave
| Driver function for inserting a snapshot into a Sweave document.
hook_rgl
, hook_webgl
| knitr
hook functions for inserting images into a document.
setupKnitr
| Function to set up knitr
hooks
The rgl.snapshot
function is identical to snapshot3d
.
The functions rgl.Sweave.off
, Sweave.snapshot
are
involved in Sweave processing and not normally called by users.
The writeWebGL
function exports a scene to HTML and Javascript code.
The functions below write HTML and Javascript for working with the
exported scene. More details are given in the vignette
User Interaction in WebGL.
———————————— | ————-
propertySlider
| insert a slider to make changes to a scene
clipplaneSlider
| insert a slider to control a clipping plane
subsetSlider
| insert a slider to control which objects are displayed
toggleButton
| insert a button to toggle some items
propertySetter
| function to modify properties
subsetSetter
| function to choose subsets
ageSetter
| function to “age” vertices
par3dinterpSetter
| function like par3dinterp
vertexSetter
| function to modify individual vertices
matrixSetter
| function to modify matrices
rgl
maintains internal structures for all the scenes it displays.
The following functions allow users to find information about them
and manipulate them.
———————————— | ———–
open3d
| open a new window
rgl.close
| close the current window
rgl.bringtotop
| bring the current window to the top
rgl.cur
| id of the active device
rgl.dev.list
| ids of all active devices
rgl.set
| set a particular device to be active
rgl.ids
| ids and types of all current objects
rgl.attrib
, rgl.attrib.count
: | attributes of objects in the scene
pop3d
, rgl.pop
| delete an object from the scene
clear3d
, rgl.clear
| delete all objects of certain classes
rgl.projection
| return information about the current projection
rgl.user2window
, rgl.window2user
| convert between coordinates in the current projection
In addition to these, there are some other related functions which
should rarely be called by users: rgl.init
, rgl.open
, rgl.quit
.
Most rgl
functions work internally with “homogeneous” coordinates.
In this system, 3-D points are represented with 4 coordinates, generally
called (x, y, z, w). The corresponding Euclidean point is
(x/w, y/w, z/w), if w is nonzero; zero values of w correspond to
“points at infinity”. The advantage of this system is that
affine transformations including translations and perspective shifts
become linear transformations, with multiplication by a 4 by 4 matrix.
rgl
has the following functions to work with homogeneous coordinates:
———————————— | ———–
asEuclidean
, asHomogeneous
: | convert between homogeneous and Euclidean coordinates
rotate3d
, scale3d
, translate3d
: | apply a transformation
transform3d
: | apply a general transformation
rotationMatrix
, scaleMatrix
, translationMatrix
: | compute the transformation matrix
identityMatrix
| return a 4 x 4 identity matrix
There is also a function GramSchmidt
, mainly for internal
use: it does a Gram-Schmidt orthogonalization of a 3x3 matrix,
with some specializations for its use in cylinder3d
.
This vignette is in a preliminary form. Many aspects of the rgl package are not described, or do not have examples. There may even be functions that are missed completely, if the following list is not empty:
## character(0)
The following functions and constants are described in this document: