Given a point set (i.e a 3XN array of vertices), how can I triangulate it using matlab?
Assuming the point set does represent some surface of an object, and does not contain any noise.
EDIT:
The chosen answer gives a way to create the tetrahedrons of a mesh. I was looking for triangulation; for my specific case of a convex shape, the convex hull (using convhulln as suggested in the answer's comments) was enough.
To create a Delaunay triangulation, you can use the class DELAUNAYTRI:
You create a triangulation object by calling
DT = DelaunayTri(coordinates);
where coordinates is a N-by-3 (or 2) array of vertex coordinates.
To access the triangulation, call
tri = DT.triangulation;
To plot, call e.g.
patch('Vertices',DT.X,'Faces',DT.triangulation)
use delaunay3 and convert the tetrahedral mesh into a triangular one
http://www.mathworks.com/matlabcentral/fileexchange/5355-toolbox-graph/content/toolbox_graph/tet2tri.m
Related
I have an array of normalized vectors (1538 of them) forming a sphere. Also I has an array of numbers of the same size 1538. I want to plot something like this:
I tried the sphere and surf functions but I can't find a way to use my vectors. I figured there should be some way to do this.
Thanks a lot.
I think you can use delaunay to create a triangulation and plot that using trimesh or trisurf.
Both trimesh as trisurf accepts a fourth argument to specify the color of each vertex, add the option 'facecolor','interp' to interpolate the color of each face between vertices.
edit: I experimented a bit further on it, and since it's a sphere, I think convhull is better suited.
Example:
[x,y,z]=sphere(25);
x=x(:);y=y(:);z=z(:);
tri = convhull([x y z]);
C = cos(y);
trisurf(tri,x,y,z,C,'facecolor','interp');
instead of C in the example you can use your own vector of values to specify the color
Is it possible to get the function f(x,y) formed by grid data which represents the convex hull. Actually, I want to get the points(simplex points) that griddata uses to interpolate a particular point. I mean instead of griddata just giving me the end results, is it possible to get the intermediate values.
I have found that it uses delaunay triangulation to form the convex hull. It could be given by delaunay function of matlab. How can I get the simplexes where my interpolation points belong then?
Is it possible to get source code of griddata function in matlab so that I can make the changes?
I want to know how griddata uses linear interpolation.
Does it just consider like four neighbor points of the point where we want to find the value or uses the whole convex hull?
The docs for griddata will guide you in this. Essentially, it does a delaunay triangulation of your point set, then for any new point, determine which simplex the point falls in. Interpolation within a simplex is linear. Thus in 2 dimensions, three points define a triangle, and 3 points determine a locally planar model for z(x,y).
I want to generate a binary mask that has ones for all voxels inside and zeros for all voxels outside a volume. The volume is defined by the convex hull around a set of 3D coordinates (<100; some of the coordinates are inside the volume).
I can get the convex hull using CONVHULLN, but how do I convert that into a binary mask?
In case there is no good way to go via the convex hull, do you have any other idea how I could create the binary mask?
You can solve this problem using the DelaunayTri class and the pointLocation method. Here's an example:
pointMatrix = rand(20,3); %# A set of 20 random 3-D points
dt = DelaunayTri(pointMatrix); %# Create a Delaunay triangulation
[X,Y,Z] = meshgrid(0:0.01:1); %# Create a mesh of coordinates for your volume
simplexIndex = pointLocation(dt,X(:),Y(:),Z(:)); %# Find index of simplex that
%# each point is inside
mask = ~isnan(simplexIndex); %# Points outside the convex hull have a
%# simplex index of NaN
mask = reshape(mask,size(X)); %# Reshape the mask to 101-by-101-by-101
The above example creates a logical mask for a 101-by-101-by-101 mesh spanning the unit volume (0 to 1 in each dimension), with a 1 (true) for the mesh points inside the convex hull of the 3-D point set.
It's late here, so only a very sketchy suggestion:
With the points from your convex hull construct a Delaunay tessellation.
Using the pointLocation method of the DelaunayTri class test every point in your array of pixels.
I expect that this will be very slow, and that there are better solutions, if one comes in my dreams I'll post again tomorrow.
This is a scan conversion problem. Check out section 8 of 3D Scan-Conversion Algorithms for Voxel-Based Graphics.
The algorithm you want is the solid one, and is slightly simpler since you are voxelizing a convex polyhedron whose faces are triangles - each "voxel" run is bounded by two triangles.
I have a polyhedron, with a list of vertices (v) and surfaces (s). How do I break this polyhedron into a series of tetrahedra?
I would particularly like to know if there are any built-in MATLAB commands for this.
For the convex case (no dents in the surface which cause surfaces to cover each other) and a triangle mesh, the simple solution is to calculate the center of the polyhedron and then connect the three corners of every face with the new center.
If you don't have a triangle mesh, then you must triangulate, first. Delaunay triangulation might help.
If there are holes or caves, this can be come arbitrarily complex.
I'm not sure the OP wanted a 'mesh' (Steiner points added) or a tetrahedralization (partition into tetrahedra, no Steiner points added). for a convex polyhedron, the addition of Steiner points (e.g. the 'center' point) is not necessary.
Stack overflow will not allow me to comment on gnovice's post (WTF, SO?), but the proof of the statement "the surfaces of a convex polyhedron are constraints in a Delaunay Tesselation" is rather simple: by definition, a simplex or subsimplex is a member in the Delaunay Tesselation if and only if there is a n-sphere circumscribing the simplex that strictly contains no point in the point set. for a surface triangle, construct the smallest circumscribing sphere, and 'puff' it outwards, away from the polyhedron, towards 'infinity'; eventually it will contain no other point. (in fact, the limit of the circumscribing sphere is a half-space; thus the convex hull is always a subset of the Delaunay Tesselation.)
for more on DT, see Okabe, et. al, 'Spatial Tesselations', or any of the papers by Shewchuk
(my thesis was on this stuff, but I remember less of it than I should...)
I would suggest trying the built-in function DELAUNAY3. The example given in the documentation link resembles Aaron's answer in that it uses the vertices plus the center point of the polyhedron to create a 3-D Delaunay tessellation, but shabbychef points out that you can still create a tessellation without including the extra point. You can then use TETRAMESH to visualize the resulting tetrahedral elements.
Your code might look something like this (assuming v is an N-by-3 matrix of vertex coordinate values):
v = [v; mean(v)]; %# Add an additional center point, if desired (this code
%# adds the mean of the vertices)
Tes = delaunay3(v(:,1),v(:,2),v(:,3)); %# Create the triangulation
tetramesh(Tes,v); %# Plot the tetrahedrons
Since you said in a comment that your polyhedron is convex, you shouldn't have to worry about specifying the surfaces as constraints in order to do the triangulation (shabbychef appears to give a more rigorous and terse proof of this than my comments below do).
NOTE: According to the documentation, DELAUNAY3 will be removed in a future release and DelaunayTri will effectively take its place (although currently it appears that defining constrained edges is still limited to only 2-D triangulations). For the sake of completeness, here is how you would use DelaunayTri and visualize the convex hull (i.e. polyhedral surface) as well:
DT = DelaunayTri(v); %# Using the same variable v as above
tetramesh(DT); %# Plot the tetrahedrons
figure; %# Make new figure window
ch = convexHull(DT); %# Get the convex hull
trisurf(ch,v(:,1),v(:,2),v(:,3),'FaceColor','cyan'); %# Plot the convex hull