在 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()
函数可以获取上面的网格列表,或者获取单个网格并使用其他参数重塑并复制它。速度应该不会有太大的区别。
我正在尝试在 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()
函数可以获取上面的网格列表,或者获取单个网格并使用其他参数重塑并复制它。速度应该不会有太大的区别。