在 RGL Plot 中有效地显示多个圆柱体

Display multiple cylinders efficiently in RGL Plot

我正在尝试在 R 中绘制由数千个圆柱体组成的圆柱体模型。目前,我正在尝试使用 rgl 包来完成这项任务。到现在为止,我遍历了所有圆柱体并将它们分别添加到 3D 绘图中。

这里有一个虚拟数据的例子:

# dummy data
cylinder <- data.frame(start_X = rep(0:2, each = 2),
                       start_Y = rep(0:1, 3),
                       start_Z = 0,
                       end_X = rep(0:2, each = 2),
                       end_Y = rep(0:1, 3),
                       end_Z = 1)
radii <- seq(0.1, 0.5, length.out = 6)

# plotting
open3d()
for (i in 1:nrow(cylinder)) {
  cyl <- cylinder3d(
    center = cbind(
      c(cylinder$start_X[i], cylinder$end_X[i]),
      c(cylinder$start_Y[i], cylinder$end_Y[i]),
      c(cylinder$start_Z[i], cylinder$end_Z[i])),
    radius = radii[i],
    closed = -2)
  shade3d(cyl, col = "steelblue")
}
axes3d(edges = c("x", "y", "z"))

但是,这种方法在尝试绘制数千个圆柱体时会花费很长时间。有没有办法一次性把几个圆柱对象交给shade3d()函数?我可以在 cylinder3d() 的一次调用中创建多个单独的圆柱体吗?或者我可能使用了错误的函数或不合适的 R 包?

有很多可能性。

最简单的更改是告诉 rgl 在使用 par3d(skipRedraw=TRUE) 选项完成更新之前不要更新显示。您需要 运行 par3d(skipRedraw=FALSE) 才能看到更新。这通常足以加快速度。

如果您所有的圆柱体都是相同的形状(但可能会重新缩放),您可以使用 sprites3d;但是您要分别改变半径和高度,所以这是不可能的。

要执行您要求的操作(将它们全部放入一个 shade3d 调用中),您可以制作一个形状列表。例如,编辑后允许单独的颜色,

cylinder <- data.frame(start_X = rep(0:2, each = 2),
                       start_Y = rep(0:1, 3),
                       start_Z = 0,
                       end_X = rep(0:2, each = 2),
                       end_Y = rep(0:1, 3),
                       end_Z = 1)
radii <- seq(0.1, 0.5, length.out = 6)
colors <- rainbow(6)

library(rgl)
thelist <- lapply(1:6, function(i) {
  cyl <- cylinder3d(
    center = cbind(
      c(cylinder$start_X[i], cylinder$end_X[i]),
      c(cylinder$start_Y[i], cylinder$end_Y[i]),
      c(cylinder$start_Z[i], cylinder$end_Z[i])),
    radius = radii[i],
    closed = -2)
  cyl$material$color <- colors[i]
  cyl
})

# plotting
open3d()
shade3d(shapelist3d(thelist, plot = FALSE))
axes3d(edges = c("x", "y", "z"))

shapelist3d() 函数可以获取上面的网格列表,或者获取单个网格并使用其他参数重塑并复制它。速度应该不会有太大的区别。