在点阵中复制 rgl 视点

标签 r lattice rgl

使用 rgl 交互地选择合适的视点,然后在格子 3d 图中采用相同的方向会很方便。例如,使用非信息性观点给出以下图。

library(lattice)
wireframe(volcano, screen = list(x=0, y=0, z=0))

enter image description here

可以通过

rgl 中打开相同的内容
library(rgl)
persp3d(volcano)
view3d(0, 0)

enter image description here

以交互方式,可以轻松地将绘图旋转到信息丰富的 View 。

enter image description here

给出当前rgl视点的矩阵可以通过以下方式提取

p <- par3d()
p$userMatrix

如何将这个矩阵转换成对应的x,y,z screen参数来复制点阵中的 View ?

更新1

我在下面尝试了 42 的转换。该代码显示了 rgl 图和每行相应的格子图。如果我正确实现了它(参见下面的代码),似乎仍然存在问题。

enter image description here

# 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())

最佳答案

我使用这个问题的答案来将旋转矩阵转换为角度:Conversion euler to matrix and matrix to euler 。我承认担心我在这里看到另一个有些不同的答案:How to calculate the angle from Roational matrix 。 (我的线性代数不足以确定哪个是正确的。)

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)

> print(list(B,P,H))
[[1]]
[1] 41.54071

[[2]]
[1] 40.28412

[[3]]
[1] 41.24902

那时我已经将 RGL 对象旋转到了您建议的大致“观察点”。我通过实验发现,提供给线框调用的负值提供了明显正确的结果。 “观察者旋转角度”似乎被视为“对象旋转角度”的负数。

 png(); print(wireframe(volcano, screen = list(x=-B, y=-P, z=-H)) ); dev.off()

enter image description here

TeachingDemos 包中有一个 rotate.wireframe 函数,但它不能很好地处理同时运行的 rgl 图。 (在我关闭 rgl 设备之前,没有明显的情节。)在 Mac 上运行时,它似乎也有一些问题(格子图上有粗黑线)。它使用 X11/XQuartz 设施通过 tk/tcl 函数管理交互,我无法从显示的角度重现绘图。看看代码我无法理解为什么会这样。但您的里程可能会有所不同。

关于在点阵中复制 rgl 视点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37007722/

相关文章:

r - 我想批量运行R代码并等待用户输入

r - 如何使用 R 在一个面板中绘制贝叶斯先验分布和后验分布?

R点阵条形图: How to write the total sum on each bar in multiple panels?

R rgl 轴刻度和刻度标签之间的距离

r - Shiny中 slider 的动态数量

r - R中的居中变量会阻止预测吗?

css - 在 Shiny 中如何控制 slider 上数字的大小?

r - 如何在格子R中隐藏x轴

r - x y 坐标与 rgl 颠倒

r - 3D 表面插值