Let P be a 3D convex polyhedron with n vertices.
1. Given an algorithm that takes an arbitrary point q as input, how can I decide in O(n) time whether q is inside or outside the convex polyhedron?
2. Can I do some processing to make it O(logn)?
For (1), if you have a convex polyhedron with n vertices then you have also O(n) faces. One could triangulate each face and in total it would still be O(n) triangles. Now take the query point q and check on which side of a triangle q lies. This check takes O(1) for one triangle, thus O(n) for all triangles.
EDIT: The O(n) faces define O(n) planes. Just check if q lies on the same side for all planes.
For (2), (I did not find source for this but it seem reasonable) one could project the polyhedron P as P' onto a plane. P' can be seen as two separate planar graphs, one graph U' for the upper part of the polyhedron and the second graph L' for the lower part. In total there are O(n) faces in L' and U'. Now one can preprocess L' and U' via Kirkpatrick optimal planar subdivision algorithm. (Other sources for it: 1 and 2) This enables O(log n) point in PSLG (planar straight line graph) checks.
Now using the query point q and projecting it to the same plane with the same projection one can look up the face of L' and U' it lies in in O(log n) time. In 3D each face lies in exactly one plane. Now we check on which side q lies in 3D an know if q is inside the polyhedron.
Another approach for (2) will be spacial subdivision of the polyhedron into slubs - pyramids with their vertex in the polyhedron centroid and polyhedron faces as their bases. Number of such slabs is O(n). You can build a binary space partitioning tree (BSP), consisting of these slubs (probably divided into sub-slubs) - if it's balanced, then the point location will work in O(logn) time.
Of course, it will make sense, if you need to call the point location function many times - because the pre-processing step here will take O(n) time (or more).
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
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.
Say we have a n x n chess board (or a matrix in other words) and each square has a weight to it. A piece can move horizontally or vertically, but it can't move diagonally. The cost of each movement will be equal to the difference of the two squares on the chess board. Using an algorithm, I want to find the minimum cost for a single chess piece to move from the square (1,1) to square (n,n) which has a worst-case time complexity in polynomial time.
Could dikstras algorithm be used to solve this? Would my algorithm below be able to solve this problem? Diijkstras can already be ran in polynomial time, but what makes it this time complexity?
Pseudocode:
We have some empty set S, some integer V, and input a unweighted graph. After that we complete a adjacency matrix showing the cost of an edge without the infinity weighted vertices and while the matrix hasn't picked all the vertices we find a vertex and if the square value is less then the square we're currently on, move to that square and update V with the difference between the two squares and update S marking each vertices thats been visited. We do this process until there are no more vertices.
Thanks.
Since you are trying to find a minimum cost path, you can use Dijkstra's for this. Since Dijkstra is O(|E| + |V|log|V|) in the worst case, where E is the number of edges and V is the number of verticies in the graph, this satisfies your polynomial time complexity requirement.
However, if your algorithm considers only costs associated with the beginning and end square of a move, and not the intermediate nodes, then you must connect all possible beginning and end squares together so that you can take "short-cuts" around the intermediate nodes.
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.
I've been studying Delaunay triangulation (not a homework) and I thought about the following problem : given a set of points S on plane (with cardinality of n) and a set of triangles T (should be with the cardinality of n-2) — how to determine if the triangles set T form a Delaunay triangulation DT(S)?
The first problem is that Delaunay triangulation is not unique, so rebuilding it for the points set again and comparing to the triangles set won't give us the answer. In addition, optimal Delaunay triangulation algorithms are rather hard to implement (however, using libraries like CGAL would have been okay).
Suppose we know how to check if the triangles set is a triangulation (not necessarily Delaunay). Then we should use the definition of a Delanuay triangulation: for every triangle t in triangulation, no point in S is strictly inside the circumference of t. This leads us to the following methods:
The trivial approach. Just iterate over T, compute the circumference and iterate over S, checking if point is inside the circumference. However, this takes O(n^2) time, which is not very optimal.
The enchanted approach. Again, iterate over T and compute the circumference. If any point s in inside the circumference, it means that its distance to the circumference center is less than the radius. Using nearest neighbour searching structures over S, we will speed up our algorithm. For instance, simple kd-tree structure leads us to O(n log n) algorithm in average and O(n sqrt(n)) in the worst case.
Does anyone have an idea of something simpler?
Now let's return to the problem of checking if T is a triangulation at all. Trivial pre-requirements like equality of S and the set of triangles' vertices can be performed no faster than O(n log n). What is left — to check that every two triangles in T intersect in a common face, or not at all.
Again, we could do this by iterating over T and again over T, checking for intersection, but this is O(n^2) algorithm.
Let's think about what «triangles t1 and t2 intersect» mean? They intersect if their edges intersect or if one triangle is completely lies in another. The problem of intersecting all the edges can be solved at O(n log n) time using Bentley-Ottmann algorithm (the worst case is O((n + k) log n), where k is the count of intersections, but we can stop the algorithm at the moment we find the first intersection). Also we didn't recognize the case of one triangle completely containing another, but I believe we can modify Bentley-Ottmann algorithm to maintain triangles crossing the sweep line instead of segments, which as I said, yields us O(n log n) algorithm. However, it is really complex to implement.
I've thought about iterative algorithm — let's maintain the structure of non-intersecting (or only intersecting by edge) triangles (it should be something very similar to kd-tree). Then we try to add the next triangle t: first check if any of t's vertices is already in one of the triangles — then we got an intersection. Otherwise, add t to the structure. However, if we want O(log n) or O(sqrt(n)) time for search and add queries, we have to balance this structure's height, which is too hard even for kd-trees.
So, does anyone know any simple solution to this problem?
There is a Delaunay lemma : "If every edge in a triangulation K of S is locally Delaunay then K is the Delaunay triangulation of S". Maybe this could help in situation from paragraph 1 of your question, where you are certain that K is some triangulation of S. Dunno the computational complexity of this approach though.