Calculate minimum area rectangle for a polygon - c++

I have a need to calculate the minimum area rectangle (smallest possible rectangle) around the polygon.
The only input i have is the number of points in polygon.
I have the co-ordinates of the points also.

This is called Minimum Bounding Box, it's most basic algorithm used in OCR packages. You can find an implementation using Rotating Calipers from the OpenCV package. Once you get the source code, check out this file,
cv/src/cvrotcalipers.cpp
The method you need is cvMinAreaRect2().

Use the rotating calipers algorithm for a convex polygon, or the convex hull otherwise. You will of course need the coordinates of the points in the polygon, not just the number of points.

First do a grahm-scan and get the convex hull of the set of points. Then you can use something like minimum rectangle discussed here

Follow the following algorithm
Rotate the polygon onto the XY plane
Pick 1 edge and align this edge with the X axis(use arctan). Use the min/max x,y to find the bounding rectangle. Compute Area and store in list
Do the same for remaining edges in clipped polygon.
Pick the rectangle with the minimum Area.
Rotate Bounding Rectangle back for Coplanar reverse rotation of Step 1 and step 2
for more detail check link Minimum-Area-Rectangle

Obviously, you'll need the coordinates of the points to get the answer. If the rectangle is aligned to the X and Y aces, then the solution is trivial. If you want the smallest possible rectangle, at any angle, then you'll need to do some sort of optimization process.

Related

How to get all four corners of Minimum Bounding Rectangle from Boost Envelope?

I'm using the boost return envelope function to find a minimum bounding rectangle around a set of 2d points. It returns a box which has two member functions, max_corner() and min_corner().
I would like to know all four corners of the minimum bounding rectangle (MBR) of my set of points so I'm a bit confused. Is two corners really enough to define a rectangle? Surely, given two points in space, there are infinitely many rectangles that could fit?
How can I get all four vertices of the MBR?
return_envelope() creates what's known as an Axis Aligned Bounding Box (AABB).
This means that the edges of the rectangle are assumed to be aligned with the X and Y axises, which greatly restricts the set of rectangles that a pair of points can represent.
Given the bottom-left and top-right corners of the rectangle, aka the corner holding the smallest and largest values for x and y, the other two corners can be determined easily:
(min_corner[0], min_corner[1])
(min_corner[0], max_corner[1])
(max_corner[0], min_corner[1])
(max_corner[0], max_corner[1])

Calculate vertices of a bounding box

I am stumped by this problem which looks very simple. I have a 2D bounding box of which I have two corner points. I wish to determine the remaining two corner points. An important constraint: the bounding box can be oriented in any way and not necessarily aligned to the horizontal and vertical axes (i.e. x and y axes).
I wish to do this as I want to raster scan the bounding box.
I'm sure this is not an answer you want to hear, however, as mentioned here before, two diagonally opposite points are not enough to define a rectangle on a 2D surface. As a picture is worth a thousand words, here's a picture of two different rectangles sharing the same diagonally opposite points.
As mentioned in the comments, you don't have complete information. Let me explain: Draw a dummy rectangle that you want to find the points for -- make sure the rectangle is rotated i.e. not "flat".
Now, pick the top-left and bottom-right points -- treat them as the top-left and bottom-right points of a rectangle that is sitting flat on the x-axis. This shows that you can have at least two rectangles with the same two opposing points. Similarly, you can alter the angle of tilt and get an infinite number of points.
If you want a unique rectangle, you need to define at least the tilt. Hope that helps.

How to detect if an ellipse collides with an another ellipse / rectangle

I want to detect if ellipse collides with another ellipse and rectangle. How I can do it?
I'm writing in C++. I want to use it for a game.
If this is for a game, then exactness should not be an issue.
Treat your ellipse as a polygon, that is, choose N evenly distributed points on your ellipse and treat is as a polygon. Adjuct N to the level of the desired correctness.
Now you need to test if a convex polygon collides with a rectangle. And the latter is a convex polygon as well. Here's a link for convex polygon collision detection
If you need precise answer, than you have to describe your figures as functions and use Newton's method for finding intersection points

Sorting of vertices after intersection of 3d isosurface with plane

Here is another geometric problem:
I have created an 3-dimensional triangulated iso-surface of a point cloud using the marching cubes algorithm. Then I intersect this iso-surface with a plane and get a number of line segments that represent the contour lines of the intersection.
Is there any possibility to sort the vertices of these line segments clockwise so that I can draw them as a closed path and do a flood fill?
Thanks in advance!
It depends on how complex your isosurface is, but the simplest thing I can think of that might work is:
For each point, project to the plane. This will give you a set of points in 2d.
Make sure these are centered, via a translation to the centroid or center of the bounding box.
For each 2d point, run atan2 and get an angle. atan2 just puts things in the correct quadrant.
Order by that angle
If your isosurface/plane is monotonically increasing in angle around the centroid, then this will work fine. If not, then you might need to find the 2 nearest neighbors to each point in the plane, and hope that that makes a simple loop. In face, the simple loop idea might be simpler, because you don't need to project and you don't need to compute angles - just do everything in 3d.

Creating OOBB from points

