使用rgl
以交互方式选择合适的视点然后在lattice
3d图中采用相同的方向将会很方便。例如,给出以下使用非信息性观点的情节。
library(lattice)
wireframe(volcano, screen = list(x=0, y=0, z=0))
可以在rgl
library(rgl)
persp3d(volcano)
view3d(0, 0)
交互式地,可以轻松地将绘图旋转到信息丰富的视图。
可以通过
提取给出当前rgl
视点的矩阵
p <- par3d()
p$userMatrix
如何将此矩阵转换为相应的x
,y
,z
screen
参数以复制格子中的视图?
更新1
我在下面尝试了42的转换。代码显示了rgl图和每行的相应晶格图。如果我正确实现了它(参见下面的代码),似乎仍然存在问题。
# 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())
答案 0 :(得分:1)
我使用这个问题的答案从旋转矩阵转换到角度: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()
在TeachingDemos包中有一个rotate.wireframe
函数,但它不能同时运行rgl图。 (直到我关闭rgl设备才有明显的情节。)当在Mac上运行时(在格子图上的粗黑线),它似乎也有点儿。它使用X11 / XQuartz工具通过tk / tcl函数管理交互,我无法从显示的角度重现这些图。看看代码,我无法理解为什么会这样。但你的里程可能会有所不同。
答案 1 :(得分:1)
此版本的函数使用orientlib
包中的转换,并将旋转矩阵作为参数:
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-forge,
包含此函数的一个版本,以及一个用于基本图形的版本。