How can I mesh a cylindrical scatter plot?

17 views (last 30 days)
Hello everyone
I'm trying to mesh a scatter plot like this one (for the coordinates of the points see the attached file):
plot3(x,y,z,'.'); grid on;
I looked in many forums and readed correlated posts and this seems to be a solution, but as you can see it doesn't work well:
tri = delaunay(x,y,z);
Warning: Duplicate data points have been detected and removed.
Some point indices will not be referenced by the triangulation.
trimesh(tri, x, y, z);
I know that trimesh shouldn't work with the m-by-4 matrix "tri" generated with delaunay, but this is actually my best solution...
Matlab seems to have a problem with duplicate data points, maybe because the surface is cylindrical and not plane. Has anyone an advice?

Answers (3)

Walter Roberson
Walter Roberson on 6 Jan 2016
tetramesh() for the m x 4 representation.
You really do have a bunch of duplicate points -- only 1838 unique out of 7056. It looks like parts of the vectors trace out triangles that could perhaps be broken apart, but the logic of what connects to what is not clear. In some of the cases the pattern just runs off and connects somewhere else for a bit. Still there is enough regularity for me to suspect that you might already have information about which vertex is connected to which; if so then extracting that information and using trimesh() or patch() would be the way to proceed.
In the meanwhile,
XYZ = unique([x(:), y(:), z(:)], 'rows');
tri = delaunay(XYZ(:,1),XYZ(:,2),XYZ(:,3));
tetramesh(tri, XYZ);
  1 Comment
Luca Roncarati
Luca Roncarati on 6 Jan 2016
Edited: Luca Roncarati on 6 Jan 2016
Hello and thx for your reply!
Thx for the code to eliminate the duplicate points. The code that you suggested,
XYZ = unique([x(:), y(:), z(:)], 'rows');
tri = delaunay(XYZ(:,1),XYZ(:,2),XYZ(:,3));
tetramesh(tri, XYZ);
generates the following figure, so there is no visible improvement:
Did you get the same figure?
But you are right: I have the information about which vertex is connected to which. However, the export of this information from the generating software is laborious and computing time consuming, but I will next look into this option.

Sign in to comment.


Mike Garrity
Mike Garrity on 6 Jan 2016
Trying to do this in Cartesian space might not be the best approach. You know that the points are nearly on the surface of a cylinder, so you might be better off performing the triangulation on the surface of the cylinder.
Here's a rough outline. First some sample data:
npts = 500;
theta = 2*pi*rand(1,npts);
r = 5+randn(1,npts)/3;
z = 10*randn(1,npts);
x = r.*cos(theta);
y = r.*sin(theta);
clear theta r
scatter3(x,y,z,'filled')
axis vis3d
Now we need to get the angle back from the X,Y,Z coordinates. In my case that's simple because my cylinder is centered at the origin. You might need to change this if your cylinder's axis is somewhere else.
ang = atan2(y,x);
Now the obvious thing would be to do the triangulation with ang and z. That would look like this:
tri = delaunay(ang,z);
trimesh(tri,x,y,z)
axis vis3d
The problem with this approach is that delaunay doesn't know that points near ang=2*pi should be connected to points near ang=0. This results in a seam. You can see that clearly here:
Another way to do this is to take the surface of the cylinder and flatten it onto a 2D plane so that the opening at one end is the origin and the opening at the other end is the point at infinity. That looks something like this (the 30 added to the z is just to get all positive).
x2 = x.*(z+30);
y2 = y.*(z+30);
tri = delaunay(x2,y2);
trimesh(tri,x,y,z)
axis vis3d
This doesn't have a seam. You will notice that it covers over one end and not the other. The one that got covered is the end that we mapped to the origin in 2D. The delaunay function is going to create triangles which cross the origin. It won't do the same at the end that maps to infinity.
Note the trick in both of these. I can use delaunay in a 2D coordinate system to generate triangle indices that I can use back in 3D with the original points. That works as long as the mapping between your 3D and 2D spaces is reasonably well behaved. You can use this trick to do the triangulation in any 2D space you can dream up, as long as you can define a well behaved transformation into it from your original coordinate system.
  1 Comment
Mike Garrity
Mike Garrity on 6 Jan 2016
Sorry, I neglected to mention one other important thing.
It looks like you're using an older version of MATLAB (I'm just guessing from the picture), but in recent versions there are some new tools for triangulating in 3D. If you're using R2015b, you might want to look at the alphashape function or the boundary function. These should do a better job than delaunay does with this data.
But if you're using a version that's older than 2015b, I would suggest taking advantage of what you know about your data to find a 2D space to use delaunay in.

Sign in to comment.


Benjamin Kraus
Benjamin Kraus on 11 Feb 2016
Have you tried using alpha shapes (available starting in MATLAB R2014b):
load('xyzCoord.mat')
shp = alphaShape(x',y',z',1);
plot(shp)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!