find the outline of a roughly 2D mesh - algorithm

I have a roughly planar mesh that I would like to find the outline of. To find the outline, I loop through all the triangles of the mesh and count the number of occurrences of each edge (represented by an unordered pair of vertices).
After examining all the triangles, there are only two possible values for each edge.
edge count = 1 : the edge belongs to a single triangle and so it is an outer edge
edge count = 2 : the edge is shared between two
triangles and so it is an inner border
Edges belonging to a single triangle (edge count = 1) define the mesh outline.
This strategy works pretty well, if it weren't for a problem, which I will try to illustrate with an example. Suppose we want to find the outline of the following mesh.
If we apply the strategy described above to this mesh, it will find the seven edges that define the outline - i.e. (0,1), (1,4), (4,7), (6,7), (5,6), (2,5) and (0,2) - but it will also find three inner edges, i.e. (2,3), (3,4) and (2,4), which belong to only one triangle each, respectively (2,3,6), (3,4,7) and (0,2,4).
I have thought of the following solution to solve the problem. As far as I can think, the issue can only arise when there are three vertices that lie on the same line as in the example above. The two short edges that connect the three vertices can be replaced by a single longer edge that connects the two outer vertices. This new edge is added to the list of edges or if already present its counter will be increased by one, reaching value 2. Iterating the procedure (following the path defined by the edges), I should simplify the list of edges and finally only those on the mesh outline should have count 1.
What do you think of my approach? Thanks.

The 2-3-4 configuration is "pathological" as it breaks the graph structure. In fact, this can be seen as a triangular hole in the mesh.
A possible way to handle is to list all single edges, detect the ones that overlap, and ignore them.

Related

Convert voronoi edges into polygons

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

Best way to merge overlapping convex polygons into a single concave polygon?

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.

Efficient algorithm to create polygons from a 2D mesh? (vertices+edges)

Given a mesh consisting of a list of vertices (2D coordinates) and edges (as vertex pairs), like so:
So the edges are defined like this:
a: 2,3
b: 3,4
c: 4,8
d: 5,8
e: 6,7
etc..
Edges are orientation-neutral, i.e. the order of any two vertices that define an edge is random (edges are not clockwise or counter clockwise).
Polygons may be convex or concave, but they never overlap or self-intersect (edges never cross eachother).
Question: how do I generate a list of all polygons?
More specifically, in the above example I would need 4 polygons, like so:
(a,b,c,d,i)
(d,g,h)
(f,i,j,k)
(e,h,k)
The polygons have no orientation either, clockwise or counterclockwise does not apply, and in fact the order of the edges that define a polygon may be random as well. For example (a,i,d,b,c) for the 5-sided one would be fine as well.
Instead of defining polygons as a list of edges, it could also be a list of connected vertices, like so:
(2,3,4,8,5)
(6,5,8)
(2,5,7,1)
(7,6,5)
In this case, the order of the vertices cannot be random (the list of vertices should be a circular sequence) but orientation (clockwise or counterclockwise) is still irrelevant. So the 4-sided polygon could also be (5,2,1,7) or (1,7,5,2) et cetera.
What is an efficient (fast) way to construct a list of polygons, defined in either edges or vertices?
For each edge vw, generate two half-edges v->w and w->v. Partition these by head (the head of x->y is y). Within each partition, sort by angle (if you use a comparison sort, then there's a way to avoid trig).
For your sample graph, the result is
7->1, 2->1
1->2, 5->2, 3->2
2->3, 4->3
8->4, 3->4
7->5, 6->5, 8->5, 2->5
8->6, 5->6, 7->6
6->7, 5->7, 1->7
5->8, 6->8, 4->8
. Now, define a permutation where v->w maps to the half-edge following w->v in the list containing w->v (wrapping around if necessary). The cycles of this permutation are the polygons.
For example, 5->8 maps to 2->5 (after 8->5) maps to 3->2 (after 5->2) maps to 4->3 (after 2->3) maps to 8->4 (after 3->4) maps to 5->8 (after 4->8).

Point inside arbitrary polygon with partitions

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.

How to take (N)-simplex edges?

In quickhull algo, there's need to build a cone upon set of edges.
An edge is thought as subsimplex with one vertex removed.
It is required, that adding a vertex to an edge will form a simplex, as if that vertex was just replaced.
For instance, when storing simplices as lists of vrtices, for triangle defined with vertexen {p0,p1,p2} edges are: {p1,p2},{p2,p0},{p0,p1} - in this index order.
Now, when adding new vertex p at the end of edge vertex list, new triangles are: {p1,p2,p},{p2,p0,p},{p0,p1,p} They have the same orientation as if original triangle was slanted.
For triangle, edge opposite to p1 has reversed order of remaining vertices.
For tetrahedron, it is for p0 and p2.
What is proper way of storing edges, or proper way to find out when to reverse vertices order?
Okay.
In general, storing vertex set is just not enough to represent a simplex, if its orientation matters. The same set can represent equivalent simplices with different sign of volume. A list can preserve orientation, but it's not trivial to derive it just from order. Thus, neither sets nor lists alone are not good solution (to represent both simplex and their edges).
It is probably best to use a list or tuple of vertices to represent a simplex; the question is how to decide the order of the vertices. (as I am not entirely certain of the exact requirements of an arbitrary-dimentional quickhull, I will speak generally below...)
If you are replacing each vertex v[i] in turn with a new point p, the simplest consistent thing to do is to substitute it for the point it replaces. Thus, for triangle {v0,v1,v2}, you will get new triangles {p,v1,v2}, {v0,p,v1}, and {v0,v1,p}.
If you want to reorder the vertices (e.g., so that p is at the end), then you should remember that swapping any two vertices will reverse the orientation of the simplex. So, to maintain the orientation, you must do an even number of swaps.
In the above example, swapping p with the final vertex will reverse the orientation, unless p is already the final vertex. You can fix this by swapping the first two vertices in that case. (note that this is a unique solution only for 3-vertex simplices -- it is not applicable for 2-simplices, and one of multiple solutions for N>3-simplices).
You could also look at this as a matter of rotating the vertex list of the original 3-simplex. Unfortunately, this only works for odd-vertex simplices. For a vertex list of size N, rotation involves N-1 swaps, so for a simplex with an even number of vertices, a rotation will change the orientation.
And edge of a simplex does not have an orientation by itself.
Only N-simplex in N-dimentions has defined orientation.
It is determined by cross-product of N vectors pi-p0 (signed volume).
For lower dimentional simlices in higher dimentional space such cross-product cannot be built.
For this patricular task (building new simplices with edges of another) an edge can be represented by an (ordered) list of vertices and an index where to add new point to make it on the same side as was removed vertex.
Considering cycling order of list (not sure it is universally valid), it could be rotated so that index is either 0 or 1.

Resources