I'm trying to calculate the shortest distance between two polygonal lines. I had thought of using a sweep algorithm but I don't know what events to take into account because the vertical ray can intersect between two vertices, a vertex and an edge or two edges. What will my events be? Is there any other way to calculate the distance?
The minimum distance will always be achieved by a segment one end of which is a vertex of one of the polygonal chains P1 or P2. Even if the min distance is achieved by two parallel edges, an endpoint of those edges also realizes the min distance.
So a naive algorithm is to iterate over all vertices v1 of P1, find the minimum distance from v1 to P2.
The problem of finding the minimum distance between v and P can iterate over each edge of P.
What I am describing is a quadratic algorithm. If you want to achieve the optimal O(n log n), you will need to compute a Voronoi diagram.
Related
I want to find the minimum distance between two polygons with million number of vertices(not the minimum distance between their vertices). I have to find the minimum of shortest distance between each vertex of first shape with all of the vertices of the other one. Something like the Hausdorff Distance, but I need the minimum instead of the maximum.
Perhaps you should check out (PDF warning! Also note that, for some reason, the order of the pages is reversed) "Optimal Algorithms for Computing the Minimum Distance Between Two Finite Planar Sets" by Toussaint and Bhattacharya:
It is shown in this paper that the
minimum distance between two finite
planar sets if [sic] n points can be
computed in O(n log n) worst-case
running time and that this is optimal
to within a constant factor.
Furthermore, when the sets form a
convex polygon this complexity can be
reduced to O(n).
If the two polygons are crossing convex ones, perhaps you should also check out (PDF warning! Again, the order of the pages is reversed) "An Optimal Algorithm for Computing the Minimum Vertex Distance Between Two Crossing Convex Polygons" by Toussaint:
Let P = {p1,
p2,..., pm} and Q = {q1, q2,...,
qn} be two intersecting polygons whose vertices are specified
by their cartesian coordinates in
order. An optimal O(m + n)
algorithm is presented for computing
the minimum euclidean distance between
a vertex pi in P and a
vertex qj in Q.
There is a simple algorithm that uses Minkowski Addition that allows calculating min-distance of two convex polygonal shapes and runs in O(n + m).
Links:
algoWiki, boost.org, neerc.ifmo.ru (in russian).
If Minkowski subtraction of two convex polygons covers (0, 0), then they intersect
Given N points in a map of edges Map<Point, List<Edge>>, it's possible to get the polygons formed by these edges in O(N log N)?
What I know is that you have to walk all the vertices and get the edges containing that vertex as a starting point. These are edges of a voronoi diagram, and each vertex has, at most, 3 artists containing it. So, in the map, the key is a vertex, and the value is a list where the vertex is the start node.
For example:
Points: a,b,c,d,e,f,g
Edges: [a,b]; [a,c]; [a,d], [b,c], [d,e], [e,g], [g,f]
My idea is to iterate the map counterclockwise until I get the initial vertex. That is a polygon, then I put it in a list of polygons and keep looking for others. The problem is I do not want to overcome the complexity O(N log N)
Thanks!
You can loop through the edges and compute the distance from midpoint of the edge to all sites. Then sort the distances in ascending order and for inner voronoi polygons pick the first and the second. For outer polygons pick the first. Basically an edge separate/divide 2 polygons.
It's something O(m log n).
If I did find a polynomial solution to this problem I would not post it here because I am fairly certain this is at least NP-Hard. I think your best bet is to do a DFS. You might find this link useful Finding all cycles in undirected graphs.
You might be able to use the below solution if you can formulate your graph as a directed graph. There are 2^E directed graphs (because each edge can be represented in 2 directions). You could pick a random directed graph and use the below solution to find all of the cycles in this graph. You could do this multiple times for different random directed graphs keeping track of all the cycles and until you've reached a satisfactory error bounds.
You can efficiently create a directed graph with a little bit of state (Maybe store a + or - with an edge to note the direction?) And once you do this in O(n) the first time you can randomly flip x << E directions to get a new graph in what will essentially be constant time.
Since you can create subsequent directed graphs in constant time you need to choose the number of times to run the cycle finding algorithm to have it still be polynomial and efficient.
UPDATE - The below only works for directed graphs
Off the top of my head it seems like it's a better idea to think of this as a graph problem. Your map of vertices to edges is a graph representation. Your problem reduces to finding all of the loops in the graph because each cycle will be a polygon. I think "Tarjan's strongly connected components algorithm" will be of use here as it can do this in O(v+e).
You can find more information on the algorithm here https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
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.
I have adjacency matrix for graph. I need to vizualize this graph without intersecting edges.
Vertex in the graph can be arranged randomly. I know one solution - enumeration of all edges for intersections. If the edges intersect, then rearrange the vertex, but it's too expensive for a large number of vertexes (more than 20).
Any other ideas how to check for intersecting edges?
It's really easy to visualise any graph in a 3D plane with disjoint edges.
1) Place all the vertices in any point in the 3D plane such that no three vertices are collinear and no four vertices are in same plane.
2) Traverse through the adjacency matrix and draw a line/curve to connect the vertices.
In a 2D plane it's not guaranteed for the existence of a solution. For example take the worst case scenario that there are some 10 vertices and every vertex is connected to each other.
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.