Which are 3d convex object slicing algorithms (which is there complexity)? - algorithm

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.

Related

Minimum bounding rectangle of polygon

Let's say we have a class/struct Point
class Point
{
int x;
int y;
}
and a class Polygon that contains list of Points
class Polygon
{
List<Point> points;
Path(List<Point> points)
{
//some implementation
}
}
I am interested in finding the Minimal bounding rectangle points of the Polygon(https://en.wikipedia.org/wiki/Minimum_bounding_rectangle). The found minimal bounding rectangle sides might not be parallel to both axis , so I am trying to find an algorithm written in Java,C#,C++ .Can anyone propose or link such a solution, thanks!
It is possible to construct minimal bounding box (both min-area and min-perimeter) using Rotating Calipers approach.
You can find description at this wayback archive page
The minimum area rectangle enclosing a convex polygon P has a side
collinear with an edge of the polygon.
The above result dramatically restricts the range of possible
rectangles. Not only is it not necessary to check all directions, but
only as many as the polygon's number of edges.
Illustrating the above result: the four lines of support (red), with
one coinciding with an edge, determine the enclosing rectangle (blue).
A simple algorithm would be to compute for each edge the corresponding
rectangle collinear with it. But the construction of this rectangle
would imply computing the polygon's extreme points for each edge, a
process that takes O(n) time (for n edges). The entire algorithm would
then have quadratic time complexity.
A much more efficient algorithm can be found. Instead of recomputing
the extreme points, it is possible to update them in constant time,
using the Rotating Calipers. Indeed, consider a convex polygon, with a
two pair of lines of support through all four usual extreme points in
the x and y directions. The four lines already determine an enclosing
rectangle for the polygon. But unless the polygon has a horizontal or
vertical edge, this rectangle is not a candidate for the minimum area.
However, the lines can be rotated until the above condition is
satisfied. This procedure is at the heart of the following algorithm.
The input is assumed to be a convex polygon with n vertices given in
clockwise order.
Compute all four extreme points for the polygon, and call them xminP,
xmaxP, yminP ymaxP.
Construct four lines of support for P through all four points. These
determine two sets of "calipers".
If one (or more) lines coincide with an edge, then compute the area of
the rectangle determined by the four lines, and keep as minimum.
Otherwise, consider the current minimum area to be infinite.
Rotate the lines clockwise until one of them coincides with an edge of
its polygon.
Compute the area of the new rectangle, and compare it to the current
minimum area. Update the minimum if necessary, keeping track of the
rectangle determining the minimum.
Repeat steps 4 and 5, until the lines have been rotated an angle
greater than 90 degrees. Output the minimum area enclosing rectangle.
Because two pairs of "calipers" determine an enclosing rectangle, this
algorithm considers all possible rectangles that could have the
minimum area. Furthermore, aside from the initialization, there are
only as many steps in the algorithm's main loop as there are vertices.
Thus the algorithm has linear time complexity.
You can do this as follows:
Find the convex hull of the polygon points. A popular method is the Graham scan.
For each edge of the convex hull, find the minimum bounding rectangle that must have one side overlapping with that edge, so that the convex hull's edge is a subsegment of that rectangle's side.
Find the two perpendicular sides of the rectangle by walking along the convex hull vertices, and projecting the vertex to the first side, retaining the two that have all other projections between them. The final opposite side can be found in a similar manner. The vertices that lie on the rectangle, should be the starting point for when this step is executed again for the next edge on the convex hull (step 2).
Calculate the size of these rectangles, and retain the minimal one.
The complexity of this algorithm is determined by the first step, which is O(nlogn). The second step is O(n), as you have a selection of one edge and 3 vertices that rotates around the convex hull, visiting each edge once, and each vertex 3 times.

Checking which triangles intersect a convex hull

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.

Continuous Collision Detection in 3D for Two Convex Polyhedra

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

Confusion on Delaunay Triangulation and Largest inscribed circle

I need to find a largest inscribed circle of a convex polygon, I've searched many sites and I get that this can be done by using Delaunay triangulation. I found a thread in CGAL discussion with an algorithm using CGAL:
You can compute this easily with CGAL:
First, compute the Delaunay triangulation of the points.
Then, iterate on all the finite faces of the triangulation.
For each finite face f
compute its circumcenter c
locate c in the triangulation (to speed up things, you can give one
vertex of f as starting hint for the point location)
if the face returned by locate(c,hint) is finite, then the circumcenter
c lies in the convex hull of the points, so, f is a candidate
if f is such a candidate face, compute its squared circumradius
keep only the face with minimum squared circumradius
The CGAL manual (chapter 2D triangulation, together with a few things
from the kernel) shows every basic function to do this.
I was a bit confused with the last part of this algorithm. When I read it what I understand from it is that the minimum circumradius of the triangulation face is the radius for the largest inscibed circle. But from examples of polygon with Delaunay triangulation, it seems that even the smallest circumcircle sometimes cannot fit inside the polygon, so how can this has the same radius as the largest inscribed circle?
Maximum inscribed circle in polygons.
The classical computational-geometry solution to the maximum inscribed circle problem for polygons is to use the generalized Voronoi diagram of the polygon's faces resp. the medial axis of the polygon. This approach works in a more general setting like polygons with holes, see this stackoverflow answer to a similar question.
Convex input.
The convexity of your input polygon, however, gives the problem more structure, which I would like to comment on. Consider the following convex input polygon (black), the Voronoi diagram (blue), and the maximum inscribed circle (green) centered on a Voronoi node.
The classical Voronoi-based solution is to (i) compute the Voronoi diagram and (ii) take the Voronoi node with largest clearance (i.e., distance to its defining faces).
The Voronoi diagram of a polygon with holes (i.e., the set of vertices and edges) can be computed in O(n log n) time, c.f. Fortune's algorithm (1986). Later Chin et alii (1999) gave an O(n) algorithm for the medial axis of a simple polygon.
For convex polygons, however, a time-optimal algorithm for Voronoi diagram that runs in O(n) time was already known in 1989 due to Aggarwal et alii. This algorithm follows basically the following idea: Consider the grey offset curves moving inwards at unit speed. If you project this movement into three-space where the z-axis is time you get a unit-slop roof over the polygon:
This roof model could also be characterized as follows: Put a half-space on each polygon edge at 45° slope with polygon (such that they contain the polygon) and intersect them all. So if you can quickly compute the intersect of half-spaces then you can also quickly compute Voronoi diagrams of convex polygons. Actually, for the maximum inscribed circle problem we do not need to go back to the Voronoi diagram but take the one peak of the roof, which marks the center of the maximum inscribed circle.
Now the half-spaces are dualized to points, and then the intersection of half-spaces corresponds the convex hull of its dual points. Aggarwal et al. now found an O(n) algorithm for the convex hull of points that stem from this setting.
A summary of this construction that leads to a Voronoi diagram algorithm for convex polyhedra in any dimension can be found in a blog article of mine.
Simple & fast implementation. A simpler algorithm to compute the Voronoi diagram is motivated by straight skeletons. For convex polygons the Voronoi diagram and the straight skeleton are the same.
The algorithm behind the straight-skeleton implementation Stalgo basically simulates the evolution of the wavefront structure (the grey offset curves). For convex polygons this reduces to finding the sequence of edges that collapse.
So a simple O(n log n) algorithm could look like this:
Construct a circular list of the polygon edges. Compute the collapse time of each edge during wavefront propagation, and insert this event into a priority queue.
Until the queue is empty: Take out the next edge-collapse event: Remove the edge from the circular structure and update the collapse times of the neighboring edges of the removed edge.
Actually, you can simplify the above algorithm further: You do not need to update edge collapses in the priority queue but simply insert new ones: Since the new collapse time of edges are strictly lower, you always get the right event first and dismiss the others and the queue is not growing larger than 2n. Hence, you do not compromise the O(n log n) time complexity.
For the maximum inscribed circle problem you can simplify the above algorithm even further: The Voronoi node (resp. straight skeleton node) you look for is due to the collapse of the final triangle at the end of the loop over the priority queue.
This algorithm should be quick in practice and only a few lines of code.
The last step can mean to select the minimum face of the triangle. Then rinse and repeat.

why is finding a point in a non-convex polygon harder than in a convex polygon?

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.

Resources