how can I identify points are inside convex hull in Matlab separately - matlab

I created 3D convex hull plot in Matlab. It seems in this function, some of laser points were used for facets of convex hull, but some other points are situated inside convex hull . My question is that how can I identify these points in Matlab separately. Which way is applicable for calculating the perpendicular distance of these points situated inside of convex hull to the nearest convex hull facet (distance from each point to the closest facet of the convex hull)?
I would be very grateful if you could introduce me some references about convex hull function.

On the Matlab file exchange, there is a great function called inhull, which will test whether your points are inside the hull or not. I'm not sure that it provides the distance from the points to the nearest facet, but perhaps the methods used in the code would be simple to change to provide this output.

Check out the function, tsearchn.
The following code creates a sphere in 3D and computes the delaunay triangularization. We then set-up testpoints variable with points to test if they are inside the sphere or not. t returns indices back into TRI for tetrahedra facet that are closest to the point or NaN if the point is outside the sphere.
[X,Y,Z] = sphere(N);
TRI = delaunay(X(:),Y(:),Z(:));
testpoints = [0 0 0; 0 .5 0; 1 2 0]
t = tsearchn([X(:) Y(:) Z(:)],TRI,testpoints)
figure;
trisurf(TRI,X(:),Y(:),Z(:));
Output is,
t =
8182
7779
NaN

Related

Find the first point where a line touches a convex hull

First I have ploted a convex hull for given points using convexHull Matlab function:
x = [4*rand(10,1)-2];
y = [rand(10,1)+5];
DT = delaunayTriangulation(x,y);
C = convexHull(DT);
plot(DT.Points(:,1),DT.Points(:,2),'.','MarkerSize',10)
hold on
plot(DT.Points(C,1),DT.Points(C,2),'r')
This convex hull is just an example, it can be any other convex hull. We assume that convex hull is inside parabola y=x^2.
Then I want to find first point on convex hull that touches line y=[(a^2+1)/a]x-1, when we start from a=1 and it can go until a=+\infty if never touches convex hull (when convex hull is on LHS).
How that can be accomplished? My final goal is to find a on the figure.
For each corner (x_i, y_i) of the polygon solve quadratic equation for a_i.
y_i*a_i = (a_i^2 + 1)*x_i - 1
You can obtain the equation by putting the point coordinates into the line equation. Next, discard solutions that are not relevant for You (a<1). Once this is done, sort solutions by a. If you also need the index of corresponding vertex, sort function in Matlab gives you indexing array as an additional output. You can then plot the line.
As a corner case, the line may hit two vertices. This is not a problem if you just need a. If you want the vertex id, just discard one arbitrarily, or use some additional rule.

Computing the Convex Hull of two non intersecting polygon in scipy

Is there any scipy method that computes the Convex hull of two non intersecting polygon? I have 2 set of points P1 and P2 and their convex hulls CH(P1) and CH(P2), where the hulls are non intersecting. I want to find the Convex hull of union of points in P1 and P2. Is there any build in method in scipy?
Documentation for Scipy's convex hull implementation can be found here. Simply concatenate the two arrays of points to obtain their union. Feed this set to the convex hull algorithm.
Every point in each polygon lies within the convex hull of its polygon. In turn, both polygons have their convex hull contained entirely inside the larger convex hull. So, every point in each polygon lies within the larger convex hull, meaning it is also valid for the complete union of polygon points.

find area of 3D polygon

