我希望有经验的人可以帮助我们如何从xyz数据中准备形状文件。虽然没有提供创建here的前面步骤,但可以看到彗星Churyumov-Gerasimenko的精心准备的数据集的一个很好的例子shape file。
我试图更好地了解如何将曲面应用于给定的XYZ坐标集。使用笛卡尔坐标直接使用R包" rgl"但是环绕的形状看起来更难。我找到了R包geometry
,它提供了QHULL函数的接口。我尝试使用它来计算Delaunay三角剖面,然后我可以在rgl
中绘制。我无法弄清楚与函数delaunayn
相关的一些选项,以便可能控制计算这些方面的最大距离。我希望这里有人可能对xyz数据改进表面结构有一些想法。
library(onion)
library(rgl)
library(geometry)
data(bunny)
#XYZ point plot
open3d()
points3d(bunny, col=8, size=0.1)
#rgl.snapshot("3d_bunny_points.png")
#Facets following Delaunay triangulation
tc.bunny <- delaunayn(bunny)
open3d()
tetramesh(tc.bunny, bunny, alpha=0.25, col=8)
#rgl.snapshot("3d_bunny_facets.png")
This answer让我相信Qhull的R实现可能存在问题。此外,我现在尝试了各种设置(例如delaunayn(bunny, options="Qt")
),效果甚微。 Qhull选项概述为here
这是一个额外的(更简单的)球体示例。即使在这里,小平面的计算并不总能找到最近的相邻顶点(如果你旋转球,你会看到一些小平面穿过内部)。
library(rgl)
library(geometry)
set.seed(1)
n <- 10
rho <- 1
theta <- seq(0, 2*pi,, n) # azimuthal coordinate running from 0 to 2*pi
phi <- seq(0, pi,, n) # polar coordinate running from 0 to pi (colatitude)
grd <- expand.grid(theta=theta, phi=phi)
x <- rho * cos(grd$theta) * sin(grd$phi)
y <- rho * sin(grd$theta) * sin(grd$phi)
z <- rho * cos(grd$phi)
set.seed(1)
xyz <- cbind(x,y,z)
tbr = t(surf.tri(xyz, delaunayn(xyz)))
open3d()
rgl.triangles(xyz[tbr,1], xyz[tbr,2], xyz[tbr,3], col = 5, alpha=0.5)
rgl.snapshot("ball.png")
答案 0 :(得分:18)
这是一种使用核密度估计和contour3d
的{{1}}函数的方法。我一直玩,直到找到misc3d
的值得体面的值。它不是非常精确,但您可以调整一些东西以获得更好,更准确的表面。如果你的内存超过8GB,那么你可以将levels
增加到超出我在此处所做的范围。
n
右侧的图像位于底部,只是为了显示另一个视图。
您可以在library(rgl)
library(misc3d)
library(onion); data(bunny)
# the larger the n, the longer it takes, the more RAM you need
bunny.dens <- kde3d(bunny[,1],bunny[,2],bunny[,3], n=150,
lims=c(-.1,.2,-.1,.2,-.1,.2)) # I chose lim values manually
contour3d(bunny.dens$d, level = 600,
color = "pink", color2 = "green", smooth=500)
rgl.viewpoint(zoom=.75)
中为n
使用更大的值,但这会花费更长时间,如果数组太大,您可能会耗尽RAM。您还可以尝试不同的带宽(此处默认使用)。我从Computing and Displaying Isosurfaces in R - Feng & Tierney 2008采用了这种方法。
使用kde3d
包非常相似的isosurface方法:
Rvcg
由于它是基于密度估计的方法,我们可以通过增加兔子的密度来获得更多。我也在这里使用library(Rvcg)
library(rgl)
library(misc3d)
library(onion); data(bunny)
bunny.dens <- kde3d(bunny[,1],bunny[,2],bunny[,3], n=150,
lims=c(-.1,.2,-.1,.2,-.1,.2)) # I chose lim values manually
bunny.mesh <- vcgIsosurface(bunny.dens$d, threshold=600)
shade3d(vcgSmooth(bunny.mesh,"HC",iteration=3),col="pink") # do a little smoothing
。成本是计算时间的显着增加,但结果表面更好野兔:
n=400
存在更好,更有效的表面重建方法(例如,动力外壳,泊松表面重建,球转动算法),但我不知道在R中已经实现了任何方法。
这是一个相关的Stack Overflow帖子,其中包含一些很棒的信息和检查链接(包括代码链接):robust algorithm for surface reconstruction from 3D point cloud?。
答案 1 :(得分:13)
我认为使用alphashape3d
包找到了一种可能的解决方案。我必须玩一下才能获得alpha
的可接受值,这与给定数据集中的距离有关(例如sd
的{{1}}给了我一些见解)。我仍在试图弄清楚如何更好地控制顶点和边缘中的线条宽度,以免占主导地位,但这可能与bunny
中的设置有关。
rgl
只有通过调整library(onion)
library(rgl)
library(geometry)
library(alphashape3d)
data(bunny)
apply(bunny,2,sd)
alphabunny <- ashape3d(bunny, alpha = 0.003)
bg3d(1)
plot.ashape3d(alphabunny, col=c(5,5,5), lwd=0.001, size=0, transparency=rep(0.5,3), indexAlpha = "all")
函数,才能删除边和顶点:
plot.ashape3d
答案 2 :(得分:3)
2016年7月将包Rvcg
更新为版本0.14,并添加了球旋转曲面重建。该函数为vcgBallPivoting
:
library(Rvcg) # needs to be >= version 0.14
library(rgl)
library(onion); data(bunny)
# default parameters
bunnybp <- vcgBallPivoting(bunny, radius = 0.0022, clustering = 0.2, angle = pi/2)
shade3d(bunnybp, col = rainbow(1000), specular = "black")
shade3d(bunnybp, col = "pink", specular = "black") # easier to see problem areas.
球旋转和默认参数设置对于斯坦福兔子来说并不完美(正如评论radius = 0.0022
中的乌贼44所指出的那样优于默认的radius = 0
),你留下了一些空白在表面上。实际的兔子在基地有2个洞,一些扫描限制导致其他一些洞(如下所述:https://graphics.stanford.edu/software/scanview/models/bunny.html)。您可能能够找到更好的参数,并且使用vcgBallPivoting
(我的机器上约0.5秒)非常快,但可能需要额外的努力/方法来缩小差距。