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.
Related
I have generated 2 sets of convex polygons from with different algorithms. Every polygon in each set is described by an array of coordinates[n_points, xy_coords], so a square is described by an array [4,2] but a pentagon with rounded corners has [80,2], with the extra 75 points being used to describe the curvatures.
My goal is to quantify how similar the two sets of geometries are.
Can anyone recommend any methods of doing so?
So far I've come across:
Hamming Distance
Hausdorff distance
I would like to know what other robust measures of similarity for 2D polygons. The method ideally needs to be robust across convex polygons and and give a measure of similarity between large sets (10,000+ each).
As I understood you look for shape similarity or shape analysis algorithms. You will find more robust methods here: https://www.cs.princeton.edu/courses/archive/spr00/cs598b/lectures/polygonsimilarity/polygonsimilarity.pdf
and
https://student.cs.uwaterloo.ca/~cs763/Projects/phil.pdf
Turning function;
Graph matching;
Shape signature.
Assuming that both polygons are aligned, centered and convex you could try to assess similarity by computing ratio of area a smaller polygon to area of convex hull of both polygons.
Ratio = Min(Area(A), Area(B)) / Area(ConvexHull(A, B))
The ratio will be 1 if both polygon are equal, and 0 if the differ severely like a point and a square.
Area of the polygon can be computed in O(N) time. See Area of polygon.
The convex hull can be computed in O(N log N). See Convex Hull Computation. It could be speed up to O(N) by merge-sorting already sorted vertices of both polygons and applying the second phase of Graham Scan Algorithm.
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
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.
The problem is to find the closest features between two 2d concave polygons. The features can be vertex, edge. So result can be any combination of features. Is there any simple solution with complexity better than O(m*n)? where m, n - number of edges of polygons respectively. The polygons are coplanar.
An algorithm in O(n.log(m)) seems to exists, please see this paper, and this question.
An optimization of mine you could try: (not tested)
If your polygons are most of the time far apart enough, you can build the two convex hull and fall back on the easiest problem of finding the Hausdorff distance between two convex polygons (solution in O(n+m)). If the distance is 0, you have to fall back to the O(m.log(n)) case, but it's worth it if you are most of the time in the "convex hull" case with a positive distance.
Post-Scriptum. I just realized that in order of the postulate to work, you also need to check that the closest features from the convex hulls belongs to the original concave polygon. If not, it's easy to find a counter-example (imagine a polygon in shape of the letter C with another round just nearby: CO).
The updated postulate is then: The Hausdorff distance d between two concave polygons is the Hausdorff distance between their convex hulls, if d > 0, and both closest features are part of the original polygons.
The proof of this is left as an exercice to the reader.