For a collision check I need to calculate time when two convex polyhedra intersect if one of them is moving along a straight line. Currently, I have:
Input: Convex polyhedron defined as a set of points of one object A and its movement direction.
Input: Convex polyhedron defined as a set of points of second object B
Calculate Minkowski sum of the two sets of points C, |C| = |A| * |B|
Calculate triangulated convex hull of C (using QuickHull)
Line intersection against triangles of the convex hull and store minimum and maximum distance along line.
This all works, but is slow. Especially the step to calculate the triangulated convex hull.
I wonder if there is a faster way to calculate the ray-convex polyhedron intersection from the set of points without calculating the triangulated convex hull. I could get the input as planes (plane equations) if it helps.
Solved by separation axis theorem:
Input: convex collision volumes as both points and plane equations
For each plane in both collision volumes, calculate shift along the movement direction when each plane becomes a separation plane (vertices of the other collision volume are all in front of the plane).
Calculate interval of shift when there is no separation plane. This can be done in place by keeping track of minimum and maximum values encountered.
Compared to the original solution:
Theoretical complexity down from O(N log N) to O(N), where N = |C| = |A| * |B|
Works in place - no memory allocation
Related
I have a bunch of 2D triangles (i.e., in R2), as well as a 2D convex hull (represented as a set of linear constraints), and I need to check which of those triangles intersect the convex hull. What algorithms are there for doing this?
At a later stage, I might also need to generalize the problem to higher dimensions than 2D (i.e., out of a set of simplexes in Rd, check which of those intersect a convex hull in Rd), so if you know of an algorithm that can handle the general case that would also be nice.
You can solve the 2D problem in two steps:
construct the vertices of the convex hull;
intersect the triangles and the hull, which are both convex polygons (https://www.bowdoin.edu/~ltoma/teaching/cs3250-CompGeom/spring17/Lectures/cg-convexintersection.pdf). The time for intersection will be O(N) for a hull of N vertices.
If you need to do this for many triangles, a possibility is to decompose the hull in two monotone chains along along an axis, say X, and find the overlap range of the hull and every triangle by dichotomic search. This will lower the time to O(Log N + K) where K is the average number of sides of the hull in X-overlap with the triangles.
Given a set of points S (x, y, z). How to find the convex hull of those points ?
I tried understanding the algorithm from here, but could not get much.
It says:
First project all of the points onto the xy-plane, and find an edge that is definitely on the hull by selecting the point with highest y-coordinate and then doing one iteration of gift wrapping to determine the other endpoint of the edge. This is the first part of the incomplete hull. We then build the hull iteratively. Consider this first edge; now find another point in order to form the first triangular face of the hull. We do this by picking the point such that all the other points lie to the right of this triangle, when viewed appropriately (just as in the gift-wrapping algorithm, in which we picked an edge such that all other points lay to the right of that edge). Now there are three edges in the hull; to continue, we pick one of them arbitrarily, and again scan through all the points to find another point to build a new triangle with this edge, and repeat this until there are no edges left. (When we create a new triangular face, we add two edges to the pool; however, we have to first check if they have already been added to the hull, in which case we ignore them.) There are O(n) faces, and each iteration takes O(n) time since we must scan all of the remaining points, giving O(n2).
Can anyone explain it in a more clearer way or suggest a simpler alternative approach.
Implementing the 3D convex hull is not easy, but many algorithms have been implemented, and code is widely available. At the high end of quality and time investment to use is CGAL. At the lower end on both measures is my own C code:
In between there is code all over the web, including this implementation of QuickHull.
I would suggest first try an easier approach like quick hull. (Btw, the order for gift wrapping is O(nh) not O(n2), where h is points on hull and order of quick hull is O(n log n)).
Under average circumstances quick hull works quite well, but processing usually becomes slow in cases of high symmetry or points lying on the circumference of a circle. Quick hull can be broken down to the following steps:
Find the points with minimum and maximum x coordinates, those are
bound to be part of the convex.
Use the line formed by the two points to divide the set in two
subsets of points, which will be processed recursively.
Determine the point, on one side of the line, with the maximum
distance from the line. The two points found before along with this
one form a triangle.
The points lying inside of that triangle cannot be part of the
convex hull and can therefore be ignored in the next steps.
Repeat the previous two steps on the two lines formed by the
triangle (not the initial line).
Keep on doing so on until no more points are left, the recursion has
come to an end and the points selected constitute the convex hull.
See this impementaion and explanation for 3d convex hull using quick hull algorithm.
Gift wrapping algorithm:
Jarvis's match algorithm is like wrapping a piece of string around the points. It starts by computing the leftmost point l, since we know that the left most point must be a convex hull vertex.This process will take linear time.Then the algorithm does a series of pivoting steps to find each successive convex hull vertex untill the next vertex is the original leftmost point again.
The algorithm find the successive convex hull vertex like this: the vertex immediately following a point p is the point that appears to be furthest to the right to someone standing at p and looking at the other points. In other words, if q is the vertex following p, and r is any other input point, then the triple p, q, r is in counter-clockwise order. We can find each successive vertex in linear time by performing a series of O(n) counter-clockwise tests.
Since the algorithm spends O(n) time for each convex hull vertex, the worst-case running time is O(n2). However, if the convex hull has very few vertices, Jarvis's march is extremely fast. A better way to write the running time is O(nh), where h is the number of convex hull vertices. In the worst case, h = n, and we get our old O(n2) time bound, but in the best case h = 3, and the algorithm only needs O(n) time. This is a so called output-sensitive algorithm, the smaller the output, the faster the algorithm.
The following image should give you more idea
GPL C++ code for finding 3D convex hulls is available at http://www.newtonapples.net/code/NewtonAppleWrapper_11Feb2016.tar.gz and a description of the O(n log(n)) algorithm at http://www.newtonapples.net/NewtonAppleWrapper.html
One of the simplest algorithms for convex hull computation in 3D was presented in the paper The QuickHull algorithm for Convex Hulls by Barber, etc from 1995. Unfortunately the original paper lacks any figures to simplify its understanding.
The algorithm works iteratively by storing boundary faces of some convex set with the vertices from the subset of original points. The remaining points are divided on the ones already inside the current convex set and the points outside it. And each step consists in enlarging the convex set by including one of outside points in it until no one remains.
The authors propose to start the algorithm in 3D from any tetrahedron with 4 vertices in original points. If these vertices are selected so that they are on the boundary of convex hull then it will accelerate the algorithm (they will not be removed from boundary during the following steps). Also the algorithm can start from the boundary surface containing just 2 oppositely oriented triangles with 3 vertices in original points. Such points can be selected as follows.
The first point has with the minimal (x,y,z) coordinates, if compare coordinates lexicographically.
The second point is the most distant from the first one.
The third point is the most distant from the line through the first two points.
The next figure presents initial points and the starting 2 oppositely oriented triangles:
The remaining points are subdivided in two sets:
Black points - above the plane containing the triangles - are associated with the triangle having normal oriented upward.
Red points - below the plane containing the triangles - are associated with the triangle having normal oriented downward.
On the following steps, the algorithm always associates each point currently outside the convex set with one of the boundary triangles that is "visible" from the point (point is within positive half-space of that triangle). More precisely each outside point is associated with the triangle, for which the distance between the point and the plane containing the triangle is the largest.
On each step of algorithm the furthest outside point is selected, then all faces of the current convex set visible from it are identified, these faces are removed from the convex set and replaced with the triangles having one vertex in furthest point and two other points on the horizon ridge (boundary of removed visible faces).
On the next figure the furthest point is pointed by green arrow and three visible triangles are highlighted in red:
Visible triangles deleted, back faces and inside points can be seen in the hole, horizon ridge is shown with red color:
5 new triangles (joining at the added point) patch the hole in the surface:
The points previously associated with the removed triangles are either become inner for the updated convex set or redistributed among new triangles.
The last figure also presents the final result of convex hull computation without any remaining outside points. (The figures were prepared in MeshInspector application, having this algorithm implemented.)
I've heard a lot of people say that programmatically finding a point in a non-convex polygon is harder than finding a point in a convex polygon. I'm having trouble wrapping my head around this. Is this true? If so, why?
So you want to check whether point P is inside a polygon or outside.
If the polygon is convex, then you can iterate over each line segment making up the polygon, and check which side of that line P lies on. P is on the inside of the polygon if it is on the right-hand side of every line segment, going clockwise.
If the polygon is concave, this algorithm doesn't work. An algorithm that works for concave polygons is to trace from P in an arbitrary direction to infinity, and count the number of times an edge of the polygon is crossed. P is inside the polygon if and only if the number of crossings is odd. This algorithm has a bunch of edge cases to consider and is generally more complicated, so it will take a lot more programmer effort to write the algorithm.
In the sense that the algorithm is more difficult to write correctly, yes, it is harder.
In the sense of computational complexity, both algorithms have Θ(N) asymptotic running time. In that sense, both problems are equally hard.
For a convex polygon, you can choose any point p inside the polygon (e.g. the center of mass of all the vertices) and then sort the vertices in a circular array according to the angle they make with p. Then, given a query point x, you can compute the angle from p to x, and search through the array and find the two neighboring vertices in the array for which the angle to x is between the angles to the two vertices. Then you compute the intersection between the line from p to x, and the edge between the two vertices. If the distance from p to the intersection point is greater than or equal to the distance from p to x, then x is inside the polygon, otherwise x is outside the polygon. This gives O(log n) time to determine is a point is inside or outside of a convex polygon. On the other hand, the best known algorithm to determine if a point is inside or outside a non-convex polygon is O(n) time. Note however you can make a hybrid algorithm depending on how much "non-convexity" you have in your polygon. You can always decompose a polygon into a union of convex polygons, by adding extra internal edges; suppose your polygon only has a few "turns" in it and you can decompose into k convex polygons where k is small. Then you can use the strategy for convex polygons to determine if a point is inside or outside in O(k log n) time. So in general, the "more convexity" you have, the faster you can determine if a point is inside the polygon.
I wonder what are most fast (in terms of O(N)) algorithms that having a convex three dimentional object and its left top bounding box corner positioned in some XYZ can prvide its cross section with some plane defined by 3 points of 3d space?
Here's one possible algorithm (assuming the object is a convex polygonal solid):
Compute the intersection between the plane and each edge of the object. If the edge is coplanar with the plane, then just assume it intersects at each endpoint of the edge.
Sort the intersection points in clockwise order.
That's it. The intersection between a plane and a convex polygonal solid must be itself a convex polygon, and this simple algorithm gives you exactly the points of the polygon.
Since calculating the intersection of a plane and an edge takes constant time, the time is O(E + K log K), where E is the number of edges in the solid and K is the number of intersection points (points in the final polygon). K might on the order of E in the worst case, so the total running time is O(E log E) in the worst case.
I'm working on the implementation of an algorithm used to determine the safest point for a drone to land, using this paper.
To do so I'm tring to find two parallel planes enclosing a set of 9 points while minimizing the distance r between those two planes.
r will then represent the roughness of the terrain.
I would like a general strategy to solve the problem or a link to a paper describing a solution.
Can you do the following:
Find the convex hull of the 9 points
For each plane p in the convex hull, find the point pt not in p that is the farthest away, let the second plane be that which is parallel to p and passes through pt and compute the distance
Take the minimum
The goal is to find planes normal. Then building the planes is easy.
And there is finite number of candidates for plane normal: cross-products of edge vectors of convex hull (this includes but is not limited to face normals). For this number of points you can just count them all.
Why?
Every plane touches some non-zero number of points (otherwise it can be moved closer).
If we can rotate planes even slightly without losing connection with these points, distance will decrease.
So the optimum planes can not rotate.
If a plane touches two points, it can rotate only around this edge.
A plane cannot rotate if it touches two non-parallel edges.
Then its normal is cross-product of those edge vectors.