Check if a point is inside a 4-points convex hull - algorithm

I have a problem to prove if a number of 4 points can form a convex hull and if a 5th points is inside the hull or not. I managed to solve the problem of the convex hull using triangles, however I don't know how to prove if the 5th point is inside the hull created by the other 4 points.
Any ideas?
Thank you!

Assuming that you're asking about points on a plane - there is a standard approach for any polygon (convex or not) with any number of vertices.

Call your points a,b,c,d. They form a tetrahedron.
If the tetrahedron is not degenerated, the points are the vertex points (extreme points) of their convex hull.
To check this, check if a,b,c form a non-degenerated triangle. To do this compute the normal vector (call it n) of the triangle (b-a) cross (c-a). If it is zero then the triangle is degenerated, otherwise it is not..
The check if d is not in the plane of this triangle. It is if (d-a) dot product with n is zero. If so, the tetrahedron is degenerated.
Compute the normal vector for each of the 4 triangles of the tetrahedron.
Each normal vector together with (any) point of the triangle describes a half-space;
that is, all the points on one side of a plane.
Let n be the normal vector and p a point of the triangle.
A point q is said to be inside of the half-space, if n dot (q - p) is negative.
Check for all 4 triangles, if the forth point is inside. If not, adjust the sign of the normal vector.
A point is inside the tetrahedron if it is inside for all 4 half-spaces.

If you were able to find the convex hull of the four points, then you are able to split the quadrilateral in two triangles by a diagonal (unless one of the points was interior, then you have a single triangle left).
So it all amounts to a point-in-triangle test.
Again, being able to construct a convex hull, you must already have the area test handy (sign of the area of a triangle). You fifth point is inside a given triangle when the area test reports the same sign for the three triangles formed by the point and the three edges of the given triangle.

Related

Triangle enclosing the biggest number of points

Given set of 2D points find a triangle built from those points, that encloses the biggest number of points.
Brutal algorithm for this is just building triangles from every possible triad of points and checking how many points they enclose, but time complexity of this solution is O(n^4).
For the optimal solution I thought about first finding the convex hull of those points and arranging points inside this hull with some structure, but I can't figure it out.
Do you have any ideas about the optimal solution for this kind of problem?
In a set of n points, there are (n choose 3) triangles, and using brute force to check for each point whether it is contained in each triangle indeed has O(n4) complexity. To give a practical example of a few set sizes:
points: 100 1,000 10,000
triangles: 161,700 166,167,000 166,616,670,000
checks: 15,684,900 165,668,499,000 1,665,666,849,990,000
Below are a few geometrical ideas; they don't lead straight to a solution, but they can reduce the number of triangles that have to be checked.
Counter-example for convex hull
First of all, using only points on the convex hull is not guaranteed to give the optimal solution. Consider this counter-example:
The convex hull is the red rectangle. However, if we use two of its sides and a diagonal to form a triangle, the diagonal will cut through the central point cluster and leave out some of the points. And even if we only use 1 or 2 corners of the rectangle, combined with a point in the center, it will always cut through the blue triangle and leave out some points. The blue triangle, which has no points on the convex hull, is in fact the optimal solution.
Triangle contained in triangle
If you consider a triangle abc, and three points d, e and f contained within it, then the triangle def cannot be the triangle which contains the most points, because triangle abc contains at least three more points. Triangles made from a combination of points from abc and def, like abd, also contain fewer points than abc.
This means that finding a triangle and some points contained within it, allows you to discard a number of triangles. In the next paragraphs, we will use this idea to discard as many triangles as possible from having to be checked.
Expanding a triangle
If we consider a triangle made from three randomly chosen points a, b and c (named clock-wise), and then check whether all other points are on the left of right side of the lines |ab|, |bc| and |ca|, the points are partitioned into 7 zones:
If we replace a corner point of the triangle by a point in the adjacent coloured zone, e.g. zone LRL for point a, we get a larger triangle that contains triangle abc. If we randomly pick three points from zones LRL, LLR and RLL, we can expand the triangle like this:
We can then partition the points again using this new triangle a'b'c' (points already in zone RRR can be added to the new zone RRR without checking) and expand the triangle again as long as there is at least one point in the zones LRL, LLR or RLL.
If we have caught enough points inside the expanded triangle, we can now use the brute force algorithm, but skip any triangle which doesn't have a point outside of the expanded triangle a'b"c'.
If we haven't caught enough points to make that feasible, we can try again with another three random points. Note, however, that you should not use the union of the points contained within several triangles; three points which are each contained in another triangle, but not in the same triangle, can still be the triangle containing the most points.
Excluding triangles in multiple steps
We could repeatedly choose a random triangle, expand it maximally, and then mark the triangles made from three points on or inside the triangle, to then exclude these from the check. This would require storing a boolean for all possible triangles, e.g. in a 3D bit array, so it is only feasible for sets up to a few thousand points.
To simplify things, instead of expanding random triangles, we could do this with a number of randomly chosen triangles, or triangles made from points on the convex hull, or points far apart when sorted in the x or y-direction, or ... But any of these methods will only help us to find triangles which can be excluded, they will not give us optimal (or even good-enough) triangles by themselves.

