how can I get if a QPolygon is simple? [duplicate] - c++

For a polygon defined as a sequence of (x,y) points, how can I detect whether it is complex or not? A complex polygon has intersections with itself, as shown:
Is there a better solution than checking every pair which would have a time complexity of O(N2)?

There are sweep methods which can determine this much faster than a brute force approach. In addition, they can be used to break a non-simple polygon into multiple simple polygons.
For details, see this article, in particular, this code to test for a simple polygon.

See Bentley Ottmann Algorithm for a sweep based O((N + I)log N) method for this.
Where N is the number of line segments and I is number of intersection points.

In fact, this can be done in linear time use Chazelle's triangulation algorithm. It either triangulates the polygon or find out the polygon is not simple.

Related

CGAL partitioning of polygon-with-holes

I'm looking at the Partition_2 section of the manual and examples to see if CGAL can handle convex partitioning of a polygon with holes. All of the examples appear to use Polygons without any holes. Does anyone know if this is supported by any of the CGAL partitioning algorithms?
https://github.com/CGAL/cgal/blob/master/Partition_2/include/CGAL/partition_2.h
https://doc.cgal.org/latest/Partition_2/index.html
Thanks,
Josh.
From the documentation:
All the partitioning functions present the same interface to the user.
That is, the user provides a pair of input iterators, first and
beyond, an output iterator result, and a traits class traits. The
points in the range [first, beyond) are assumed to define a simple
polygon whose vertices are in counterclockwise order.
Simple means no holes and no self intersection.
Handling polygons with holes is not hard to achieve since CGAL also provides boolean operations on polygons. Just create the partition and subtract the holes. This may not be an ideal solution if your use case is performance critical (directly partitioning a polygon with holes can be faster).
Right, the "2D Polygon Partitioning" package supports only polygons without holes (as far as I know). You can always triangulate a polygon with holes using the edges (on the outer and inner CCBs) as constraints. Another option is to use vertical decomposition. It is directly provided by the "2D Minkowski Sums" package; see Polygon_vertical_decomposition_2. It is based on the decompose(arr, oi) free function that accepts as input a 2D arrangement; see CGAL::decompose(). The output is a collection of pseudo trapezoids (a pseudo trapezoid can be a triangle in degenerate cases), so it's a bit "better" than pure triangles and extremely efficient, especially if you have the underlying arrangement at hand.

Does AStar grid algorithm only handle square grids?

Looking for some clarification as I cannot seem to get an answer. When writing an astar algorirthm for grids, I was wondering if it was meant to work with any size rectangle or just perfectly square grids?
If there is a specific method for handling the heuristic for rectangles, what is it?
If people need to know I’m writing it in C++ for use in UE4.
Thanks everyone!
No, A* doesn't need a grid at all. You can use any placement of nodes, and as long as your heuristic is admissible, A* should work.
In fact, if you can guarantee your heuristic is admissible (i.e., it is guaranteed to never overestimate the distance), your nodes don't actually need a position at all. Of course, many actual applications do have nodes with particular locations, and Euclidean distance is a convenient admissible heuristic.
The only thing you need to do to make a rectangular grid work is to make sure your metrics are correct. That is: your node-to-node distances and your Euclidean distance calculation must correctly reflect the horizontal and vertical spacing of your grid.

k-way triangle set intersection and triangulation

