How to find convex hull in a 3 dimensional space - algorithm

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.)

Related

How to compute the set of polygons from a set of overlapping circles?

This question is an extension on some computation details of this question.
Suppose one has a set of (potentially overlapping) circles, and one wishes to compute the area this set of circles covers. (For simplicity, one can assume some precomputation steps have been made, such as getting rid of circles included entirely in other circles, as well as that the circles induce one connected component.)
One way to do this is mentioned in Ants Aasma's and Timothy's Shields' answers, being that the area of overlapping circles is just a collection of circle slices and polygons, both of which the area is easy to compute.
The trouble I'm encountering however is the computation of these polygons. The nodes of the polygons (consisting of circle centers and "outer" intersection points) are easy enough to compute:
And at first I thought a simple algorithm of picking a random node and visiting neighbors in clockwise order would be sufficient, but this can result in the following "outer" polygon to be constructed, which is not part of the correct polygons.
So I thought of different approaches. A Breadth First Search to compute minimal cycles, but I think the previous counterexample can easily be modified so that this approach results in the "inner" polygon containing the hole (and which is thus not a correct polygon).
I was thinking of maybe running a Las Vegas style algorithm, taking random points and if said point is in an intersection of circles, try to compute the corresponding polygon. If such a polygon exists, remove circle centers and intersection points composing said polygon. Repeat until no circle centers or intersection points remain.
This would avoid ending up computing the "outer" polygon or the "inner" polygon, but would introduce new problems (outside of the potentially high running time) e.g. more than 2 circles intersecting in a single intersection point could remove said intersection point when computing one polygon, but would be necessary still for the next.
Ultimately, my question is: How to compute such polygons?
PS: As a bonus question for after having computed the polygons, how to know which angle to consider when computing the area of some circle slice, between theta and 2PI - theta?
Once we have the points of the polygons in the right order, computing the area is a not too difficult.
The way to achieve that is by exploiting planar duality. See the Wikipedia article on the doubly connected edge list representation for diagrams, but the gist is, given an oriented edge whose right face is inside a polygon, the next oriented edge in that polygon is the reverse direction of the previous oriented edge with the same head in clockwise order.
Hence we've reduced the problem to finding the oriented edges of the polygonal union and determining the correct order with respect to each head. We actually solve the latter problem first. Each intersection of disks gives rise to a quadrilateral. Let's call the centers C and D and the intersections A and B. Assume without loss of generality that the disk centered at C is not smaller than the disk centered at D. The interior angle formed by A→C←B is less than 180 degrees, so the signed area of that triangle is negative if and only if A→C precedes B→C in clockwise order around C, in turn if and only if B→D precedes A→D in clockwise order around D.
Now we determine which edges are actually polygon boundaries. For a particular disk, we have a bunch of angle intervals around its center from before (each sweeping out the clockwise sector from the first endpoint to the second). What we need amounts to a more complicated version of the common interview question of computing the union of segments. The usual sweep line algorithm that increases the cover count whenever it scans an opening endpoint and decreases the cover count whenever it scans a closing endpoint can be made to work here, with the adjustment that we need to initialize the count not to 0 but to the proper cover count of the starting angle.
There's a way to do all of this with no trigonometry, just subtraction and determinants and comparisons.

Minimum bounding rectangle of polygon

