I have generated 2 sets of convex polygons from with different algorithms. Every polygon in each set is described by an array of coordinates[n_points, xy_coords], so a square is described by an array [4,2] but a pentagon with rounded corners has [80,2], with the extra 75 points being used to describe the curvatures.
My goal is to quantify how similar the two sets of geometries are.
Can anyone recommend any methods of doing so?
So far I've come across:
Hamming Distance
Hausdorff distance
I would like to know what other robust measures of similarity for 2D polygons. The method ideally needs to be robust across convex polygons and and give a measure of similarity between large sets (10,000+ each).
As I understood you look for shape similarity or shape analysis algorithms. You will find more robust methods here: https://www.cs.princeton.edu/courses/archive/spr00/cs598b/lectures/polygonsimilarity/polygonsimilarity.pdf
and
https://student.cs.uwaterloo.ca/~cs763/Projects/phil.pdf
Turning function;
Graph matching;
Shape signature.
Assuming that both polygons are aligned, centered and convex you could try to assess similarity by computing ratio of area a smaller polygon to area of convex hull of both polygons.
Ratio = Min(Area(A), Area(B)) / Area(ConvexHull(A, B))
The ratio will be 1 if both polygon are equal, and 0 if the differ severely like a point and a square.
Area of the polygon can be computed in O(N) time. See Area of polygon.
The convex hull can be computed in O(N log N). See Convex Hull Computation. It could be speed up to O(N) by merge-sorting already sorted vertices of both polygons and applying the second phase of Graham Scan Algorithm.
Related
I need a fast polygon clipping implementation against an axis aligned rectangle and I've implemented Sutherland–Hodgman algorithm based on my particular data set and it's 40 to 100 times faster than ClipperLib and other generic polygon clipping algorithms, but the output is a degenerate polygon in some cases:
results in:
Is there a variation of Sutherland–Hodgman algorithm to generate multiple polygons instead of a degenerate one or any fast and simple way to transform the degenerate polygon into multiple polygons?
I have a set of 2D points.
I want to find a set of (possibly overlapping and arbitrarily oriented) bounding-boxes for subsets of these points such that each point lies within at least one box, each box contains at least k points and such that the combined area of the boxes is minimized.
One idea for an algorithm I have is:
use a concave-hull algorithm to find a concave hull for the points.
use convex decomposition algorithm to find a set of convex hulls.
compute arbitrarily oriented minimum bounding box for each of the convex hulls.
I'm looking for a list of other (potentially better suited) algorithms for this problem?
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).
I have a polygon whose vertices are the center points of other 4 polygons. For these 4 polygons I also have the coordinates of their vertices. I would like to determine for each "corner polygon" the vertex that if chosen as vertex of the bigger polygon would maximize it's area. The polygon is a rectangle to which has been applied a perspective transformation, so I was thinking that it's a trapezoid.
I have tried calculating a rough center by summing the (x,y)s of the corners and diving by 4. I then chose each vertex based on the one that had farthest distance from this center point among it's peers. (something like distance = (Xc - X)^2 + (Yc - Y)^2, I avoided square rooting the result for performance purposes).
This unfortunately does not give the intended results. Usually just one vertex is substituted by the outer most "corner polygon" vertex, while the others are substituted by one of the other two "corner polygon" vertices excluding the nearest one.
What could be a way to create a better algorithm?
The method I posted actually does work, as #MBo suggested there were implementation mistakes. To specify for future readers, this algorithm probably works only because the polygon is convex and/or a trapezoid, although that remains pure speculation based on the fact that my algorithm was produced heuristically.
A first approach is just by brute force: compare the areas of the 4^4 = 256 polygons obtained by combinations.
Slightly better, I guess that the vertices must belong to the convex hull of the point set (needs to be confirmed). Then discard the inner points and brute-force the remainig ones. As between one and three vertices of the corner quadrilaterals are on the convex hull, there are 3^4 = 81 combinations at worst (and a single at best; four in the given example; 2^4 = 16 is the most likely in practice).
You will need an efficient convex hull algorithm for the savings to be effective.
I need to find a largest inscribed circle of a convex polygon, I've searched many sites and I get that this can be done by using Delaunay triangulation. I found a thread in CGAL discussion with an algorithm using CGAL:
You can compute this easily with CGAL:
First, compute the Delaunay triangulation of the points.
Then, iterate on all the finite faces of the triangulation.
For each finite face f
compute its circumcenter c
locate c in the triangulation (to speed up things, you can give one
vertex of f as starting hint for the point location)
if the face returned by locate(c,hint) is finite, then the circumcenter
c lies in the convex hull of the points, so, f is a candidate
if f is such a candidate face, compute its squared circumradius
keep only the face with minimum squared circumradius
The CGAL manual (chapter 2D triangulation, together with a few things
from the kernel) shows every basic function to do this.
I was a bit confused with the last part of this algorithm. When I read it what I understand from it is that the minimum circumradius of the triangulation face is the radius for the largest inscibed circle. But from examples of polygon with Delaunay triangulation, it seems that even the smallest circumcircle sometimes cannot fit inside the polygon, so how can this has the same radius as the largest inscribed circle?
Maximum inscribed circle in polygons.
The classical computational-geometry solution to the maximum inscribed circle problem for polygons is to use the generalized Voronoi diagram of the polygon's faces resp. the medial axis of the polygon. This approach works in a more general setting like polygons with holes, see this stackoverflow answer to a similar question.
Convex input.
The convexity of your input polygon, however, gives the problem more structure, which I would like to comment on. Consider the following convex input polygon (black), the Voronoi diagram (blue), and the maximum inscribed circle (green) centered on a Voronoi node.
The classical Voronoi-based solution is to (i) compute the Voronoi diagram and (ii) take the Voronoi node with largest clearance (i.e., distance to its defining faces).
The Voronoi diagram of a polygon with holes (i.e., the set of vertices and edges) can be computed in O(n log n) time, c.f. Fortune's algorithm (1986). Later Chin et alii (1999) gave an O(n) algorithm for the medial axis of a simple polygon.
For convex polygons, however, a time-optimal algorithm for Voronoi diagram that runs in O(n) time was already known in 1989 due to Aggarwal et alii. This algorithm follows basically the following idea: Consider the grey offset curves moving inwards at unit speed. If you project this movement into three-space where the z-axis is time you get a unit-slop roof over the polygon:
This roof model could also be characterized as follows: Put a half-space on each polygon edge at 45° slope with polygon (such that they contain the polygon) and intersect them all. So if you can quickly compute the intersect of half-spaces then you can also quickly compute Voronoi diagrams of convex polygons. Actually, for the maximum inscribed circle problem we do not need to go back to the Voronoi diagram but take the one peak of the roof, which marks the center of the maximum inscribed circle.
Now the half-spaces are dualized to points, and then the intersection of half-spaces corresponds the convex hull of its dual points. Aggarwal et al. now found an O(n) algorithm for the convex hull of points that stem from this setting.
A summary of this construction that leads to a Voronoi diagram algorithm for convex polyhedra in any dimension can be found in a blog article of mine.
Simple & fast implementation. A simpler algorithm to compute the Voronoi diagram is motivated by straight skeletons. For convex polygons the Voronoi diagram and the straight skeleton are the same.
The algorithm behind the straight-skeleton implementation Stalgo basically simulates the evolution of the wavefront structure (the grey offset curves). For convex polygons this reduces to finding the sequence of edges that collapse.
So a simple O(n log n) algorithm could look like this:
Construct a circular list of the polygon edges. Compute the collapse time of each edge during wavefront propagation, and insert this event into a priority queue.
Until the queue is empty: Take out the next edge-collapse event: Remove the edge from the circular structure and update the collapse times of the neighboring edges of the removed edge.
Actually, you can simplify the above algorithm further: You do not need to update edge collapses in the priority queue but simply insert new ones: Since the new collapse time of edges are strictly lower, you always get the right event first and dismiss the others and the queue is not growing larger than 2n. Hence, you do not compromise the O(n log n) time complexity.
For the maximum inscribed circle problem you can simplify the above algorithm even further: The Voronoi node (resp. straight skeleton node) you look for is due to the collapse of the final triangle at the end of the loop over the priority queue.
This algorithm should be quick in practice and only a few lines of code.
The last step can mean to select the minimum face of the triangle. Then rinse and repeat.