How can I create minimal OOBB for given points? Creating AABB or sphere is very easy, but I have problems creating minimal OOBB.
[edit]
First answer didn't get me good results. I don't have huge cloud of points. I have little amount of points. I am doing collision geometry generation. For example, cube has 36 points (6 sides, 2 triangles each, 3 points for each triangle). And algorithm from first post gave bad results for cube. Example points for cube: http://nopaste.dk/download/3382 (should return identity axis)
The PCA/covariance/eigenvector method essentially finds the axes of an ellipsoid that approximates the vertices of your object. It should work for random objects, but will give bad results for symmetric objects like the cube. That's because the approximating ellipsoid for a cube is a sphere, and a sphere does not have well defined axes. So you're not getting the standard axes that you expect.
Perhaps if you know in advance that an object is, for example, a cube you can use a specialized method, and use PCA for everything else.
On the other hand, if you want to compute the true OBB there are existing implementations you can use e.g. http://www.geometrictools.com/LibMathematics/Containment/Containment.html
(archived at https://web.archive.org/web/20110817024344/geometrictools.com/LibMathematics/Containment/Containment.html and https://github.com/timprepscius/GeometricTools/blob/master/WildMagic5/LibMathematics/Containment/Wm5ContMinBox3.cpp). I believe this implements the algorithm alluded to in the comments to your question.
Quoting from that page:
The ContMinBox3 files implement an
algorithm for computing the
minimum-volume box containing the
points. This method computes the
convex hull of the points, a convex
polyhedron. The minimum-volume box
either has a face coincident with a
face of the convex polyhedron or has
axis directions given by three
mutually perpendicular edges of the
convex polyhedron. Each face of the
convex polyhedron is processed by
projecting the polyhedron to the plane
of the face, computing the
minimum-area rectangle containing the
projections, and computing the
minimum-length interval containing the
projections onto the perpendicular of
the face. The minimum-area rectangle
and minimum-length interval combine to
form a candidate box. Then all triples
of edges of the convex polyhedron are
processed. If any triple has mutually
perpendicular edges, the smallest box
with axes in the directions of the
edges is computed. Of all these boxes,
the one with the smallest volume is
the minimum-volume box containing the
original point set.
If, as you say, your objects do not have a large number of vertices, the running time should be acceptable.
In a discussion at http://www.gamedev.net/topic/320675-how-to-create-oriented-bounding-box/ the author of the above library casts some more light on the topic:
Gottschalk's approach to OBB construction is to compute a covariance matrix for the point set. The eigenvectors of this matrix are the OBB axes. The average of the points is the OBB center. The OBB is not guaranteed to have the minimum volume of all containing boxes. An OBB tree is built by recursively splitting the triangle mesh whose vertices are the point set. A couple of heuristics are mentioned for the splitting.
The minimum volume box (MVB) containing a point set is the minimum volume box containing the convex hull of the points. The hull is a convex polyhedron. Based on a result of Joe O'Rourke, the MVB is supported by a face of the polyhedron or by three perpendicular edges of the polyhedron. "Supported by a face" means that the MVB has a face coincident with a polyhedron face. "Supported by three perpendicular edges" means that three perpendicular edges of the MVB are coincident with edges of the polyhedron.
As jyk indicates, the implementations of any of these algorithms is not trivial. However, never let that discourage you from trying :) An AABB can be a good fit, but it can also be a very bad fit. Consider a "thin" cylinder with end points at (0,0,0) and (1,1,1) [imagine the cylinder is the line segment connecting the points]. The AABB is 0 <= x <= 1, 0 <= y <= 1, and 0 <= z <= 1, with a volume of 1. The MVB has center (1,1,1)/2, an axis (1,1,1)/sqrt(3), and an extent for this axis of sqrt(3)/2. It also has two additional axes perpendicular to the first axis, but the extents are 0. The volume of this box is 0. If you give the line segment a little thickness, the MVB becomes slightly larger, but still has a volume much smaller than that of the AABB.
Which type of box you choose should depend on your own application's data.
Implementations of all of this are at my www.geometrictools.com website. I use the median-split heuristic for the bounding-volume trees. The MVB construction requires a convex hull finder in 2D, a convex hull finder in 3D, and a method for computing the minimum area box containing a set of planar points--I use the rotating caliper method for this.
First you have to compute the centroid of the points, in pseudcode
mu = sum(0..N, x[i]) / N
then you have to compute the covariance matrix
C = sum(0..N, mult(x[i]-mu, transpose(x[i]-mu)));
Note that the mult performs an (3x1) matrix multiplication by (1x3) matrix multiplication, and the result is a 3x3 matrix.
The eigenvectors of the C matrix define the three axis of the OBB.
There is a new library ApproxMVBB in C++ online which computes an approximation for the minimum volume bounding box. Its released under MPL 2.0 Licences, and written by me.
If you have time look at: http://gabyx.github.io/ApproxMVBB/
The library is C++11 compatible and only needs Eigen http://eigen.tuxfamily.org.
Tests show that an approximation for 140Million points in 3D can be computed in reasonable time (arround 5-7 seconds) depending on your settings for the approximation.