Let's say we have a class/struct Point
class Point
{
int x;
int y;
}
and a class Polygon that contains list of Points
class Polygon
{
List<Point> points;
Path(List<Point> points)
{
//some implementation
}
}
I am interested in finding the Minimal bounding rectangle points of the Polygon(https://en.wikipedia.org/wiki/Minimum_bounding_rectangle). The found minimal bounding rectangle sides might not be parallel to both axis , so I am trying to find an algorithm written in Java,C#,C++ .Can anyone propose or link such a solution, thanks!
It is possible to construct minimal bounding box (both min-area and min-perimeter) using Rotating Calipers approach.
You can find description at this wayback archive page
The minimum area rectangle enclosing a convex polygon P has a side
collinear with an edge of the polygon.
The above result dramatically restricts the range of possible
rectangles. Not only is it not necessary to check all directions, but
only as many as the polygon's number of edges.
Illustrating the above result: the four lines of support (red), with
one coinciding with an edge, determine the enclosing rectangle (blue).
A simple algorithm would be to compute for each edge the corresponding
rectangle collinear with it. But the construction of this rectangle
would imply computing the polygon's extreme points for each edge, a
process that takes O(n) time (for n edges). The entire algorithm would
then have quadratic time complexity.
A much more efficient algorithm can be found. Instead of recomputing
the extreme points, it is possible to update them in constant time,
using the Rotating Calipers. Indeed, consider a convex polygon, with a
two pair of lines of support through all four usual extreme points in
the x and y directions. The four lines already determine an enclosing
rectangle for the polygon. But unless the polygon has a horizontal or
vertical edge, this rectangle is not a candidate for the minimum area.
However, the lines can be rotated until the above condition is
satisfied. This procedure is at the heart of the following algorithm.
The input is assumed to be a convex polygon with n vertices given in
clockwise order.
Compute all four extreme points for the polygon, and call them xminP,
xmaxP, yminP ymaxP.
Construct four lines of support for P through all four points. These
determine two sets of "calipers".
If one (or more) lines coincide with an edge, then compute the area of
the rectangle determined by the four lines, and keep as minimum.
Otherwise, consider the current minimum area to be infinite.
Rotate the lines clockwise until one of them coincides with an edge of
its polygon.
Compute the area of the new rectangle, and compare it to the current
minimum area. Update the minimum if necessary, keeping track of the
rectangle determining the minimum.
Repeat steps 4 and 5, until the lines have been rotated an angle
greater than 90 degrees. Output the minimum area enclosing rectangle.
Because two pairs of "calipers" determine an enclosing rectangle, this
algorithm considers all possible rectangles that could have the
minimum area. Furthermore, aside from the initialization, there are
only as many steps in the algorithm's main loop as there are vertices.
Thus the algorithm has linear time complexity.
You can do this as follows:
Find the convex hull of the polygon points. A popular method is the Graham scan.
For each edge of the convex hull, find the minimum bounding rectangle that must have one side overlapping with that edge, so that the convex hull's edge is a subsegment of that rectangle's side.
Find the two perpendicular sides of the rectangle by walking along the convex hull vertices, and projecting the vertex to the first side, retaining the two that have all other projections between them. The final opposite side can be found in a similar manner. The vertices that lie on the rectangle, should be the starting point for when this step is executed again for the next edge on the convex hull (step 2).
Calculate the size of these rectangles, and retain the minimal one.
The complexity of this algorithm is determined by the first step, which is O(nlogn). The second step is O(n), as you have a selection of one edge and 3 vertices that rotates around the convex hull, visiting each edge once, and each vertex 3 times.

Given a set of points in the plane, find a (not necessarily convex) polygon of minimal area containing them

Given a set of points in the plane, I want to find the smallest polygon containing all the points. More precisely, the vertices of this polygon must be a subset of the original set of points.
The easiest approach would be to find the convex hull, which can be computed in O(N log(N)) time using Graham's scanning algorithm, but I would ideally like to drop the requirement that the polygon be convex. Are there any standard approaches to this? I imagine this problem is a fair bit harder because it seems to me there is not guaranteed to be a unique solution.
Do you need the absolutely smallest area solution or just a 'fairly good' solution. If the latter then one possible algorithm would be:
1) calculate the convex hull of all your points - all these points must be vertexes of your final solution.
2) calculate the convex hull of the remaining points - repeat this process until you have no points left. You will end up with n non-intersecting convex hulls.
3) Determine (possibly by greedy algorithm), where to join these hulls to form a single contiguous path between all the points by adding pairs of lines between neighboring points in neighboring hulls and removing lines in the hulls.
This might not be the minimal area but should be a fairly good solution.
Added comment: Greedy removal from the outermost hull to the next inner one should be by removing the largest area region separating the two. Greedy removal from the second hull to the next inner one should be by 'removing' (which is actually retaining) the smallest area separating the hulls...and so on inwards swapping between largest and smallest areas...
Picture added to explain better than my 100 words.

rectilinear polygon intersection

