以 svg 或 pdf 等无损格式保存 rgl 3D 散点图
Save a rgl 3D scatterplot in a lossless format like svg or pdf
我想要实现的是,在 rgl 中显示 3D 图形,将其旋转到我想要显示的视图中,然后将其保存到文件中。我知道我可以用 rgl.snapshot
函数来做到这一点:
library(rgl)
x <- runif(20)
y <- runif(20)
z <- runif(20)
plot3d(x, y, z)
rgl.snapshot("rgl.snapshot.png")
问题是,rgl.snapshot
以屏幕分辨率生成文件,因此分辨率不足以打印。我无法影响文件保存时的分辨率。一般来说,如果我能够将文件保存为 pdf 或 svg 等矢量格式,那就更好了。
我的想法是保存当前视图的旋转,并将其与另一个生成非交互式 3d 散点图的函数一起使用,例如 plot3D
包中的 scatter3D
。为了保存旋转矩阵,我做了以下操作:
rotationMatrix <- rgl.projection()
你也可以这样做:
rotationMatrix <- par3d()$modelMatrix
旋转矩阵如下所示:
$model
[,1] [,2] [,3] [,4]
[1,] 0.9584099 0.0000000 0.0000000 -0.4726846
[2,] 0.0000000 0.3436644 0.9792327 -0.6819317
[3,] 0.0000000 -0.9442102 0.3564116 -3.6946754
[4,] 0.0000000 0.0000000 0.0000000 1.0000000
$proj
[,1] [,2] [,3] [,4]
[1,] 3.732051 0.000000 0.000000 0.00000
[2,] 0.000000 3.732051 0.000000 0.00000
[3,] 0.000000 0.000000 -3.863703 -14.36357
[4,] 0.000000 0.000000 -1.000000 0.00000
$view
x y width height
0 0 256 256
现在我的问题是如何从这个旋转矩阵得到参数 phi
和 theta
,它们被 scatter3D
函数使用。
library(plot3D)
# phi = ?
# theta = ?
pdf("scatter3D.pdf")
scatter3D(x, y, z, pch=20, phi = 20, theta =30, col="black")
dev.off()
我知道有数学可以从旋转矩阵中提取旋转角度。我真的不知道如何在我的案例中应用它。特别是因为矩阵有 4 行和 4 列。我希望每个都有 3 个...下一个问题是 scatter3D
仅使用两个旋转轴(theta 给出方位角方向,phi 给出余纬度),所以我必须从 3 轴旋转转换为相同的由两轴旋转引起的旋转。我认为phi的旋转轴是由theta的旋转定义的。
如果有另一种方法可以以无损格式保存 rgl 快照,我很乐意了解它!
rgl 的最新版本(仅限 R-forge;请参阅 了解如何获取)版本的 rglToBase() 函数 returns 您需要的 phi 和 theta 值。还有 rgl.postscript() 正如我在 4 月 24 日的评论中提到的那样,它以无损格式保存(但不能保存所有内容)。
编辑添加:writeASY()
函数是一个非常新的添加。这写出 Asymptote 源代码以绘制各种格式的图像,主要用于 LaTeX 文档。参见 http://asymptote.sourceforge.net。这仍然有一些限制(不支持子场景,表面照明不完美,等等)但它已经到了。欢迎提出建议。
我想要实现的是,在 rgl 中显示 3D 图形,将其旋转到我想要显示的视图中,然后将其保存到文件中。我知道我可以用 rgl.snapshot
函数来做到这一点:
library(rgl)
x <- runif(20)
y <- runif(20)
z <- runif(20)
plot3d(x, y, z)
rgl.snapshot("rgl.snapshot.png")
问题是,rgl.snapshot
以屏幕分辨率生成文件,因此分辨率不足以打印。我无法影响文件保存时的分辨率。一般来说,如果我能够将文件保存为 pdf 或 svg 等矢量格式,那就更好了。
我的想法是保存当前视图的旋转,并将其与另一个生成非交互式 3d 散点图的函数一起使用,例如 plot3D
包中的 scatter3D
。为了保存旋转矩阵,我做了以下操作:
rotationMatrix <- rgl.projection()
你也可以这样做:
rotationMatrix <- par3d()$modelMatrix
旋转矩阵如下所示:
$model
[,1] [,2] [,3] [,4]
[1,] 0.9584099 0.0000000 0.0000000 -0.4726846
[2,] 0.0000000 0.3436644 0.9792327 -0.6819317
[3,] 0.0000000 -0.9442102 0.3564116 -3.6946754
[4,] 0.0000000 0.0000000 0.0000000 1.0000000
$proj
[,1] [,2] [,3] [,4]
[1,] 3.732051 0.000000 0.000000 0.00000
[2,] 0.000000 3.732051 0.000000 0.00000
[3,] 0.000000 0.000000 -3.863703 -14.36357
[4,] 0.000000 0.000000 -1.000000 0.00000
$view
x y width height
0 0 256 256
现在我的问题是如何从这个旋转矩阵得到参数 phi
和 theta
,它们被 scatter3D
函数使用。
library(plot3D)
# phi = ?
# theta = ?
pdf("scatter3D.pdf")
scatter3D(x, y, z, pch=20, phi = 20, theta =30, col="black")
dev.off()
我知道有数学可以从旋转矩阵中提取旋转角度。我真的不知道如何在我的案例中应用它。特别是因为矩阵有 4 行和 4 列。我希望每个都有 3 个...下一个问题是 scatter3D
仅使用两个旋转轴(theta 给出方位角方向,phi 给出余纬度),所以我必须从 3 轴旋转转换为相同的由两轴旋转引起的旋转。我认为phi的旋转轴是由theta的旋转定义的。
如果有另一种方法可以以无损格式保存 rgl 快照,我很乐意了解它!
rgl 的最新版本(仅限 R-forge;请参阅
编辑添加:writeASY()
函数是一个非常新的添加。这写出 Asymptote 源代码以绘制各种格式的图像,主要用于 LaTeX 文档。参见 http://asymptote.sourceforge.net。这仍然有一些限制(不支持子场景,表面照明不完美,等等)但它已经到了。欢迎提出建议。