If we have K sets of potentially overlapping triangles, what is a computationally efficient way of computing a new, non-overlapping set of triangles?
For example, consider this problem:
Here we have 3 triangle sets A, B, C, with some mutual overlap, and wish to obtain the non-overlapping sets A', B', C', AB, AC, BC, ABC, where for example the triangles in AC would contain the surfaces where there is exclusive overlap among A and C; and A' would contain the surfaces of A which do not overlap any other set.
I (also) propose a two step approach.
1. Find the intersection points of all triangle sides.
As pointed out in the comments, this is a well-researched problem, typically approached with line sweep methods. Here is a very nice overview, look especially at the Bentley-Ottmann algorithm.
2. Triangulate with Constrained Delaunay.
I think Polygon Triangulation as suggested by #Claudiu cannot solve your problem as it cannot guarantee that all original edges are included. Therefore, I suggest you look at Constrained Delaunay triangulations. These allow you to specify edges that must be included in your triangulation, even if they would not be included in an unconstrained Delaunay or polygon triangulation. Furthermore, there are implementations that allow you to specify a non-convex border of your triangulation outside of which no triangles are generated. This also seems to be a requirement in your case.
Implementing Constrained Delaunay is non-trivial. There is however, a somewhat dated but very nice C implementation of available from a CMU researcher (including a command line tool). See here for the theory of this specific algorithm. This algorithm also supports specification of a border. Note that the linked algorithm can do more than just Constrained Delaunay (namely quality mesh generation), but it can be configured not to add new points, which amounts to Constrained Delaunay.
Edit See comments for another implementation.
If you want something a bit more straight forward, faster to implement, and significantly less code... I'd recommend just doing some simple polygon clipping like the old software rendering algorithms used to do (especially since you're only dealing with triangles as your input). As briefly mentioned by a couple of other people, it involves splitting each triangle at the point where every other segment intersects it.
Triangles are easy, because splitting a triangle at a given plane always results in just 1 or 2 new ones (2 or 3 total). If your data set is rather large, you could introduce a quad-tree or other form of spacial organization in order to find the intersecting triangles faster as the new ones get added.
Granted, this would generate more polygons than the suggested Constrained Delaunay algorithm. But many of those algorithms don't do well with overlapping shapes and would require you to know your silhouette segments, so you'd be doing much of the same work anyhow.
And if fewer resulting triangles is a requirement, you can always do a merging pass at the end (adding neighbor information during the clipping to speed that portion up).
Anyway, good luck!
Your example is a special case of what computational geometers call "an arrangement." The CGAL Library has extensive and efficent arrangement handling routines. If you check this part of the documentation, you'll see that you can declare an empty arrangement, then insert triangles to divide the 2d plane into disjoint faces. As others have said, you'll then need to triangulate the faces that aren't already triangles. Happily CGAL also provides the routines to do this. This example of constrained Delaunay triangulation is a good place to start.
CGAL attempts to use the most efficient algorithms available that are practical to implement. In this case it looks like you can achieve O((n + k) log n) for an arrangment with n edges (3 times the number of triangles in your case) with k intersection. The algorithm uses a general technique called "sweep line". A vertical line is swept left-to-right with "events" computed and processed along the way. Events are edge endpoints and intersections. As each event is processed, a cell of the arrangement is updated.
Delaunay algorithms are typically O(n log n) for n vertices. There are several common algorithms, easily looked up or found in the CGAL references.
Even if you can't use CGAL in your work (e.g. for licensing reasons), the documentation is full of sources on the underlying algorithms: arrangements and constrained Delaunay algorithms.
Beware however that both arrangments and triangulations are notoriously hard to implement correctly due to floating point error. Robust versions often depend on rational arithmetic (available in CGAL).
To expand a bit on the comment from Ted Hopp, this should be possible by first computing a planar subdivision in which each bounded face of the output is associated with one of the sets A', B', C', AB, AC, BC, ABC, or "none". The second phase is then to triangulate the (possibly non-convex) faces in each set.
Step 1 could be performed in O((N + K) log N) time using a variation of the Bentley-Ottmann sweep line algorithm in which the current set is maintained as part of the algorithm's state. This can be determined from the line segments that have already been crossed and their direction.
Once that's done, the disjoint polygons for each set can then be broken into monotone pieces in O(N log N) time which in turn can be triangulated in O(N) time.
If you haven't already, pick up a copy of "Computational Geometry: Algorithms and Applications" by de Berg et al.
I can think of two approaches.
A more general approach is treating your input as just a set of lines and splitting the problem in two:
Polygon Detection. Take the set of lines your initial triangles make and get a set of non-overlapping polygons. This paper offers an O((N + M)^4) approach, were N is the number of line segments and M the number of intersections, which does seem a bit slow unfortunately...
Polygon Triangulation. Take each polygon from step 1 and triangulate it. This takes O(n log* n) which is practically O(n).
Another approach is to do do a custom algorithm. Solve the problem for intersecting two triangles, apply it to the first two input triangles, then for each new triangle, apply the algorithm to all the current triangles with the new one. It seems even for two triangles this isn't that straightforward, though, as there are several cases (might not be exhaustive):
No points of the triangle are in any other trianle.
No intersection
Jewish star
Two perpendicular spikes
One point of one triangle is contained in the other
Each triangle contains one point of the other
Two points of one triangle are in the other
Three points of one are in the other - one is fully contained
etc... no, it doesn't seem like that is the right approach. Leaving it here anyway for posterity.

Determine Polygon with specified property

I am creating a graphics project in which I have to find at some point of time that if there exists a point x inside the polygon such that if I join this point to all vertices of this polygon then all the line segments joining vertices and this point x lies completely inside the Polygon.
I wonder if there is some famous algorithm to do so or could any one of you describe an algorithm to do so.
I am looking for a linear time algorithm.
You are asking how to compute the kernel of a star-shaped polygon. This problem was solved in 1979 by Lee and Preparata in a paper entitled An Optimal Algorithm for Finding the Kernel of a Polygon. From their abstract:
The kernel K(P) of a simple polygon P with n vertices is the locus of
the points internal to P from which all vertices of P are visible
Equivalently, K(P) is the intersection of appropriate half-planes
determined by the polygon's edges. Although it is known that to find
the intersection of n generic half-planes requires time O(n log n), we
show that one can exploit the ordering of the half-planes
corresponding to the sequence of the polygon's edges to obtain a
kernel finding algorithm which runs in time O(n) and is therefore
optimal.

How can I solve Codeforces Beta round#12 Problem D?

Click here to view the problem.
I can't come to a solution better than O(n^2) but with n<=500000 this won't work!
My Idea is to sort them by (beauty+intellect+richness) and test any of them with those after it.
Please help!
If you restrict the problem to two attributes (e.g. only B_i and R_i, just for illustration purposes), you can think of these attributes as points in a 2D plane. For each point (corresponding to a Lady) you'll have to count the number of points in the (semi-infinite) rectangle 'right and above' the given point.
I think a faster than O(n^2) solution would involve a range tree although I have not thought about the details. See also an illustration here.
EDIT: and you would store (or update while building) the number of points 'below' each node with the node so you can e.g. easily get the number of points below or above the splitting point of a given node.
I think you can solve this in O(n log n) by considering each lady as a point in 3-space and computing the convex hull of the points (see, e.g., here). Then, any point inside the hull is a potential suicide case.