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.
Related
Given two convex polygons P, Q separated by a line, how can I find their common tangents?
There should be 4 total.
Geometry isn't my strong side so any help will be appreciated :)
Any tangent will be generated from (at least) one point on each polygon. The tangent forms a half-space for each polygon, containing that entire polygon; different tangents are generated by requiring that each polygon be above or below the tangent line.
Whenever you have a problem involving two convex polygons, the algorithm probably involves "pick a point on each one, then iterate." This algorithm is no different.
What you do, basically, is start with a random guess, and refine. Pick a vertex on each polygon and calculate the line through the two vertices. Look at polygon A and see whether either of the two neighboring vertices is on the wrong side of the line. If one is, replace the current vertex with that vertex. Then do the same check on polygon B. Then, if you updated either vertex, repeat. Eventually the lines will converge to tangents with each vertex the extremal one in the desired direction.
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
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.
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.
I'm using PyGTS to construct domain specific 3D geometry. It doesn't have binding to triangulation functions of GTS, so I'm using poly2try instead. I triangulate coplanar polygon with 6 vertices, then filter it's edges on number of faces that they belong to, that way I obtain original outline of polygon, but with edges already attached to faces.
Next step is to "extrude" these edges along Z axis. For PyGTS boolean operations to work, all edges needs to be reused and the object must be closed (no edge belonging to just 1 face). So I want to iterate over my outline edges and build up sides of extrusion, reusing original polygon edge, 3 more, and saving one of those for reuse in next iteration. For this to work, those outline edges needs to be sorted so that: e1.v2 = e2.v1 and e2.v2 = e3.v1 and so on.
How do I sort these outline edges? Original sorting is lost when the base polygon is triangulated.