given a convex polgyon and a number N, how do I find the smallest polygon that
contains every point from the original polygon
has exactly N corner points
For example, suppose I have a set of points and compute the convex hull for them (green). Now I want to find the smallest quadrangle that contains all the points (red)
It is easy to see that any other polygon with 4 corners would either be bigger or fail to contain all the points. But how do I find this polygon in the general case?
EDIT:
With smallest polygon I mean the the one that covers the smallest area, although I am not sure whether the smallest circumference would give different results.
I added two more example pictures that unfortunately do not seem to work with the 'remove edges' approach in one of the answers
Some background information:
The goal is to accurately determine shapes with image recognition. For example take a foto of a cuboid. All points inside the box in the 2D-photo will be contained in a 6-corner convex polygon. However since real-world shapes do not have perfect corners, and the camera adds some blur, the edges of this polygon will be rounded.
See the attached image from the question Getting corners from convex points
You need to define the notion of "smallest" in your question. Whatever your definition,
this question has been heavily studied in the computational geometry literature.
The key search phrase is minimal enclosing k-gon:
Mictchell et al.: "Minimum-Perimeter Enclosing k-gon" 2006 (CiteSeer link)
Aggarwal et al.: "Minimum Area Circumscribing Polygons" 1985 (CiteSeer link)
O'Rourke et al.: "An optimal algorithm for fnding minimal enclosing triangles" 1986, Algorithmica (ACM link)
The general algorithms are not simple
(although algorithms for min area triangles or rectangles are simple).
Depending on your goals, you might have to abandon any mathematical notion of
"smallest" and head for a heuristic.
While number of edges > N do
remove the shortest edge by replacing its endpoints
with the intersection point of the adjacent edges
Related
The minimum bounding box (MBB) is the box around a cloud of 3D points with the smallest volume.
Joseph O'Rourke published [2] a cubic-time algorithm to find the minimum-volume enclosing box of a 3-dimensional point set. O'Rourke's approach uses a 3-dimensional rotating calipers technique.
I read the article and wiki (Minimum bounding box algorithms) [1]. Due to the
extremely complicated, I gained nothing. Furthermore, the execution steps of the algorithm are my next problem.
I want to write O'Rourke's algorithm by Fortran.
Any tips about algorithm or flowchart, etc, makes me happy.
Just a hint about the spirit of the algorithm.
In the first place you need to compute the convex hull of the points set, an O(N Log N) process in 2 and 3D. This gives a convex polygon (described by a ring of vertices) or polyhedron (described as a planar graph).
The next step is combinatorial and consists in trying all the positions that are potentially the tightest. In 2D, a minimum bounding box is flush with an edge, and it suffices to try the directions of all edges in turn (you rotate the polygon so that the edge becomes horizontal, and construct the AABB).
The 3D case is more elaborate and uses the fact that a tightest box is flush with two edges of the polyhedron, on two adjacent faces of the box (the box is not necessarily flush with a face). This property allows to generate a finite number of orientations by trying all pairs of edges, and as above, bring the edges in two coordinate planes and construct the AABB. This takes a little of spherical trigonometry.
This can be approached in two ways :
i) by partitioning the given polygon into convex polygons such that there is no
overlap between the convex polygons
ii) by covering the given polygon using convex polygons such that their union
gives the original polygon. In this case there can be overlap between
the convex polygons
Although partitioning covers the entire polygon, number of convex polygons can be reduced by second approach. It is also known that covering a concave polygon(second approach) with minimal number of convex polygons is NP-Hard.
I'm specifically looking for algorithms based on second approach mentioned above,but number of convex polygons may not be minimal.
As already mentioned by MBo and Yves Daoust in the comments to your questions. Polygon decomposition into convex polygons can be done by triangulation (or trapezoidal decomposition). This will result for an n vertex simple polygon P with n-2 (interior) triangles, i.e., is linear in the number of vertices.
Another way to construct a convex decomposition would be to use a generalized motorcycle graph. I would assume there must be a simpler way though!
The main idea is to start a motorcycle m for every reflex vertex r in P. Every motorcycle m drives with a given speed in a given direction and leaves a trace behind. If another motorcycle meets such a trace it crashes, i.e., stops but leaves the trace.
Generalized refers to the embedding in P and that the polygon boundaries function as walls where the motorcycles also crash. Furthermore if two motorcycles meet at the same point we have to start another one, or in this case just continue with one and stop the other. After all motorcycles have crashed there is the graph of the traces which in fact is a convex tessellation of P. There are several papers (one here) on this but implementation would be tough. This results in O(r) convex polygons that cover the interior of P.
I think the easiest way is to go with the triangulation or trapezoidal decomposition. These are well studied and available as implementation in many libraries.
Also mentioned in the comments: Input can be produced that will force O(n) polygons. Just think of a star shaped polygon that has n/2 reflex vertices (interior angle > pi).
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.)
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.
I need to compute the area of the region of overlap between two triangles in the 2D plane. Oddly, I have written up code for the triangle-circle problem, and that works quite well and robustly, but I have trouble with the triangle-triangle problem.
I already first check to see if one entirely contains the other, or if the other contains the first, as well as obtain all the edge-wise intersection points. These intersection points (up to 6, as in the star of David), combined with the triangle vertices that are contained within the other triangle, are the vertices of the intersection region. These points must form a convex polygon.
The solution I seek is the answer to either of these questions:
Given a set of points known to all lie on the convex hull of the point set, compute the area of the convex hull. Note that they are in random order.
Given a set of half-planes, determine the intersecting area. This is equivalent to describing both triangles as the intersection of three half-planes, and computing the solution as the direct intersection of this description.
I have considered for question 1 simply adding up all areas of all possible triangles, and then dividing by the multiplicity in counting, but that seems dumb, and I'm not sure if it is correct. I feel like there is some kind of sweep-line algorithm that would do the trick. However, the solution must also be relatively numerically robust.
I simply have no idea how to solve question 2, but a general answer would be very useful, and providing code would make my day. This would allow for direct computation of intersection areas of convex polygons instead of having to perform a triangle decomposition on them.
Edit: I am aware of this article which describes the general case for finding the intersection polygon of two convex polygons. It seems rather involved for just triangles, and furthermore, I don't really need the resulting polygon itself. So maybe this question is just asked in laziness at this point.
Question 1: why are the points in a random order? If they are, you have to order them so that connecting consecutive points with straight lines yields a convex polygon. How to order them -- for example, by running a convex hull algorithm (though there are probably also simpler methods). Once you have ordered them, compute the area as described here.
--
Question 2 is simpler. Half-plane is defined by a single line having an implicit equation a*x+b*y+c=0 ; all points (x, y) for which a*x+b*y+c <= 0 (note the inequality) are "behind" the half-plane. Now, you need at least three planes so that the intersection of their negative half-spaces is closed (this is necessary, but not sufficient condition). If the intersection is closed, it will be a convex polygon.
I suggest that you maintain a linked list of vertices. The algorithm is initialized with THREE lines. Compute the three points (in general case) where the lines intersect; these are the starting vertices of your region (triangle). You must also check that each vertex is "behind" the half-plane defined by the line going through the other two vertices; this guarantees that the intersection actually IS a closed region.
These three vertices define also the the three edges of a triangle. When you intersect by a new half-plane, simply check for the intersection between the line defining the half-plane and each of the edges of the current region; in general you will get two intersection points, but you must watch out for degenerate cases where the line goes through a vertex of the region. (You can also end up with an empty set!)
The new intersection vertices define a line that splits the current region in TWO regions. Again, use orientation of the new half-plane to decide which of the two new regions to assign to the new "current region", and which one to discard.
The points in the list defining the edges of the current region will be correctly ordered so you can apply the formula in the above link to compute its area.
If this description is not detailed/understandable, the next-best advice I can give you is that you invest in a book on computational geometry and linear algebra.