Given a matrix nx3 that represents n points in 3D space. All points lie on a plane. The plane is given by its normal and a point lying on it. Is there a Matlab function or any Matlabby way to find the area directly from the matrix?
What i was trying to do is write a function that first computes the centroid,c, of the n-gon. Then form triangles : (1,2,c),(2,3,c),...,(n,1,c). Compute their area and sum up. But then i had to organise the polygon points in a cyclic order as they were unordered which i figured was hard. Is there a easy way to do so?
Is there a easier way in Matlab to just call some function on the matrix?
Here is perhaps an easier method.
First suppose that your plane is not parallel to the z-axis.
Then project the polygon down to the xy-plane simply by removing the 3rd coordinate.
Now compute the area A' in the xy-plane by the usual techniques.
If your plane makes an angle θ with the xy-plane, then your 3D
area A = A' / cos θ.
If your plane is parallel to the z-axis, do the same computation
w.r.t. the y-axis instead, projecting to the xz-plane.
To project from 3D to the plane normal to N, take some non-parallel vector A and compute the cross products U = N x A and V = N x U. After normalizing U and V, the dot products P.U and P.V give you 2D coordinates in the plane.
Joseph's solution is even easier (I'd recommend to drop the coordinate with the smallest absolute cosine).
You said the points all lie on a plane and you have the normal. You should then be able to reproject the 3-D points into 2-D coordinates in a new 2-D basis. I am not aware of a canned function in Matlab to do this , but coding it should not be difficult, this answer from Math.SE and this Matlab Central post should help you.
If you already solved the problem of finding the coordinates of the points in the 2-D plane they are in, you could use the Matlab boundary or convex hull function to compute the area of the boundary or convex hull enclosing the points.
[k,v]= boundary(x,y)
or
[k,v] =convhull(x,y)
where k is the vector of indices into points x,y, that define the boundary or convex hull, v is the area enclosed, and x, y are vectors of the x and y coordinates of your points.
What you were describing with trying to find triangles with the points sounds like a first attempt toward Delaunay triangulation. I think more recent versions of Matlab have functions to do Delaunay triangulation as well.

Given Polygon and Fix Points, Find the Triangle Meshes

Let's say I have a polygon, and I want to mesh it. In order to further put constraints on the mesh I get, I will supply a list of fix points ( which must lie inside the polygon) so that they must be connected by the triangle elements generated.
What is the matlab command to do it? I tried delaunay command, but it can't work on concave polygon because the delaunay command will always return me a list of elements that encompass a convex area.
The function you want to use is DelaunayTri, and you would follow these steps to do it:
Create a list of the edge points in your polygon.
Take all of the vertex points of your polygon and combine them with the additional fixed points you want to include inside the polygon.
Create a constrained triangulation (as I've illustrated in other answers here and here).
As you noted, this will create a triangulation of the convex hull (even if you have a concave polygon), so you would have to remove triangles outside of the constrained edges using the method inOutStatus (also illustrated in the answers linked above).
Here's some sample code:
polygonVertices = [0 0;... %# Concave polygon vertices
0 1;...
1 1;...
0.5 0.5;...
1 0];
polygonEdges = [1 2;... %# Polygon edges (indices of connected vertices)
2 3;...
3 4;...
4 5;...
5 1];
otherVertices = [0.5.*rand(5,1) rand(5,1)]; %# Additional vertices to be added
%# inside the polygon
vertices = [polygonVertices; otherVertices]; %# Collect all the vertices
dt = DelaunayTri(vertices,polygonEdges); %# Create a constrained triangulation
isInside = inOutStatus(dt); %# Find the indices of inside triangles
faces = dt(isInside,:); %# Get the face indices of the inside triangles
And now the variables faces and vertices can be used to plot the meshed polygon.
Working with older versions of MATLAB...
Looking through the archived version documentation (note: a MathWorks account is required to do so), one can see that DelaunayTri first appeared in version 7.8.0 (2009a). Prior to that, the only built-in functionality available for performing 2-D Delaunay triangulation was delaunay, which was based on Qhull and was thus unable to support constrained triangulations or triangulations of non-convex surfaces.
The newer DelaunayTri uses CGAL. As such, one option for users of versions older than 7.8.0 is to create MEX-files to interface CGAL routines in MATLAB. For example, if you're faced with triangulating a concave polygon, you can create a MEX-file to interface one of the convex partitioning routines in CGAL in order to break the concave polygon into a set of convex polygons. Then delaunay could be used to triangulate each convex polygon, and the final set of triangulations grouped into one larger triangulation of the concave polygon.

Converting convex hull to binary mask

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.