[vtkusers] vtkDelaunay3D: wrong convex hull
David Doria
daviddoria at gmail.com
Wed Jul 27 08:25:18 EDT 2011
2011/7/26 Miguel Sotaquirá <msotaquira at gmail.com>
> Hi David!
>
> Here's the hardcoded version. Just to clarify: I just want to know if the
> current 3-D vertex ("c" in the code) is contained in the convex hull of its
> 3-D neighbors ("pts" in the code). I've used vtkDelaunay3D and vtkDelaunay2D
> currently without any success.
> Miguel
>
> #include <vtkSmartPointer.h>
> #include <vtkPolyData.h>
> #include <vtkPoints.h>
> #include <vtkUnstructuredGrid.h>
> #include <vtkDelaunay3D.h>
> #include <vtkPlane.h>
> #include <vtkDelaunay2D.h>
> #include <vtkXMLPolyDataWriter.h>
> #include <vtkXMLUnstructuredGridWriter.h>
>
> int main (int argc, char* argv[])
> {
> // Current vertex coordinates (this data is not used. serves only as a
> reference)
> double c[3] = {-0.59842, 2.12762, 5.17183};
> // Current vertex normal
> double N[3] = {-0.604189, 0.796814, -0.00654253};
> // Original 3-D neighbors coordinates
> double p0[3] = {-0.53592, 2.21902, 5.10933};
> double p1[3] = {-0.59842, 2.17465, 5.10933};
> double p2[3] = {-0.53592, 2.17465, 5.17183};
> double p3[3] = {-0.66092, 2.07811, 5.17183};
> double p4[3] = {-0.59842, 2.17465, 5.23433};
> double p5[3] = {-0.66092, 2.12762, 5.23433};
> // Insert 3-D neighbors in a polydata
> vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
> pts->InsertNextPoint( p0 );
> pts->InsertNextPoint( p1 );
> pts->InsertNextPoint( p2 );
> pts->InsertNextPoint( p3 );
> pts->InsertNextPoint( p4 );
> pts->InsertNextPoint( p5 );
> /*
> // 3-D convex hull: NOT WORKING
> // point cloud of neighbors
> vtkSmartPointer<vtkUnstructuredGrid> points =
> vtkSmartPointer<vtkUnstructuredGrid>::New();
> points->SetPoints( pts );
> points->Update();
> // convex hull
> vtkSmartPointer<vtkDelaunay3D> delaunay3D =
> vtkSmartPointer<vtkDelaunay3D>::New();
> delaunay3D->SetInput( points );
> delaunay3D->Update();
> */
> //
> // A 2D triangulation (using vtkDelaunay2D) will be obtained by projecting
> // 3-D points onto a plane
> //
> // create a plane, seting its origin in (0,0,0) and its normal N
> vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
> plane->SetOrigin(0.0, 0.0, 0.0);
> plane->SetNormal(N[0], N[1], N[2]);
> // project each point in the point cloud onto the plane
> vtkSmartPointer<vtkPoints> ptsProj = vtkSmartPointer<vtkPoints>::New();
> double origin[3] = {0.0, 0.0, 0.0};
> double normal[3] = {N[0], N[1], N[2]};
> double projected[3];
> double p[3];
> for ( int i = 0; i < pts->GetNumberOfPoints(); i++ ) {
> pts->GetPoint(i,p);
> plane->ProjectPoint( p, origin, normal, projected );
> ptsProj->InsertNextPoint(projected);
> }
> // apply delaunay2D on the projected points
> vtkSmartPointer<vtkPolyData> ptsForTriang =
> vtkSmartPointer<vtkPolyData>::New();
> ptsForTriang->SetPoints(ptsProj);
> vtkSmartPointer<vtkDelaunay2D> delaunay2D =
> vtkSmartPointer<vtkDelaunay2D>::New();
> delaunay2D->SetInput(ptsForTriang);
> delaunay2D->Update();
>
> // export points (original and projected) and triangulation for viewing
> in Paraview
> vtkSmartPointer<vtkUnstructuredGrid> points2D =
> vtkSmartPointer<vtkUnstructuredGrid>::New();
> vtkSmartPointer<vtkUnstructuredGrid> points3D =
> vtkSmartPointer<vtkUnstructuredGrid>::New();
> points2D->SetPoints(ptsProj);
> points3D->SetPoints(pts);
> vtkSmartPointer<vtkXMLUnstructuredGridWriter> writerpts2D =
> vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
> writerpts2D->SetFileName("points2D.vtu");
> writerpts2D->SetInput(points2D);
> writerpts2D->Write();
> vtkSmartPointer<vtkXMLUnstructuredGridWriter> writerpts3D =
> vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
> writerpts3D->SetFileName("points3D.vtu");
> writerpts3D->SetInput(points3D);
> writerpts3D->Write();
> vtkSmartPointer<vtkXMLPolyDataWriter> writer =
> vtkSmartPointer<vtkXMLPolyDataWriter>::New();
> writer->SetFileName("delaunay2D.vtp");
> writer->SetInput(delaunay2D->GetOutput());
> writer->Update();
> return 0;
> }
>
You are projecting the points onto an arbitrary plane, but Delaunay2D
expected them to be on the XY plane:
"The input to this filter is a list of points specified in 3D, even though
the triangulation is 2D. Thus the triangulation is constructed in the x-y
plane, and the z coordinate is ignored (although carried through to the
output)"
I've done this by finding a local coordinate system on the plane and mapping
the points into that coordinate system:
https://github.com/daviddoria/vtkPlanarPatch/blob/master/vtkPlanarPatch.cxx
You can also do this by passing a transform to Delaunay2D with
SetTransform().
The idea is to apply the topology that results from the triangulation to
your original points.
David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20110727/775eaa04/attachment.htm>
More information about the vtkusers
mailing list