I am looking for / trying to develop an optimal algorithm for rectilinear polygon intersection with rectangles. The polygons I am testing do not have holes.
Answers like those given here and here are for very general polygons, and the solutions are understandably quite complex.
Hoping that the S.O. community can help me document algorithms for the special cases with just rectilinear polygons.
I am looking for the polygon filled in green in the image below:
The book Computational Geometry: an Introduction by Preparata and Shamos has a chapter on rectilinear polygons.
Use a sweep line algorithm, making use of the fact that a rectilinear polygon is defined by its vertices.
Represent the vertices along with the rectangle that they belong to, i.e. something like (x, y, #rect). To this set of points, add those points that result from the intersections of all edges. These new points are of the form (x, y, final), since we already know that they belong to the resulting set of points.
Now:
sort all points by their x-value
use a sweep line, starting at the first x-coordinate; for each new point:
if it's a "start point", add it to a temporary set T. Mark it "final" if it's a point from rectangle A and between y-coordinates from points from rectangle B in T (or vice versa).
if it's an "end point", remove it and its corresponding start point from T.
After that, all points that are marked "final" denote the vertices of the resulting polygon.
Let N be the total number of points. Further assuming that testing whether we should mark a point as being "final" takes time O(log(n)) by looking up T, this whole algorithm is in O(N*log(N)).
Note that the task of finding all intersections can be incorporated into the above algorithm, since finding all intersections efficiently is itself a sweep line algorithm usually. Also note that the resulting set of points may contain more than one polygon, which makes it slightly harder to reconstruct the solution polygons out of the "final" vertices.

Largest triangle from a set of points [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to find largest triangle in convex hull aside from brute force search
I have a set of random points from which i want to find the largest triangle by area who's verticies are each on one of those points.
So far I have figured out that the largest triangle's verticies will only lie on the outside points of the cloud of points (or the convex hull) so i have programmed a function to do just that (using Graham scan in nlogn time).
However that's where I'm stuck. The only way I can figure out how to find the largest triangle from these points is to use brute force at n^3 time which is still acceptable in an average case as the convex hull algorithm usually kicks out the vast majority of points. However in a worst case scenario where points are on a circle, this method would fail miserably.
Dose anyone know an algorithm to do this more efficiently?
Note: I know that CGAL has this algorithm there but they do not go into any details on how its done. I don't want to use libraries, i want to learn this and program it myself (and also allow me to tweak it to exactly the way i want it to operate, just like the graham scan in which other implementations pick up collinear points that i don't want).
Don't know if this help, but if you choose two points from the convex hull and rotate all points of the hull so that the connecting line of the two points is parallel to the x-Axis, either the point with the maximum or the one with the minimum y-coordinate forms the triangle with the largest area together with the two points chosen first.
Of course once you have tested one point for all possible base lines, you can remove it from the list.
Here's a thought on how to get it down to O(n2 log n). I don't really know anything about computational geometry, so I'll mark it community wiki; please feel free to improve on this.
Preprocess the convex hull by finding for each point the range of slopes of lines through that point such that the set lies completely on one side of the line. Then invert this relationship: construct an interval tree for slopes with points in leaf nodes, such that when querying with a slope you find the points such that there is a tangent through those points.
If there are no sets of three or more collinear points on the convex hull, there are at most four points for each slope (two on each side), but in case of collinear points we can just ignore the intermediate points.
Now, iterate through all pairs of points (P,Q) on the convex hull. We want to find the point R such that triangle PQR has maximum area. Taking PQ as the base of the triangle, we want to maximize the height by finding R as far away from the line PQ as possible. The line through R parallel to PQ must be such that all points lie on one side of the line, so we can find a bounded number of candidates in time O(log n) using the preconstructed interval tree.
To improve this further in practice, do branch-and-bound in the set of pairs of points: find an upper bound for the height of any triangle (e.g. the maximum distance between two points), and discard any pair of points whose distance multiplied by this upper bound is less than the largest triangle found so far.
I think the rotating calipers method may apply here.
Off the top of my head, perhaps you could do something involving gridding/splitting the collection of points up into groups? Maybe... separating the points into three groups (not sure what the best way to do that in this case would be, though), doing something to discard those points in each group that are closer to the other two groups than other points in the same group, and then using the remaining points to find the largest triangle that can be made having one vertex in each group? This would actually make the case of all points being on a circle a lot simpler, because you'd just focus on the points that are near the center of the arcs contained within each group, as those would be the ones in each group furthest from the other two groups.
I'm not sure if this would give you the proper result for certain triangles/distributions of points, though. There may be situations where the resultant triangle isn't of optimal area, either because the grouping and/or the vertex choosing aren't/isn't optimal. Something like that.
Anyway, those are my thoughts on the problem. I hope I've at least been able to give you ideas for how to work on it.
How about dropping a point at a time from the convex hull? Starting with the convex hull, calculate the area of the triangle formed by each triple of adjacent points (p1p2p3, p2p3p4, etc.). Find the triangle with minimum area, then drop the middle of the three points that formed that triangle. (In other words, if the smallest area triangle is p3p4p5, drop P4.) Now you have a convex polygon with N-1 points. Repeat the same procedure until you are left with three points. This should take O(N^2) time.
I would not be at all surprised if there is some pathological case where this doesn't work, but I expect that it would work for the majority of cases. (In other words, I haven't proven this, and I have no source to cite.)

Resources