如何从一组n x 3数据绘制非凸面?

3
有没有一种直接的方法在R中绘制非凸曲面?
对于凸曲面,我已经使用类似以下代码的方法,并且可以正常工作:
xyz <- cbind(y,x,z)
tbr <- t(surf.tri(xyz, delaunayn(xyz)))
rgl.triangles(xyz[tbr,1], xyz[tbr,2], xyz[tbr,3])

然而,对于非凸面,凹区域会被填充。我认为这是函数的问题,因为它使用不支持约束Delaunay三角剖分或非凸对象网格生成的库。

欢迎任何建议。

P.S.

我有一个ASCII文件作为数据,但它有3列,共225行。提供此数据的最佳方式是什么?

数据可在http://pastebin.com/R2p4Cf7d找到。

图的顶部应该是凹的!这是使用创建的图像,显示了表面的正确外观。它是使用极坐标中更多的网格点计算出来的,而不是使用不规则的插值点。

Correct rendering of surface, but with more grid points.


1
请添加一个可重现的示例,使用模拟数据。 - Remko Duursma
一个 Delaunay 三角剖分总是凸的。也许您需要修改一些边界三角形(即具有长边的三角形)的绘图颜色。 - mdsumner
请查看alphahull包。 - mdsumner
如果您稍微处理一下 x,y,z 数据并使用 lattice::wireframe 进行阴影或覆盖,会发生什么? - Carl Witthoft
请参见:https://dev59.com/eG025IYBdhLWcg3whGSx - nico
2个回答

3
以下解决方案并不完美,但如果您有Matlab的副本,则可以使用。
library(rgl)
library(geometry)
# Read in data - also at: http://pastebin.com/R2p4Cf7d
simDat <- read.csv("testDat.csv")
#
x   <- simDat[,1];y<-simDat[,2];z<-simDat[,3]
xyz <- cbind(simDat[,1],simDat[,2],simDat[,3])
#
triNodes <- delaunayn(xyz)
tbr1     <- t(surf.tri(xyz, triNodes ))
# Plot data from R generated triangles
open3d()
rgl.triangles(xyz[tbr1,1], xyz[tbr1,2], xyz[tbr1,3])
#
# Import data generated by Matlab function delaunay()
#  - also at: http://pastebin.com/vQV2Zaii
nodeDat_ML <- read.csv("testDatNodes.csv")
triNodes2  <- cbind(nodeDat_ML[,1], nodeDat_ML[,2], nodeDat_ML[,3],1)
#
tbr2 <- t(surf.tri(xyz, triNodes2))
# Plot data from Matlab generated triangles
open3d()
rgl.triangles(xyz[tbr2,1], xyz[tbr2,2], xyz[tbr2,3])

该代码生成了以下两个曲面。左侧图基于由R函数delaunayn()生成的三角剖分,右侧图基于Matlab函数delaunay()生成的三角剖分。 使用R和Matlab生成的三角剖分情况 Matlab生成的数据可在此处获取:http://pastebin.com/vQV2Zaii
相关Matblab代码如下:
fname = 'testDat.csv';
tt = table2array(readtable(fname)); % get data
x =  tt(:,1);y = tt(:,2);z = tt(:,3);
tri = delaunay(x,y); % the triangulation data
trisurf(tri,x(:,1),y(:,1),z(:,1)); % surface plot

结果并不完美,因为最终的图形(右侧)有一个虚假的三角形。
希望以上内容对于有类似问题的人有所帮助。

0

我觉得在这种情况下,deldir::deldir() 做得比 geometry::delaunayn() 更好(作为一个新函数 rgl::plot3d.deldir() 的纪念)。 (我使用了 OP的数据。)

library(rgl); library(deldir)

dxyz <- deldir(xyz[,1], xyz[,2], z=xyz[,3])

open3d()
plot3d(dxyz, col=cm.colors(256)[cut(xyz[,3], 256)], alpha=0.9)  # there isn't a bottom
wire3d(as.mesh3d(dxyz), col="black")

enter image description here


谢谢您提供这个例子。然而,使用相同的数据(跳过标题)plot3d()会抛出一个错误。我尝试了不同的数据格式,但都没有成功。您是如何读取数据的? - Graham G
刚刚更新了deldir和rgl包,代码运行良好。再次感谢,这太棒了。 - Graham G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接