Find the first point where a line touches a convex hull - matlab

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.

Related

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.

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

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

Finding the concavness pixel/point in binary map using Matlab

Given an binary mask with an object in Matlab. I am going to find the concavity point of the object boundary. The concavity point I mean here is the deepest concavity point with respect to the Euclidean distance to the convex hull chords K_1, K_2 ,and K_3 in the concavity regions B_1, B_2, B_3, respectively. The red dot indicates the concavity point I want to find, where in concavity region B_1 I draw three lines perpendicular to the chord K_1, the deepest concavity point is the middle one since it has the largest length.
Anyone have efficient way/code to do that? Thanks.
Another figure below gives an example with the convex hull, where the red dot indicates the valid concavity point.
Efficient is relative...
How about computing the convex hull (there are standard algorithms for it) and then shrinking it until it is completely inside the object boundaries. The last point touching is your desired concavity point.
Alternative strategy:
calculate convex hull
find all differences between convex hull and object boundary (have to be straight lines, K1 K2 K3 in your case)
for every line, rotate image such that line is horizontal
take the lowest pixel of the object boundary below the line

How do I break a polyhedron into tetrahedra in MATLAB?

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