It would be convenient to interactively select a decent viewpoint using rgl
and then adopt the same orientation in a lattice
3d-plot. For example, given the following plot using a non-informative viewpoint.
library(lattice)
wireframe(volcano, screen = list(x=0, y=0, z=0))
The same can be opened in rgl
by
library(rgl)
persp3d(volcano)
view3d(0, 0)
Interactively it is easy to rotate the plot to an informative view.
The matrix giving the current rgl
viewpoint in can be extracted by
p <- par3d()
p$userMatrix
How can this matrix be converted into corresponding x
,y
,z
screen
parameters to replicate the view in lattice?
UPDATE 1
I tried out 42's conversion below. The code shows the rgl plot and the corresponding lattice plot per row. If I implemented it correctly (see code below), there appears to still be an issue.
# convert rgl viewpoint into lattice
# screen orientation
rgl_to_lattice_viewpoint <- function()
{
p <- par3d()
rotm <- p$userMatrix
B = 360*atan(rotm[1,2]/rotm[2,2])/(2*pi)
P = 360*asin(-rotm[3,2])/(2*pi)
H = 360*atan(rotm[3,1]/rotm[3,3])/(2*pi)
list(x=-B, y=-P, z=-H)
}
# read and plot PNG image
plot_png <- function(f)
{
img <- readPNG(f)
rimg <- as.raster(img) # raster multilayer object
plot(NULL, xlim=c(0,1), ylim=c(0,1), xlab = "", ylab = "",
asp=1, frame=F, xaxt="n", yaxt="n")
rasterImage(rimg, 0, 0, 1, 1)
}
# create rgl snapshot with random rotation and
# corresponding lattice wireframe plot
lattice_plus_rgl_plot <- function()
{
# rgl plot random rotation
persp3d(volcano, col = "green3")
theta <- sample(-180:180, 1)
phi <- sample(-90:90, 1)
view3d(theta, phi, fov=40)
v <- rgl_to_lattice_viewpoint()
f <- tempfile(fileext = ".png")
rgl.snapshot(f)
rgl.close()
# lattice plot
f2 <- tempfile(fileext = ".png")
png(f2)
print(wireframe(volcano, screen = v))
dev.off()
# plot both
plot_png(f)
plot_png(f2)
}
# CREATE SOME PLOTS
library(rgl)
library(lattice)
library(png)
par(mfrow=c(3,2), mar=c(0,0,0,0))
replicate(3, lattice_plus_rgl_plot())