Calculate vertices of a bounding box - c++

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.

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

Splitting a rotating rect into smaller rects, how to rotate them to maintain the original big rect?

I have a rectangle r with the size of 1536x720 which I rotate around its own center point p(768, 360), which is easy enough with the built in sf::Sprite::rotate function
Now for unrelated reasons I have to split up the rectangle into 6 smaller rectangles (each sized 512x360).
These smaller rectangles are just the bigger rectangle r sliced up; they are positioned in such a way that "stitched together" they form the original rectangle (so it looks like it's still the original big rectangle)
Illustration: image
Since rectangle r was constantly rotating around its own center, splitting it into smaller rectangles has introduced the problem:
How do I rotate the stitched together rectangle (i.e. the smaller rectangles) around the original center p so that the original bigger rectangle is maintained? Is this even possible?
My English isn't that great so it's a bit tricky to explain. If you need more explaining I can draw the scenario in paint or something
You can use sf::Transformable::setOrigin to set transform origin of each small rectangle to the center point of the large one.
Notice that it will become the origin of all transformations, e.g. small rectangles will scale with respect to that new center too, but probably that's the desired behavior.

Point in vertex defined box algorithm?

How would I test if a point is within a 3D box that is defined by its 8 points only or by its 6 quads? (Dont have access to normal vectors)
The box is made up of triangles, but the two polygons on each side are aligned so could be considered a quad.
You can test that by forming 6 square pyramids with your point as head and 4 vertices of a each quad as base, then summing up volumes of square pyramids. If sum of volumes is equal to volume of your box, the point is in the box. If sum of volumes is greater than your box's volume, it's outside of the box (sum of volumes would never be less than box volume).
For calculating volume of each square pyramid, you can break it into two tetrahedrons where their volume could be easily calculated by a mix vector product. You can calculate volume of box with mix vector product as well.
Assuming the points have a known order, you could work out the normal vectors. There's no need to normalise them for this sort of test so the cost isn't prohibitive. If you already know it's a cuboid then you need work out only two normals as you can get the third with the cross product, then use the other points to get distances. Obviously you're cross-producting to get normals anyway, so that's more a question about what information you want to expose to whom.
If the points don't have a known order then you can probably apply a miniature version of QuickHull — starting from the initial triangle you should find either that you already have one of the real edge faces (in which case you can use that normal and find the relevant points at the other extreme of that normal plus the requirement of mutual orthogonality to get to all three normals) or that one step gives you at least two real edges, which you'll spot when their local sets of points in front go empty.
A crazy idea, perhaps:-
set up a 3d orthographic projection on a 1x1 pixel viewport
set the camera and near clip plane such the the point of interest is on the near clip plane
render the box without any culling
if only one pixel is rendered then point is inside the box, 0 or 2 or more pixels rendered then the point is outside the box

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.

Calculate minimum area rectangle for a polygon

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.