Minimum bounding box algorithm in 3D - algorithm

The minimum bounding box (MBB) is the box around a cloud of 3D points with the smallest volume.
Joseph O'Rourke published [2] a cubic-time algorithm to find the minimum-volume enclosing box of a 3-dimensional point set. O'Rourke's approach uses a 3-dimensional rotating calipers technique.
I read the article and wiki (Minimum bounding box algorithms) [1]. Due to the
extremely complicated, I gained nothing. Furthermore, the execution steps of the algorithm are my next problem.
I want to write O'Rourke's algorithm by Fortran.
Any tips about algorithm or flowchart, etc, makes me happy.

Just a hint about the spirit of the algorithm.
In the first place you need to compute the convex hull of the points set, an O(N Log N) process in 2 and 3D. This gives a convex polygon (described by a ring of vertices) or polyhedron (described as a planar graph).
The next step is combinatorial and consists in trying all the positions that are potentially the tightest. In 2D, a minimum bounding box is flush with an edge, and it suffices to try the directions of all edges in turn (you rotate the polygon so that the edge becomes horizontal, and construct the AABB).
The 3D case is more elaborate and uses the fact that a tightest box is flush with two edges of the polyhedron, on two adjacent faces of the box (the box is not necessarily flush with a face). This property allows to generate a finite number of orientations by trying all pairs of edges, and as above, bring the edges in two coordinate planes and construct the AABB. This takes a little of spherical trigonometry.

Related

How to compute the set of polygons from a set of overlapping circles?

This question is an extension on some computation details of this question.
Suppose one has a set of (potentially overlapping) circles, and one wishes to compute the area this set of circles covers. (For simplicity, one can assume some precomputation steps have been made, such as getting rid of circles included entirely in other circles, as well as that the circles induce one connected component.)
One way to do this is mentioned in Ants Aasma's and Timothy's Shields' answers, being that the area of overlapping circles is just a collection of circle slices and polygons, both of which the area is easy to compute.
The trouble I'm encountering however is the computation of these polygons. The nodes of the polygons (consisting of circle centers and "outer" intersection points) are easy enough to compute:
And at first I thought a simple algorithm of picking a random node and visiting neighbors in clockwise order would be sufficient, but this can result in the following "outer" polygon to be constructed, which is not part of the correct polygons.
So I thought of different approaches. A Breadth First Search to compute minimal cycles, but I think the previous counterexample can easily be modified so that this approach results in the "inner" polygon containing the hole (and which is thus not a correct polygon).
I was thinking of maybe running a Las Vegas style algorithm, taking random points and if said point is in an intersection of circles, try to compute the corresponding polygon. If such a polygon exists, remove circle centers and intersection points composing said polygon. Repeat until no circle centers or intersection points remain.
This would avoid ending up computing the "outer" polygon or the "inner" polygon, but would introduce new problems (outside of the potentially high running time) e.g. more than 2 circles intersecting in a single intersection point could remove said intersection point when computing one polygon, but would be necessary still for the next.
Ultimately, my question is: How to compute such polygons?
PS: As a bonus question for after having computed the polygons, how to know which angle to consider when computing the area of some circle slice, between theta and 2PI - theta?
Once we have the points of the polygons in the right order, computing the area is a not too difficult.
The way to achieve that is by exploiting planar duality. See the Wikipedia article on the doubly connected edge list representation for diagrams, but the gist is, given an oriented edge whose right face is inside a polygon, the next oriented edge in that polygon is the reverse direction of the previous oriented edge with the same head in clockwise order.
Hence we've reduced the problem to finding the oriented edges of the polygonal union and determining the correct order with respect to each head. We actually solve the latter problem first. Each intersection of disks gives rise to a quadrilateral. Let's call the centers C and D and the intersections A and B. Assume without loss of generality that the disk centered at C is not smaller than the disk centered at D. The interior angle formed by A→C←B is less than 180 degrees, so the signed area of that triangle is negative if and only if A→C precedes B→C in clockwise order around C, in turn if and only if B→D precedes A→D in clockwise order around D.
Now we determine which edges are actually polygon boundaries. For a particular disk, we have a bunch of angle intervals around its center from before (each sweeping out the clockwise sector from the first endpoint to the second). What we need amounts to a more complicated version of the common interview question of computing the union of segments. The usual sweep line algorithm that increases the cover count whenever it scans an opening endpoint and decreases the cover count whenever it scans a closing endpoint can be made to work here, with the adjustment that we need to initialize the count not to 0 but to the proper cover count of the starting angle.
There's a way to do all of this with no trigonometry, just subtraction and determinants and comparisons.

Algorithm to create minimal bounding-box composition of point cloud

I have a set of 2D points.
I want to find a set of (possibly overlapping and arbitrarily oriented) bounding-boxes for subsets of these points such that each point lies within at least one box, each box contains at least k points and such that the combined area of the boxes is minimized.
One idea for an algorithm I have is:
use a concave-hull algorithm to find a concave hull for the points.
use convex decomposition algorithm to find a set of convex hulls.
compute arbitrarily oriented minimum bounding box for each of the convex hulls.
I'm looking for a list of other (potentially better suited) algorithms for this problem?

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.

How to find convex hull in a 3 dimensional space

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.)

How to fill polygon with points regularly?

It is simple to fill rectangle: simply make some grid. But if polygon is unconditioned the task becomes not so trivial.
Probably "regularly" can be formulated as distance between each other point would be: R ± alpha. But I'm not sure about this.
Maybe there is some known algorithm to achieve this.
Added:
I need to generate net, where no large holes, and no big gathering of the points.
Have you though about using a force-directed layout of the points?
Scatter a number of points randomly over the bounding box of your polygon, then repeatedly apply two simple rules to adjust their location:
If a point is outside of the polygon, move it the minimum possible distance so that it lies within, i.e.: to the closest point on the polygon edge.
Points repel each other with a force inversely proportional to the distance between them, i.e.: for every point, consider every other point and compute a repulsion vector that will move the two points directly apart. The vector should be large for proximate points and small for distant points. Sum the vectors and add to the point's position.
After a number of iterations the points should settle into a steady state with an even distribution over the polygon area. How quickly this state is achieved depends on the geometry of the polygon and how you've scaled the repulsive forces between the points.
You can compute a Constrained Delaunay triangulation of the polygon and use a Delaunay refinement algorithm (search with this keyword).
I have recently implemented refinement
in the Fade2D library, http://www.geom.at/fade2d/html/. It takes an
arbitrary polygon without selfintersections as well as an upper bound on the radius of the circumcircle of each resulting triangle. This feature is not contained in the current release 1.02 yet, but I can compile the current development version for Linux or Win64 if you want to try that.

Resources