Given a set of n points in a plane, I am looking for an algorithm that will generate all empty triangles. Empty triangle is defined as a triangle that has 3 of the given points at its vertices and none of the given points in the interior. I could compute take all combinations of three points (n choose 3) and then eliminate those which are not empty but I am looking for a more efficient algorithm.
Related
How to decompose the polygon with self intersections to the set of simple polygons?
The input polygon P = {p1, ... pn} is given by the set of n vertices with the CCW orientation. I would like to perform a decposition to a set of m polygons P1, ..., Pm.
A simple walking along the segments from the intersection to the next one does not bring any effect; there are 2 segments with the same start point represented by the intersection point.
Probably, some lexicographical sort of edges may help...
Calculate all intersections, make new nodes and divide edges at intersections, for every node create list of adjacent edges.
Start from some point. Walk using the most CCW edge from current vertex (relative to the last edge). Add traversed edges to polygon and remove them (or mark). When you return to the same vertex, close polygon.
Repeat from the first vertex still having edges.
I have been given a lattice convex polygon. All I want to do is iterate through all vertices and grab the interior points near it (if possible) and only in 4 directions and of unit distance from the point.How do I do that?
Brief of what I did,
I iterate through all vertices. I take a vertex calculate slope between current vertex and the next and
if the slope is positive and Y-coord is increasing I print the (curX-1,curY).
else I print (curX+1,curY)
Similarly for slope being negative.
I leave the the cases where the slope is INF or 0.And also the cases where the previous slope was INF or 0. (optional,better methods would consider this too)
Any other better method?Is my algorithm correct? (curX=current X,curY=current Y)
Assume that the vertices are given in CCW.
Suppose you have a set of triangles, like the one shown in the image below, where black is a triangle edge, red is a triangle point, green is the polygon that needs to be found, and blue is the polygon's points.
The polygon described may or may not be concave. The triangles in it will always be adjacent (share all three points with the other triangles in the set).
What sort of algorithms exist to generate the polygon that such a set of triangles describes? The polygon should be in the form of a list of points in clockwise or counter-clockwise order.
How About Following A simple GrahamScan Algo... That's should Do the Trick.
Assume you have N distinct points Pi and M triangles. We define each triangle by 3 indices i, j and k to the points. Each triangle will have 3 edges defined as E(i,j), E(j,k) and E(i,k). The way to find the "polygon" is as follows:
1) Loop thru all triangles. For each triangle, add the 3 edges into a set. Edges with two identical point indices should be considered as the same edge. Namely, E(i,j) = E(j,i). Once encounter such case, remove both E(i,j) and E(j,i) from the set as these are the interior edges.
2) The remaining edges in the set should be the edges forming the polygon.
3) Sort the edges in the set by the point indices as follows:
(3a) Pick any edge from the set, say E(i,j).
(3b) Add indices i and j into a std::vector, then remove E(i,j) from the set.
(3c) Find the edge from the set that shares the last point index in the std::vector (which is j now). Denote this edge as E(j,k). Add index k into the std::vector and remove E(j,k) from the set.
(3d) Repeat step (3c) until the set contains no edges. The point indices in the std::vector will be the points order for the polygon.
If you only have M triangles and 3*M (x, y) values for the triangle vertices, then you will need to do some pre-processing to remove identical points and re-define the triangles in terms of the point indices as stated above.
Say I have a polygon represented as a list of vertices in CCW order (not a DCEL) and I have a given list of diagonals of that polygon. How can I split the polygon along all of those diagonals into a list of n+1 polygons?
I'm having no trouble splitting the list along one diagonal. The problem is quickly determining which of the two remaining polygons my other diagonals belong to. From there, I could split the list of diagonals into two lists, and recursively operate on the two split polygons.
Preferably, I'd like to do this in O(n log(n)) time, as opposed to the obvious algorithm of simply walking around the two split polynomials to determine which diagonals lie in which of the subpolygons.
Here is an outline of what I think is a solution.
Let's assume you already made sure the diagonals do not intersect each other and are fully contained inside the polygon.
Then (statement 1) you can think the task is fully combinatorial and forget about the real geometric layout details of the polygon and diagonals. Let's think about the task as you are given a regular polygon with vertices [0,1,..,N-1] and you cut it with a set of diagonals [i_k, j_k], 0<=k
For any vertices i and j let's call
arc_length(i, j) := min(max(i,j) - min(i,j), N - max(i,j) + min(i,j)) -
the least number of steps from i to j or from j to i along the cycle [0,1,..,N-1].
Let's call sortedDiagonals a container (vector>, list>, or alike), of all your diagonals sorted by arc_length(i,j), that is like
struct LessPredicate {
bool operator(pair<int,int> diag1, pair<int,int> diag2) const {
return arc_length(diag1) < arc_length(diag2);
}
};
Now let's cut our regular polygon along the diagonals from sortedDiagonals starting from 'shortest' to 'longest. Imagine a picture of a regular N-gon inscribed into a circle with a few first diagonals from sortedDiagonals drawn. Obviously we see on the picture our regular polygon split into smaller polygons, one of which contains the center of the circle (the case when the diagonal crosses the center may happen only once and at the very last step due to the sorting, so it's easy to sort it out as a special case). (Statement 2) Every time we draw next diagonal from the sortedDiagonals the diagonal belongs to the polygon containing the center.
Now, every time you take next diagonal from sortedDiagonals you know the polygon containing the center (say, you remember the index of the polygon or a pointer to it's structure, etc), so you know the polygon the diagonal belongs to. You cut the polygon with the diagonal into two parts and remember which one of them contains the center to know it on the next step.
If you need proof to statements 1 and 2 here is a sketch.
Statement 1 is true because if the diagonals are fully inside a given polygon and can intersect each other only in their end points then this polygon with all these diagonals and a regular polygon with same number of vertices and diagonals connecting vertices with same indices as in the given polygon are same as graphs in sense that their incidence data is same. So we reduce the task to the case of regular polygon which we need rather to simplify explanation of which polygon we know as containing the next diagonal from our list.
Statement 2. Suppose we cut a regular polygon with someDiagonal not crossing the center. The result is two polygons, one of which does not contain the center - let's call it 'small polygon'. What can we say about arc_length(diag) for any diag fully contained in the 'small polygon'? It can not be greater then arc_length(someDiagonal) and the only case when
arc_length(diag) == arc_length(someDiagonal)
is when diag == someDiagonal.
Now suppose we drew in our regular polygon k first diagonals from sortedDiagonals. Each of them cuts it's own 'small polygon' from the whole regular polygon (and probably some of these 'small polygons' contain some other 'small polygons' from other diagonals, it's ok). Now we draw k-1-th diagonal from the sortedDiagonals and notice that due to our sorting all previously drawn diagonals d_i were not greater then the d_(k+1) in sense of arc_length. Hence their 'small polygons' have no inner diagonals of arc_length greater or equal to arc_length(d_(k+1)). Hence the d_(k+1) can not belong to any 'small polygons' of diagonals preceding it in sortedDiagonals and it can belong only to the polygon containing the center point.
hth
I'm looking for an algorithm to solve this problem:
Given N rectangles on the Cartesian coordinate, find out if the intersection of those rectangles is empty or not. Each rectangle can lie in any direction (not necessary to have its edges parallel to Ox and Oy)
Do you have any suggestion to solve this problem? :) I can think of testing the intersection of each rectangle pair. However, it's O(N*N) and quite slow :(
Abstract
Either use a sorting algorithm according to smallest X value of the rectangle, or store your rectangles in an R-tree and search it.
Straight-forward approach (with sorting)
Let us denote low_x() - the smallest (leftmost) X value of a rectangle, and high_x() - the highest (rightmost) X value of a rectangle.
Algorithm:
Sort the rectangles according to low_x(). # O(n log n)
For each rectangle in sorted array: # O(n)
Finds its highest X point. # O(1)
Compare it with all rectangles whose low_x() is smaller # O(log n)
than this.high(x)
Complexity analysis
This should work on O(n log n) on uniformly distributed rectangles.
The worst case would be O(n^2), for example when the rectangles don't overlap but are one above another. In this case, generalize the algorithm to have low_y() and high_y() too.
Data-structure approach: R-Trees
R-trees (a spatial generalization of B-trees) are one of the best ways to store geospatial data, and can be useful in this problem. Simply store your rectangles in an R-tree, and you can spot intersections with a straightforward O(n log n) complexity. (n searches, log n time for each).
Observation 1: given a polygon A and a rectangle B, the intersection A ∩ B can be computed by 4 intersection with half-planes corresponding to each edge of B.
Observation 2: cutting a half plane from a convex polygon gives you a convex polygon. The first rectangle is a convex polygon. This operation increases the number of vertices at most per 1.
Observation 3: the signed distance of the vertices of a convex polygon to a straight line is a unimodal function.
Here is a sketch of the algorithm:
Maintain the current partial intersection D in a balanced binary tree in a CCW order.
When cutting a half-plane defined by a line L, find the two edges in D that intersect L. This can be done in logarithmic time through some clever binary or ternary search exploiting the unimodality of the signed distance to L. (This is the part I don't exactly remember.) Remove all the vertices on the one side of L from D, and insert the intersection points to D.
Repeat for all edges L of all rectangles.
This seems like a good application of Klee's measure. Basically, if you read http://en.wikipedia.org/wiki/Klee%27s_measure_problem there are lower bounds on the runtime of the best algorithms that can be found for rectilinear intersections at O(n log n).
I think you should use something like the sweep line algorithm: finding intersections is one of its applications. Also, have a look at answers to this questions
Since the rectangles must not be parallel to the axis, it is easier to transform the problem to an already solved one: compute the intersections of the borders of the rectangles.
build a set S which contains all borders, together with the rectangle they're belonging to; you get a set of tuples of the form ((x_start,y_start), (x_end,y_end), r_n), where r_n is of course the ID of the corresponding rectangle
now use a sweep line algorithm to find the intersections of those lines
The sweep line stops at every x-coordinate in S, i.e. all start values and all end values. For every new start coordinate, put the corresponding line in a temporary set I. For each new end-coordinate, remove the corresponding line from I.
Additionally to adding new lines to I, you can check for each new line whether it intersects with one of the lines currently in I. If they do, the corresponding rectangles do, too.
You can find a detailed explanation of this algorithm here.
The runtime is O(n*log(n) + c*log(n)), where c is the number of intersection points of the lines in I.
Pick the smallest rectangle from the set (or any rectangle), and go over each point within it. If one of it's point also exists in all other rectangles, the intersection is not empty. If all points are free from ALL other rectangles, the intersection is empty.