首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在格中复制rgl视点

在格中复制rgl视点
EN

Stack Overflow用户
提问于 2016-05-03 15:03:21
回答 2查看 436关注 0票数 5

使用rgl交互地选择一个像样的观点,然后在lattice三维图形中采用相同的方向是很方便的。例如,给出以下使用非信息视角的绘图。

代码语言:javascript
复制
library(lattice)
wireframe(volcano, screen = list(x=0, y=0, z=0))

rgl中,也可以通过

代码语言:javascript
复制
library(rgl)
persp3d(volcano)
view3d(0, 0)

交互作用下,可以很容易地将图旋转到信息丰富的视图。

给出当前rgl视点的矩阵可以通过

代码语言:javascript
复制
p <- par3d()
p$userMatrix

如何将此矩阵转换为相应的x**,**y**,**z screen 参数,以便在格子中复制视图?

更新1

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

代码语言:javascript
复制
# 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())
EN

回答 2

Stack Overflow用户

发布于 2016-05-03 17:16:15

我用这个问题的答案从旋转矩阵转换为角度:Conversion euler to matrix and matrix to euler。我承认,我在这里看到了另一个有点不同的答案:How to calculate the angle from Roational matrix。(我的线性代数不足以判断其中哪一个是正确的。)

代码语言:javascript
复制
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对象旋转到了您建议的大致“查看点”。我通过实验发现,提供给线框调用的负值提供了明显正确的结果。“查看器旋转角度”似乎被认为是“物体旋转角度”的负值。

代码语言:javascript
复制
 png(); print(wireframe(volcano, screen = list(x=-B, y=-P, z=-H)) ); dev.off()

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

票数 1
EN

Stack Overflow用户

发布于 2016-05-04 18:41:32

函数的这个版本使用来自orientlib包的转换,并使旋转矩阵成为一个参数:

代码语言:javascript
复制
rgl_to_lattice_viewpoint <- function(rotm = par3d("userMatrix"))
{
  e <- -orientlib::eulerzyx(orientlib::rotmatrix(rotm[1:3, 1:3]))@x*180/pi
  list(z = e[1], y = e[2], x = e[3])
}

注意,z,y,x顺序是基本的。

使用它代替您的函数,我得到了以下输出:

这些都是正确的旋转。我不知道是否也有可能找到匹配的视角。

编辑以添加:rgl版本0.95.1468,到目前为止只能在R-锻造,包含该功能的一个版本,以及一个基本图形。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37007722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档