Approximate area of overlap of rotated rectangles - algorithm

I need to estimate the overlap ratio of two rectangles of arbitrary size and orientation.
I know how to perform the exact computation, using the Sutherland-Hodgman algorithm, which can be optimized for this case.
Anyway as I need to use that function intensively and perfect accuracy isn't required (say 10% error can be tolerated), I was wondering if it cannot be evaluated in a faster way, preferably branchless.
If that helps, one can assume the same aspect ratio for both rectangles, and ratio of the areas not exceeding 4.
Update:
For unrotated rectangles, the formula is
(min(W0,DX+W1) - max(-W0,DX-W1)).(min(H0,DY+H1) - max(H0,DY-H1))
or zero if any of the two factors is negative, where DX, DY are the differences between center coordinates, W and H denote the respective half sizes.
It is probably worthwhile to look at the curve of the common area for given placement of the centers and given sizes, when you vary the relative rotation angle.

Sutherland-Hodgman algorithm is intended for intersection of convex clip polygon with arbitrary one. I would expect that algorithm especially designed for convex-convex case is faster.
I had good practical experience with O'Rourke algorithm (O(m+n)) for alike problem
(area of intersections between two sets of thousands of rotated rectangles).
Code link is here - convconv. AFAIR, some simplifications were possible for rectangles.
Another algorithm
I doubt that any approximation approach could find a result significantly faster and with controlled accuracy.

Related

Algorithmic complexity of finding subset of 3D points in cube