Is there an algorithm to reduce the sides of a Polygon while keeping all Points within the Polygon?

I'm trying to reduce a polygon with 4+ vertexes to a polygon with 4 sides to perform perspective transformation later on. I need to find the polygon with 4 sides which contains all the points the original polygon had. Basicly what i want is something like this:
The real problem here is that the polygon must only get bigger... if it gets smaller with let's say a polygon approximation algorithm it's not usefull anymore...
EDIT:
I need the optimal solution, that means that the resulting 4-sided polygon has as little area as possible!
EDIT2:
What would also work is an convex hull algorithm where I can determine the number of sides the resulting polygon must have!
The easiest solution is to take the bounding box of your polygon, the rectangle defined by the min and max of the x values of your vertices, and the min and max of the y values.
If you need a 4-vertex polygon with smaller area, an idea could be:
Take the convex hull of your polygon.
Select one side for deletion, and extend its neighboring sides to the point where they meet. Do this only if they really meet at the end where the deleted side was. Maybe you want to select the side to be deleted by the smallest area that this deletion adds to the polygon (that's the triangle formed by the deleted side and the new intersection point).
Repeat until only 4 sides are left.

Point inside arbitrary polygon with partitions

Say I have a polygon. It can be a convex one or not, it doesn't matter, but it doesn't have holes. It also has "inner" vertices and edges, meaning that it is partitioned.
Is there any kind of popular/known algorithm or standard procedures for when I want to check if a point is inside that kind of polygon?
I'm asking because Winding Number and Ray Casting aren't accurate in this case
Thanks in advance
You need to clarify what you mean by 'inner vertices and edges'. Let's take a very general case and hope that you find relevance.
The ray casting (point in polygon) algorithm shoots off a ray counting the intersections with the sides of the POLYGON (Odd intersections = inside, Even = outside).
Hence it accurately gives the correct result regardless of whether you start from inside the disjoint trapezoidal hole or the triangular hole (inner edges?) or even if a part of the polygon is completely seperated and/or self intersecting.
However, in what order do you feed the vertices of the polygon such that all the points are evaluated correctly?
Though this is code specific, if you're using an implementation that is counting every intersection with the sides of the polygon then this approach will work -
- Break the master polygon into polygonal components. eg - trapezoidal hole is a polygonal component.
- Start with (0,0) vertex (doesn't matter whether (0,0) actually lies wrt your polygon) followed by the first component' vertices, repeating its first vertex after the last vertex.
- Include another (0,0) vertex.
- Include the next component , repeating its first vertex after the last vertex.
- Repeat the above two steps for each component.
- End with a final (0,0) vertex.
2 component eg- Let the vertices of the two components be (1x,1y), (2x,2y), (3x,3y) and (Ax,Ay), (Bx,By), (Cx,Cy). Where (Ax,Ay), (Bx,By), (Cx,Cy) could be anything from a disjoint triangular hole, intersecting triangle or separated triangle.
Hence , the vertices of a singular continous polygon which is mathematically equivalent to the 2 components is -
(0,0),(1x,1y),(2x,2y),(3x,3y),(1x,1y),(0,0),(Ax,Ay),(Bx,By),(Cx,Cy),(Ax,Ay),(0,0)
To understand how it works, try drawing this mathematically equivalent polygon on a scratch pad.-
1. Mark all the vertices but don't join them yet.
2. Mark the repeated vertices separately also. Do this by marking them close to the original points, but not on them. (at a distance e, where e->0 (tends to/approaches) ) (to help visualize)
3. Now join all the vertices in the right order (as in the example above)
You will notice that this forms a continuous polygon and only becomes disjoint at the e=0 limit.
You can now send this mathematically equivalent polygon to your ray casting function (and maybe even winding number function?) without any issues.

How to calculate the cross section of a tetrahedron

I have a volume mesh which is actually a tetrahedral mesh. I would like to calculate the cross-section of this mesh given a plane function, saying z = 0. I can imagine that the cross section of a tetrahedron is either a triangle or a quadrilateral. For the first case, triangle, once I calculate the 3 cross points I can get it; but for the second case, how can I make the quadrilateral become 2 triangles? My problem is I cannot determine the diagonal of the quadrilateral.
Intersect all tetrahedron edges by the plane. You will get 3 or 4 intersection points.
If 3 points then a single triangle.
If 4 points, they form a convex quadrilateral. Take any 3 points, that form a first triangle. The other triangle if formed of the fourth point and the two endpoints of the edge that has this point to its right.
Alternatively (for a more general solution), tag the intersection points with the indexes of the faces incident on the edge, and reconstruct the ring of labels.
Ex: edges are common to faces AB, CD, DA and BC; then the section is ABCD.
This answer outlines a general volume-plane intersection algorithm. It will return the vertices of the intersection in order, so it's easy to determine the diagonal of your quadrilateral.

How to find convex hull in a 3 dimensional space

Given a set of points S (x, y, z). How to find the convex hull of those points ?
I tried understanding the algorithm from here, but could not get much.
It says:
First project all of the points onto the xy-plane, and find an edge that is definitely on the hull by selecting the point with highest y-coordinate and then doing one iteration of gift wrapping to determine the other endpoint of the edge. This is the first part of the incomplete hull. We then build the hull iteratively. Consider this first edge; now find another point in order to form the first triangular face of the hull. We do this by picking the point such that all the other points lie to the right of this triangle, when viewed appropriately (just as in the gift-wrapping algorithm, in which we picked an edge such that all other points lay to the right of that edge). Now there are three edges in the hull; to continue, we pick one of them arbitrarily, and again scan through all the points to find another point to build a new triangle with this edge, and repeat this until there are no edges left. (When we create a new triangular face, we add two edges to the pool; however, we have to first check if they have already been added to the hull, in which case we ignore them.) There are O(n) faces, and each iteration takes O(n) time since we must scan all of the remaining points, giving O(n2).
Can anyone explain it in a more clearer way or suggest a simpler alternative approach.
Implementing the 3D convex hull is not easy, but many algorithms have been implemented, and code is widely available. At the high end of quality and time investment to use is CGAL. At the lower end on both measures is my own C code:
In between there is code all over the web, including this implementation of QuickHull.
I would suggest first try an easier approach like quick hull. (Btw, the order for gift wrapping is O(nh) not O(n2), where h is points on hull and order of quick hull is O(n log n)).
Under average circumstances quick hull works quite well, but processing usually becomes slow in cases of high symmetry or points lying on the circumference of a circle. Quick hull can be broken down to the following steps:
Find the points with minimum and maximum x coordinates, those are
bound to be part of the convex.
Use the line formed by the two points to divide the set in two
subsets of points, which will be processed recursively.
Determine the point, on one side of the line, with the maximum
distance from the line. The two points found before along with this
one form a triangle.
The points lying inside of that triangle cannot be part of the
convex hull and can therefore be ignored in the next steps.
Repeat the previous two steps on the two lines formed by the
triangle (not the initial line).
Keep on doing so on until no more points are left, the recursion has
come to an end and the points selected constitute the convex hull.
See this impementaion and explanation for 3d convex hull using quick hull algorithm.
Gift wrapping algorithm:
Jarvis's match algorithm is like wrapping a piece of string around the points. It starts by computing the leftmost point l, since we know that the left most point must be a convex hull vertex.This process will take linear time.Then the algorithm does a series of pivoting steps to find each successive convex hull vertex untill the next vertex is the original leftmost point again.
The algorithm find the successive convex hull vertex like this: the vertex immediately following a point p is the point that appears to be furthest to the right to someone standing at p and looking at the other points. In other words, if q is the vertex following p, and r is any other input point, then the triple p, q, r is in counter-clockwise order. We can find each successive vertex in linear time by performing a series of O(n) counter-clockwise tests.
Since the algorithm spends O(n) time for each convex hull vertex, the worst-case running time is O(n2). However, if the convex hull has very few vertices, Jarvis's march is extremely fast. A better way to write the running time is O(nh), where h is the number of convex hull vertices. In the worst case, h = n, and we get our old O(n2) time bound, but in the best case h = 3, and the algorithm only needs O(n) time. This is a so called output-sensitive algorithm, the smaller the output, the faster the algorithm.
The following image should give you more idea
GPL C++ code for finding 3D convex hulls is available at http://www.newtonapples.net/code/NewtonAppleWrapper_11Feb2016.tar.gz and a description of the O(n log(n)) algorithm at http://www.newtonapples.net/NewtonAppleWrapper.html
One of the simplest algorithms for convex hull computation in 3D was presented in the paper The QuickHull algorithm for Convex Hulls by Barber, etc from 1995. Unfortunately the original paper lacks any figures to simplify its understanding.
The algorithm works iteratively by storing boundary faces of some convex set with the vertices from the subset of original points. The remaining points are divided on the ones already inside the current convex set and the points outside it. And each step consists in enlarging the convex set by including one of outside points in it until no one remains.
The authors propose to start the algorithm in 3D from any tetrahedron with 4 vertices in original points. If these vertices are selected so that they are on the boundary of convex hull then it will accelerate the algorithm (they will not be removed from boundary during the following steps). Also the algorithm can start from the boundary surface containing just 2 oppositely oriented triangles with 3 vertices in original points. Such points can be selected as follows.
The first point has with the minimal (x,y,z) coordinates, if compare coordinates lexicographically.
The second point is the most distant from the first one.
The third point is the most distant from the line through the first two points.
The next figure presents initial points and the starting 2 oppositely oriented triangles:
The remaining points are subdivided in two sets:
Black points - above the plane containing the triangles - are associated with the triangle having normal oriented upward.
Red points - below the plane containing the triangles - are associated with the triangle having normal oriented downward.
On the following steps, the algorithm always associates each point currently outside the convex set with one of the boundary triangles that is "visible" from the point (point is within positive half-space of that triangle). More precisely each outside point is associated with the triangle, for which the distance between the point and the plane containing the triangle is the largest.
On each step of algorithm the furthest outside point is selected, then all faces of the current convex set visible from it are identified, these faces are removed from the convex set and replaced with the triangles having one vertex in furthest point and two other points on the horizon ridge (boundary of removed visible faces).
On the next figure the furthest point is pointed by green arrow and three visible triangles are highlighted in red:
Visible triangles deleted, back faces and inside points can be seen in the hole, horizon ridge is shown with red color:
5 new triangles (joining at the added point) patch the hole in the surface:
The points previously associated with the removed triangles are either become inner for the updated convex set or redistributed among new triangles.
The last figure also presents the final result of convex hull computation without any remaining outside points. (The figures were prepared in MeshInspector application, having this algorithm implemented.)

Resources