Currently I am trying to get Voronoi polygons dividing a plane of a certain size (e.g. 1000x1000 with 500 random points).
For this purpose, I used Delaunay's triangulation - Bowyer Watson's algorithm. Thanks to this, I am able to generate points and properly connect the edges included in the Voronoi diagram. Unfortunately, in my case, I need a list of polygons (of which each polygon contains a list of its edges).
I tried to create a naive algorithm that would take the edges one by one and look for the next ones to create a final polygon and so on - unfortunately without success. I was also thinking about taking the vertices of the triangles and creating a circle until the polygon is formed (from the existing edges), but I am not sure if this is a good solution?
Is there any way to do it? Or should I use a different algorithm to get the Voronoi polygon list?
I have not found a suitable solution to this problem on the Internet, if there is one, I will be grateful for the link
Select E an arbitrary edge
Add vertices in E to polygon
Select point P slightly to one side of E
If point inside plane
Select one vertex of selected edge
Select E2 new edge from vertex with smallest angle on side with point P
Add second vertex in E2 to polygon
Repeat last two steps until reach other vertex in E
Add polygon to solution, if not already included
Repeat with point on other side of edge
Repeat until all edges processed
Related
I am working with several convex polygons that overlap each other and I need to combine them back together to form one single polygon that may be convex or concave.
The problem is always as follows:
1) The polygons that I need to merge together are always convex.
2) The vertices of each polygon are defined in clockwise order.
3) The polygons are never in any specific order.
4) The final polygon can only be simple convex or concave polygon, i.e. no self-intersection, no duplicate vertices or holes in the shape.
Here is an example of the kind of polygons that I am working with.
![overlapping convex polygons]"image removed")
My current approach is to start from the first polygon and vertex by vertex I loop through all vertices of all of the polygons to find overlap. If there is no overlap, I store the vertex for the final outline and continue.
Upon finding overlapping vertices, I determine which polygon to continue to by measuring the angles of the possible paths and by choosing the one that leads towards the outside of the shape.
This method works until I encounter polygons that do not have vertices overlapping each other, but instead one polygon's vertex is overlapping another polygon's side, as is the case with the rectangle in the image.
I am currently planning on solving these situations by running line intersect checks for all shapes that I have not yet processed, but I am convinced that this cannot be the easiest or the best method in terms of performance.
Does someone know how I should approach this problem in a more efficient manner and/or universal manner?
I solved this issue and I'm posting the answer here in case someone else runs into this issue as well.
My first step was to implement a pre-processing loop based on trincot's suggestions.
I calculated the minimum and maximum x and y bounds for each individual shape.
I used these values to determine all overlapping shapes and I stored a simple array for each shape that I could later use to only look at shapes that can overlap each other.
Then, for the actual loop that determines the outline of the final polygon:
I start from the first shape and simply compare its vertices to those of the nearby shapes. If there is at least one vertex that isn't shared by another vertex, it must be on the outer edge and the loop starts from there. If there are only overlapping vertices, then I add the first shape to a table for all checked shapes and repeat this process with another shape until I find a vertex that is on the outer edge.
Once the starting vertex is found, the main loop will check the vertices of the starting shape one by one and measure how far from the given vertex is from every nearby shapes' edges. If the distance is zero, then the vertex either overlaps with another shape's vertex or the vertex lies on the side of another shape.
Upon finding the aforementioned type of vertex, I add the previous shape's number to the table of checked shapes so that it isn't checked again. Then, I check if there are other shapes that share this particular vertex. If there are, then I determine the outermost shape and continue from there, starting back from step 2.
Once all shapes have been checked, I check that all non-overlapping vertices from the starting shape were indeed added to the outline. If they weren't, I add them at the end.
There may be computationally faster methods, but I found this one to be simple to write, that it meets all of my requirements and it is fast enough for my needs.
Given a vertex, you could speed up the search of an "overlapping" vertex or edge as follows:
Finding vertices
Assuming that the coordinates are exact, in the sense that if two vertices overlap, they have exactly the same x and y coordinates, without any "error" of imprecision, then it would be good to first create a hash by x-coordinate, and then for each x-entry you would have a hash by y-coordinate. The value of that inner hash would be a list of polygons that have that vertex.
That structure can be built in O(n) time, and will allow you to find a matching vertex in constant time.
Only if that gives no match, you would go to the next algorithm:
Finding edges
In a pre-processing step (only once), create a segment tree for these polygons where a "segment" corresponds to a min/max x-coordinate range for a particular polygon.
Given a vertex, use the segment tree to find the polygons that are in the right x-coordinate range, i.e. where the x-coordinate of the vertex is within the min/max range of x-coordinates of the polygon.
Iterate those polygons, and eliminate those that do not have an y-coordinate range that has the y-coordinate of the vertex.
If no polygons remain, the vertex does not participate in any edge of another polygon.
You cannot get more than one polygon here, since that would mean another polygon shares the vertex, which is a case already covered by the hash-based algorithm.
If you get just one polygon, then continue your search by going through the edges of that polygon to find a match -- which is what you already planned on doing (line intersect check), but now you would only need to do it for one polygon.
You could speed that line intersect check up a little bit by first filtering the edges to those that have the right x-range. For convex polygons you would end up with at most two edges. At most one of those two will have the right y-range. If you get such an edge, check whether the vertex is really on that edge.
As in the title of the question, how to triangulate a simple polygon that grows dynamically that's say whenever a new vertex is added by user or by a computer dynamically the polygon should get triangulated again. So rather than running some triangulation algorithm after each new vertex is added is there any clever/efficient(possibly easy to implement also) way for each new input it should take say <= O(n) time to triangulate the polygon.
The newly added vertex will be adjacent with the first and last vertices of the current polygon.
When you insert a new vertex and replace an edge with two, the triangle they form may overlap a number of triangles of the triangulation. The overlapped triangles form a subpolygon. Build the outline of this polygon and insert the new vertex. Then retriangulate the updated subpolygon.
I guess that the overlapping triangles can be efficiently found by exploring the neighbors of the starting triangle, recursively, and checking them for overlap. The outline of the subpolygon is formed of the edges not shared by two triangles.
I'm assuming that the polygon is augmented, at each step, by adding a vertex C, removing the segment AB, and adding segments AC and CB. I'm also assuming no degeneracies.
If ABC winds positively (that is, the polygon is expanded "outwards"), simply add ABC to the triangulation.
Otherwise, consider the triangle ABD in the previous triangulation. If C is in that triangle, remove the triangle ABD and add triangles BDC and DAC. If it is not, then it is in the subpolygon on the AD side, or the one on the BD side. Remove ABD and recurse into the appropriate subpolygon, adding C to (say) the segment BD. Once the recursion completes, add triangles BDC and DAC as before.
This solution relies on both the old and the new polygons being simple (non-self-intersecting). Otherwise, adding the triangles following the recursive step might not be valid.
Given a list of coordinates (x, y) that form up polygons is there a specific algorithm/s that can be used to find the number of separate polygons "not colliding polygons" that these points create?
And if there is no algorithm/s what would be the most efficient way to calculate these separate polygons?
I have tried using SAT but the performance is bad, since i have to create each individual polygon and check it for collision against every other polygon.
To illustrate what i want to ultimately achieve, in the following picture you can see the polygons that i'd like to calculate/find which are in some cases comprised of connecting squares.
Also note that i actually start with x, y coordinates for the center of a square and based on a radius i calculate corner points, so i have access to both methods, but mainly opted for the corner points for SAT.
P.S. i'm doing this in lua, but would happily accept any code samples/solutions in other languages.
Fast sweep-line algorithm are described in these papers:
Hiroshi Imai, Takao Asano,
Finding the connected components and a maximum clique of an intersection graph of rectangles in the plane,
Journal of Algorithms 4 (1983) 310—323
H. Edelsbrunner, J. v. Leeuwen, Th. Ottmann and D. Wood,
Computing the connected components of simple rectilinear geometrical objects in d-space,
RAIRO Inform. Theor. 18 (1984) 171—183.
Put all the edges of every polygon in a hash table with the edge as the key (specifically the key will be the two corner points which the edge connects, in sorted order) and the polygon identifier as the value. When adding an edge to the hash-table, just check if an identical edge already exists (same key). This would let you find the duplicate/shared edges.
Say I have a polygon. It can be a convex one or not, it doesn't matter, but it doesn't have holes. It also has "inner" vertices and edges, meaning that it is partitioned.
Is there any kind of popular/known algorithm or standard procedures for when I want to check if a point is inside that kind of polygon?
I'm asking because Winding Number and Ray Casting aren't accurate in this case
Thanks in advance
You need to clarify what you mean by 'inner vertices and edges'. Let's take a very general case and hope that you find relevance.
The ray casting (point in polygon) algorithm shoots off a ray counting the intersections with the sides of the POLYGON (Odd intersections = inside, Even = outside).
Hence it accurately gives the correct result regardless of whether you start from inside the disjoint trapezoidal hole or the triangular hole (inner edges?) or even if a part of the polygon is completely seperated and/or self intersecting.
However, in what order do you feed the vertices of the polygon such that all the points are evaluated correctly?
Though this is code specific, if you're using an implementation that is counting every intersection with the sides of the polygon then this approach will work -
- Break the master polygon into polygonal components. eg - trapezoidal hole is a polygonal component.
- Start with (0,0) vertex (doesn't matter whether (0,0) actually lies wrt your polygon) followed by the first component' vertices, repeating its first vertex after the last vertex.
- Include another (0,0) vertex.
- Include the next component , repeating its first vertex after the last vertex.
- Repeat the above two steps for each component.
- End with a final (0,0) vertex.
2 component eg- Let the vertices of the two components be (1x,1y), (2x,2y), (3x,3y) and (Ax,Ay), (Bx,By), (Cx,Cy). Where (Ax,Ay), (Bx,By), (Cx,Cy) could be anything from a disjoint triangular hole, intersecting triangle or separated triangle.
Hence , the vertices of a singular continous polygon which is mathematically equivalent to the 2 components is -
(0,0),(1x,1y),(2x,2y),(3x,3y),(1x,1y),(0,0),(Ax,Ay),(Bx,By),(Cx,Cy),(Ax,Ay),(0,0)
To understand how it works, try drawing this mathematically equivalent polygon on a scratch pad.-
1. Mark all the vertices but don't join them yet.
2. Mark the repeated vertices separately also. Do this by marking them close to the original points, but not on them. (at a distance e, where e->0 (tends to/approaches) ) (to help visualize)
3. Now join all the vertices in the right order (as in the example above)
You will notice that this forms a continuous polygon and only becomes disjoint at the e=0 limit.
You can now send this mathematically equivalent polygon to your ray casting function (and maybe even winding number function?) without any issues.
Is there a computationally efficient way to determine the points of intersection of a straight line with all the edges of a given Voronoi tessellation in a rectangular plane area?
Thanks
Once you have your first intersection point, the rest is easy.
Prepare a database of edges: for each edge, list both polygons it belongs to, or say it is the outer edge (and so belongs to one polygon only). In your picture, the lower side of the rectangle would contain 4 edges of 4 different polygons.
Draw your line, find your first intersection point ([0, 0.25] in your picture, not circled). Say it's polygon A. Then the next intersection point (the lowest one circled in your picture) also belongs to A. You find the relevant edge with a binary search through the list of edges of A.
Now you have found the second edge of A, find out which other polygon it belongs to. Then use binary search to find which other edge of that other polygon the line intersects. And so on until you exit your rectangle.