Outermost Polygon from a set of Edges - computational-geometry

Suppose I have a set of 2d line segments that are all connected. I need an algorithm that finds the outermost segments in the set. That is, the minimal subset that bounds the same region.
Note: this is not the same as finding the convex hull of the points making up the segments.
Edit:
On the top is the initial set of segments.
Below that is the same outline with interior segments deleted.
(Ignore the little grey crosses, they're just to mark intersection points.)

How would you do that with a pencil...?
Find the leftmost vertex (minimum x). If there's more than one, choose the lowest of them (minimum y). There is no vertex below the current one, so take the direction 'downwards' as a reference.
Find all edges going from the current vertex and calculate their directions (bearings). Find the one which makes the smallest positive angle (counter-clockwise) from the reference direction. That will be the outline segment.
Select its other end as your new 'current' vertex and set the direction from that vertex to the recent one as a new reference direction.
Proceed from step 2 until you arrive to the start vertex.
Remove all unvisited segments.
Remove all orphaned vertices (if any appeared in step 5).

Given a triangulated non-convex polygon you can specify the direction of vertices traversal (clockwise of CCW). Make all the triangles to be similarly oriented WRT traversal of its vertices. Do decompose all the triangles into directed edges. Every edge for every triangle is the tuple of two vertices (a, b). For each neighbouring triangles you have two contradirectional edges (a, b) and (b, a). You can simply exclude such a pairs of edges from further consideration. Finally you will obtain a set of exclusively outer edges.
There is no loss of generality if your polygon consists of non-simplicial parts (but still you can specify the direction of vertices traversal).
Triangulation of the source segments-constructed polygon is evident step: stretching the vertices onto $d + 1$ paraboloid and triangulation, then excluding triangles, containing at least one edge that match no one source segment.
Another possible approach is slightly modified Gift wrapping algorithm.

The following is an approach that starts with the convex hull then works its way inward. The intuition is that you start with edges on the hull, then you fill in gaps by finding the closest point "along" the gap by following the shortest path in your edge set.
Compute the convex hull of your points.
Intersect the hull set with your edge set. This will leave you with a series of, potentially disconnected, edge paths.
Any point that does not have two edges (i.e., a leaf in graph terms) is connected to its closest leaf by finding the shortest path in the original edge set.
Any ties can be broken by a path that makes the smallest area when closed off by the hull.

Related

Extracting only bounded faces from undirected connected planar graph with possibly curved edges

I want to extract only bounded faces from an undirected connected planar graph where edges are represented as straight lines or quadratic/cubic Bézier curves, and they don't intersect each other. I did it successfuly for graphs with only straight line edges following this paper. My algorithm goes like this.
Find the 2-core of the graph. Use the 2-core instead of the entire graph.
Pick a vertex V and a directed edge V->U. Mark V->U as visited.
Find edge U->W such that the counterclockwise angle from U->V to U->W is the minimum. Mark U->W as visited.
If W is the initial vertex, a face is found. Else put U in place of V and U->W in place of V->U and repeat 3.
Let V1V2...Vn be the face found. Find k such that the directed edge Vk->Vk-1 is unvisited. Restart 2 with initial vertex Vk and edge Vk->Vk-1. If there is no such k, pick any unvisited edge and restart.
Remove the only face with different orientation. This face represents the unbounded exterior region.
I calculated the orientation of faces with this answer.
But if there are curved edges, the situation is different. First, I modified step 2 so that we compare the angle between tangent vectors instead. Now, I have trouble at step 6. The convex hull of a face could contain no vertices, so that answer doesn't work. In this case we can instead grab a point on a curve with minimal y coordinate and calculate the sign of the curvature, but it seems too inefficient. Is there a way to calculate orientation more efficiently, or is there another way to distinguish unbounded region from bounded regions?

Optimal algorithm to check which vertices in a set of polygons can be connected to a point without overlap

I have a set of polygons described by their vertices. My question is, given a certain vertex, how can I find the vertices of all the polygons to which I can draw a line segment from the given vertex without overlapping the polygons.
Is it possible to do in less than O(n^2)?

Efficient Way to construct triangles from Edges/Lines?

Lets say I have a set of points and I have lines/edges between them. All of these edges create non-overlapping triangles within the convex hull of my points. All points are connected to triangles.
How can I efficiently check which points are part of which triangle? I could check incident points of each edge and gradually construct a triple of points, but that sounds awefully slow (o(n^2)?).
Is there something like linesweep or so to do that?
cheers.
If you have a 2-dimensional set-up like you described, then you have a fully triangulated planar graph (no intersecting edges when you exclude the endpoints) which spans the convex hull of your points. In this case, if you sort the edges around each vertex circularly according to the angle they make with the vertex, then you know for sure that each pair of adjacent edges makes a triangle. Furthermore, every triangle can be found this way if you perform this procedure for each vertex. Each triangle will be found 3 times when you iterate over all vertices. You can either use a hash table to detect duplicates, or sort all your triangles when you are done to identify duplicates. If you use hash table, then the overall complexity if you have V vertices is O(V log d), where d is the maximum degree of a vertex (because the total number of edges is linear in the number of vertices because you have a planar graph). So absolute worst-case is O(V log V), which is the same worst-case if you sort all triangles to find duplicates (because the max number of triangles is also linear in the number of vertices). The only caveat to make this work is that you need to know the neighbor vertices (i.e. the incidental edges) for each vertex.
The edges define an undirected graph G and the triangles are the set of cycles in G with length=3.
Geometric triangulations typically have relatively low nodal degree (degree d is the number of edges adjacent to each node, d<=10 is typical for geometric triangulations) and, as such, here is a reasonably efficient O(n*d^3) algorithm that can be used to construct the set of triangles.
Setup a graph-like data structure, supporting access to the list of edges adjacent to each node.
Iterate over all nodes. Consider all pairs of edges adjacent to a given node i. For a given pair of edges adjacent to i, we have a potential nodal triplet i,j,k. This triplet is a triangle if there is an edge joining nodes j,k, which can be checked by scanning the edge lists of j,k.
Duplicate triangles will be generated by a naive implementation of (2). Maintain a hash table of triangles to reject duplicate triplets as they're considered.
I've assumed that the edges define a valid disjoint triangulation, being non-intersecting, etc.
Hope this helps.

Finding the smallest distance from any vertex to the border of the graph

So I have triangular mesh approximating a surface.
It's like a graph with the following properties:
The vertices on the graph border are trivially identifiable. (Number of neighbor vertices > number of containing triangles)
You can trivially calculate the distance between any two vertices. (Euclidean distance)
For any vertex v, any vertex that is not a neighbor of v must have a greater distance to v than at least one of v's neighbors. In other words, no non-neighbor vertices may appear within v's neighborhood ring.
For each vertex v, I want to calculate the smallest distance from v to any border vertex.
I can do this by brute force, build a list of all border vertices, compare v's distance to each, and keep the minimum. But this is inefficient.
I believe the most efficient way for each single vertex v is to do have a priority queue where the top element is the closest to v. The queue is initialized with v's neighbors. While the top of the queue is not a border vertex, pop the top and push all the neighbors of the popped vertex.
Let's say vertex v has 6 neighbors, and I calculate the minimum border distance for each of the 6, and I recorded the exact border vertex that gave the minimum for the 6 neighbors. I know that one of these must also give v's minimum border value. I can't really prove this, but I think it's intuitive. If v's surrounded by it's neighbors, the closest border vertex to v must also be the closest border vertex to one of its neighbors.
I want to know if there is a way to use this knowledge to efficiently computing the minimum for each point in the graph. More efficient than a breadth first search from each vertex.
If you do breadth-first search until you find a border vertex, this does not guarantee that this is the closest border vertex. To see this, note that for any triangulated planar graph in 2-d, you could add a very small distinct z-coordinate to each vertex, and define a 3-d surface whose natural simplest good approximating triangular mesh (giving a perfect approximation) is simply the mesh corresponding to the original planar graph. So it suffices to give an example of a triangulated planar graph where there are vertices v whose closest border vertex in terms of minimum #edges on a path connecting v to the border vertex is not the closest border vertex in terms of euclidean distance. Here's an example of such a planar graph.
First draw a right triangle with vertices (0,0), (1,0), (0,1). Then choose a large number of vertices along the edge from (1,0) to (0,1), such that the vertices break up the edge into equal sized segments. Connect all these vertices to (0,0). Then, for all the vertices you added, for each pair of neighboring vertices draw an equilateral triangle that uses the two vertices as two of the equilateral triangle vertices. Connect all the "tops" of the equilateral triangles with a straight line. Now you should have a region that looks like the first level of a house of cards. Similarly add the second level of the house of cards on top of the first. This is the graph, and it satisfies your properties. Now note, for all of the vertices you added along the edge from (1,0) to (0,1), they have (0,0) as a neighbor and this is a border vertex. However, the closest border vertex in terms of euclidean distance will be one of the border vertices along the perimeter of your 2-level house of cards, which will be almost always be 2 edges away. A breadth first search from one of these interior vertices would return (0,0) as the closest border vertex, which is incorrect. I think this example is just a glimpse of how complicated things can get, such that your assumptions are still satisfied. The fastest algorithm may indeed be to just enumerate all border vertices, and then for each vertex test all border vertices to find the closest. If you have a nice "fat" mesh with most of the vertices not being border vertices, at least the number of border vertices will be much smaller than the total number of vertices, so the complexity is at least reduced some from the worst-case O(N^2) if you have N vertices.

Find all non-overlapping polygons in a list of edges/vertices

I have a list of edges and a list of vertices. Each edge references two vertices, each vertex maintains a list of edges.
I want to find all non-overlapping polygons produced from this graph.
An example would be
0,0) (4,0) (4,2) (4,4) (2,4) (2,2) (4,2) (6,2) (6,6) (0,6) (0,0)
This path should describe each unique edge with collisions on some verticies. In the actual graph, the vertices are distinct. The two polygons I would need from this set are (0,0) (4,0) (4,2) (2,2) (2,4) (4,4) (4,2) (6,2) (6,6) (0,6) and (2,2) (2,4) (4,4) (4,2)
What you are describing is the problem of finding all minimal circuits in a graph. (That it happens to have a geometric model is irrelevant, I think.) There's a paper here for finding a minimal circuit. You can build on that by removing the edges of the minimal circuit and running the algorithm again.
The problem is also discussed in this thread for the case of directed graphs. You can turn your graph into a directed graph by making a copy of each edge with the vertices reversed and then treating it as directed. The only problem will be that each polygon will be found twice, once in each traversal direction. You can clean that up with a post-process step or perhaps by some clever bookkeeping while the algorithm is running.
Well, I was thinking...
The only vertices of particular interest are ones with more than two edges. To find all vertices with more than two edges is O(n). Then to find the tighest closed loop is the same as finding the smallest theta between a given an edge and another edge at a given vertex (if the vertices are ccw, this is the smallest angle clockwise from the current edge). In order to find all tightest closed loops, I need to check all edge ccw edge pairs at a vertex where the edge count is greater than 2. This is the initialization of the trace. From that point on, the trace will always pick the next edge with the smallest theta clockwise. Once the path is returned, I move to the next edge pair in the root vertex, and path again. Once all pairs are checked, I move to the next vertex with an edge count greater than 2. Now, if I can only determine if I am falling into a known loop and not trace. Maybe if the first two vertices of a path occur in the same order in an already known polygon...
How does that sound? I know it's no djikstra, but it will work, and hopefully faster than finding all cycles brute force.

Resources