Given an array of 3D integers, what is the algorithmic complexity of determining which of those integers exist within a cube? I'm assuming the points can be represented in a number of concurrent data structures, each sorted in one or more dimensions.
My intuition tells me given a sorted array of points in 1D one can determine the subset of points between some lower and upper bound in something like O(log(n), but I would be very grateful for any insights others can offer on this notion (and any help others can offer generalizing to the multidimensional case!).
If you're unfamiliar with the math involved, I recommend doing this problem in two dimensions first, with a rectangle. That way, you can get familiar with the math, which is really just a bit of basic trigonometry. After that, stepping up to three dimensions isn't very difficult.
The problem is much simpler if the cube (or rectangle) is axis aligned, so you probably should do that first. For an example of determining the rotation you need, see How to calculate rotation angle from rectangle points?.
Once you've determined the rotation angle, you can translate the rectangle to the origin and rotate it by doing the first two steps in the accepted answer here: Drawing a Rotated Rectangle.
You now have an axis-aligned rectangle that's centered at the origin.
Finally, for each of your points:
Apply the same translation and rotation that you applied to the rectangle.
Test to see if the x and y coordinates in the resulting point are within the rectangle. This is a matter of, at most, four bounds checks.
If the point is in the rectangle, save it.
Once you've done this in two dimensions, you should be able to apply those concepts to three dimensions.
The algorithm is O(n), where n is the number of points.

Find overlapping circles

I have a rectangular area where there are circles with equal radius. I want to find which circles overlap with other circles (the output is a list of 2-element sets of overlapping circles).
I know how to check if two of the circles overlap (the distance between their centers is less than the diameter). I can perform this check for every pair of circles, but I was wondering if there is a better algorithm (faster than O(n^2)).
EDIT
The number of circles is usually about 100 and overlappings won't happen very often.
Here is some context:
The rectangle is a battlefield in a game. The movement of the units is done on small steps and I'm trying to detect collisions between units.
Given the new explanation of the problem statement, I would recommend a different approach.
Overlay a square grid over the battlefield, with a grid step equal to one circle diameter. Every circle can overlap at most four cells. In each cell, keep a list of the overlapping circles (and update it on every move).
Detecting potential collisions will now take about four cell/circle tests per circle, i.e. close to linear time.
For a simple solution, insert the centers in a 2d-tree and perform circular range queries around every center with a query radius 2R. In good conditions, this can be O(N Log(N)).
Alternatively, just sort the centers on X and try all circles in turn: by dichotomic search, locate the abscissa Xc and scan to Xc-2R and to Xc+2R, then check the 2D distance.
The cost of the dichotomic searches will be O(N Log(N)). If the circles are uniformly spread out in a square of side S, a stripe of width 4R contains 4RN/S circles, hence a total comparison cost of 4RN²/S. This is a good performance if S is large (think that for N tightly packed circles in a square, S~2R√N, hence 2N√N comparisons).
Direct answer: You cannot get better than O(n^2) in general since the circles could potentially all overlap, so you have to generate n^2 answers.
If you get more specific, you might get better answers. For example, if what you are really trying to do is find bounding spheres in a 2D simulation, you can profit from the fact that entities only move so far between frames, if the circles are sparse it's different from when they are tightly packed, etc. So let us know more about what it's all about.
EDIT: You edited your question - you indeed are looking for collision detection in a 2D simulation. If you check out https://en.wikipedia.org/wiki/Collision_detection , they point to several algorithms for exactly your case.
I like the one detailed right on that page where you keep one list of bounding intervals per axis (2 in "2D") and only need to "work hard" when those bounding intervals (which are themself by definition one-dimensional) change (i.e., there "overlap state"). This removes the O(n²) for well-behaved cases. They don't give an estimate for the complexity of that, but as it basically comes down to sorting, it looks more or less O(n logn) to me, and less when there are only minimal changes between frames.

Best-fit a rectangle over a 2D blob

I have a binary blob (see image), and I want to fit a rectangle of known width and height over it.
How can I find the optimal fitting rectangle, i.e. the one where the maximum of foreground pixels are inside and the maximum amount of background pixels are outside?
(This is my preliminary definition of best-fit, I am open to other suggestions)
I am looking for rectangles of a known size, but if there is a solution for arbitrary sizes, that would be great too.
Example blobs:
I want to find these rectangles:
My ideas so far included
start with the minimum enclosing rectangle; but that is not a good match for these blobs
maximum enclosed rectangle; same problem, plus I do not have an algorithm for that
find rectangle sides with hough transform; the data is too noisy for that.
I realize that there could be multiple rectangles for the same blob that fit my criteria, ideally I would want some algorithm that can find all candidates (thought since that is probably harder, I'd be happy with a way to find only one candidate):
I am using mostly opencv and cvBlobLib to process my data, but I am open for any general solution.
I have seen a thesis on a similar subject (circle covering on a RGB plane), based on an evolutionary approach.
The objective function was clearly defined (How many squares? How big?
Can they overlap? You'd probably want to penalize small or
overlapping squares).
You may start by running the k-means
algorithm to preprocess the data, i.e. find potential center points of the squares.
As I recall, SGA, CGA and eCGA were compared (CGA started with initial, k-means-based covering), with SGA outperforming the others. They were ran on a per-image basis. There were around 30 individuals and 20 generations with runtimes around a couple of minutes.
As for the SGA, the crossover operator would take two parents at a time and pair up the closes/most similar circles from both of the parents. Then, for each pair, it would draw a children circle somewhere in between with a radius also in between that of the two circles'. (Though I would suggest not to take values exactly between those of the parents', but allow +/- 15% outside the range. It would keep the population from the premature convergence).
With rectangles, you'd have to slightly modify the approach; each rectangle could be a tuple (x, y, width, height, rotation), with x and y being the coordinates of the center.

Find largest rectangle inside an SVG path

Given an irregular shape made by an SVG path, how do you calculate the largest rectangle (with only horizontal and vertical borders) that can fit inside it?
I don't think you can find the largest rectangle in the general case. You should better consider the problem to find the largest rectangle that fits inside a shape that is drawn on a grid, it will give you a good approximation of what you are looking for and by decreasing the step of the grid, you can increase the precision of your approximation.
On a grid the problem can be solved in O(n) where n is the number of cells in the grid.
An SVG path consists of segments of lines, cubic Bezier paths, quadratic Bezier paths, and elliptic arcs. Therefore it is piecewise differentiable. It consists of a finite number of segments, not an infinite recurrence. Don't laugh, things like that can be represented easily in a "lazy" programming language such as Haskell, but they're not allowed in SVG. In particular, although an SVG path can look like a fractal to our eyes, it can't mathematically be a fractal. Furthermore the constants can only be integers or IDL floats, which are IEEE single-precision floating-point numbers. So the resolution of a grid that would have all of those numbers at grid points might be considered large, but it is surely finite.
Using those facts I claim that in general, if an SVG path encloses an area, then there exists a largest area for rectangles enclosed in the path; and that there is a tractable algorithm to find (at least) one rectangle whose area is the largest area.
Any algorithm needs to account for difficult cases such as (approximations to) space-filling curves, which could have a large number of small but still "largest" rectangles. I don't know an algorithm, so we can consider here how to develop one. Could you solve the problem for paths made only of line segments? Would a mesh generation algorithm help? Does it help to consider that rectangles that have the same center and area have their corners on a pair of hyperbolas? Does it help to know about convex hull algorithms? Would you need the differential calculus method called max-min, or perhaps not? Then, how would you extend your algorithm to allow the other types of path segments? Would it be necessary, or helpful, or unnecessary to approximate those path segments as polygonal paths?

Filling a Polygon with Least Amount of Rectangles

I'm trying to render polygons, but they can only be rendered using axis-aligned rectangles. So, I' looking for an algorithm that can basically fill in a polygon using the least possible amount of rectangles. If it helps reduce the amount, the rectangles are allowed to overlap each other.
I've already implemented this fill algorithm, which mostly suffices. The downfall is that it restricts rectangles to each pixel row. I ultimately want to reduce the amount of rectangles as much as possible.
Pixel representation of polygon is same as rectilinear polygon and you can partition it quite fast. See answer to this question.
Removing that restriction (that each rectangle have a height of one pixel) helps in some special cases when the polygon is made of big rectangles, but not at all in the general case.
How about this: use that algorithm, but extend each rectangle upward and downward as much as you can, and when all of the rectangles are in place, eliminate redundant ones.
There is still a little bit of room for improvement, in that the order in which you eliminate redundant rectangles might matter in some very rare cases, but honestly I don't think it's worth worrying about for a practical solution.

Resources