как построить невыпуклую поверхность из набора данных n x 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])

Однако для невыпуклых поверхностей вогнутые области становятся заполненными. Я думаю, что это проблема с функцией delaunayn(), так как она использует библиотеку Qhull, которая не поддерживает ограниченные триангуляции Делоне или создание сетки невыпуклых объектов.

Любые предложения приветствуются.

P.S.

У меня есть данные в виде файла ascii, но он имеет 3 столбца и 225 строк. Каков наилучший способ обеспечить это?

Данные доступны по адресу: http://pastebin.com/R2p4Cf7d.

Верх участка должен быть вогнутым! Это изображение, созданное с использованием persp3d() того, как должна выглядеть поверхность. Он был рассчитан с использованием большего количества точек сетки на регулярной сетке в полярных координатах, а не с использованием неправильных точек коллокации.

Правильный рендеринг поверхности, но с большим количеством точек сетки.


person Graham G    schedule 07.07.2014    source источник
comment
Пожалуйста, добавьте воспроизводимый пример, что-нибудь с смоделированными данными.   -  person Remko Duursma    schedule 07.07.2014
comment
Триангуляция Делоне всегда выпукла. Возможно, вам нужно изменить цвета графика для некоторых граничных треугольников (например, с длинным краем)   -  person mdsumner    schedule 07.07.2014
comment
Проверьте пакет alphahull.   -  person mdsumner    schedule 07.07.2014
comment
Что произойдет, если вы просто немного испортите свои x,y,z данные и используете lattice::wireframe с затенением или драпировкой?   -  person Carl Witthoft    schedule 07.07.2014
comment
См.: stackoverflow .com/questions/5963269/   -  person nico    schedule 07.07.2014


Ответы (2)


Я чувствую, что 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")

введите здесь описание изображения

person cuttlefish44    schedule 29.08.2016
comment
Спасибо за этот пример. Однако при использовании тех же данных (пропуская заголовок) plot3d() выдает ошибку. Я пробовал разные форматы данных безрезультатно. Как вы читали данные? - person Graham G; 30.08.2016
comment
Только что обновил пакеты deldir и rgl и код работает нормально. Еще раз спасибо, это здорово. - person Graham G; 30.08.2016

Следующее решение не идеально, но работает, если у вас есть копия 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])

Код создает следующие две поверхности. Левый график основан на триангуляции, сгенерированной функцией delaunay() R, а правый график основан на триангуляции, сгенерированной функцией delaunay() в Matlab.

Графики из триангуляции, сгенерированные 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

Результат не совсем идеален, так как на финальном графике (справа) есть ложный треугольник.

Надеюсь, что вышеизложенное будет полезно всем, у кого есть похожая проблема.

person Graham G    schedule 09.07.2014