find overlapping rectangles algorithm - c++

let's say I have a huge set of non-overlapping rectangle with integer coordinates, who are fixed once and for all
I have another rectangle A with integer coordinates whose coordinates are moving (but you can assume that its size is constant)
What is the most efficient way to find which rectangles are intersecting (or inside) A?
I cannot simply loop through my set as it is too big. Thanks
edit : the rectangles are all parallel to the axis

I'll bet you could use some kind of derivation of a quadtree to do this. Take a look at this example.

Personally, I would solve this with a KD-Tree or a BIH-Tree. They are both adaptive spatial data structures that have a log(n) search time. I have an implementation of both for my Ray Tracer, and they scream.
-- UPDATE --
Store all of your fixed rectangles in the KD-Tree. When you are testing intersections, iterate through the KD-Tree as follows:
function FindRects(KDNode node, Rect searchRect, List<Rect> intersectionRects)
// searchRect is the rectangle you want to test intersections with
// node is the current node. This is a recursive function, so the first call
// is the root node
// intersectionRects contains the list of rectangles intersected
int axis = node.Axis;
// Only child nodes actually have rects in them
if (node is child)
{
// Test for intersections with each rectangle the node owns
for each (Rect nRect in node.Rects)
{
if (nRect.Intersects(searchRect))
intersectionRects.Add(nRect);
}
}
else
{
// If the searchRect's boundary extends into the left bi-section of the node
// we need to search the left sub-tree for intersections
if (searchRect[axis].Min // Min would be the Rect.Left if axis == 0,
// Rect.Top if axis == 1
< node.Plane) // The absolute coordinate of the split plane
{
FindRects(node.LeftChild, searchRect, intersectionRects);
}
// If the searchRect's boundary extends into the right bi-section of the node
// we need to search the right sub-tree for intersections
if (searchRect[axis].Max // Max would be the Rect.Right if axis == 0
// Rect.Bottom if axis == 1
> node.Plane) // The absolute coordinate of the split plane
{
FindRects(node.RightChild, searchRect, intersectionRects);
}
}
This function should work once converted from pseudo-code, but the algorithm is correct. This is a log(n) search algorithm, and possibly the slowest implementation of it (convert from recursive to stack based).
-- UPDATE -- Added a simple KD-Tree building algorithm
The simplest form of a KD tree that contains area/volume shapes is the following:
Rect bounds = ...; // Calculate the bounding area of all shapes you want to
// store in the tree
int plane = 0; // Start by splitting on the x axis
BuildTree(_root, plane, bounds, insertRects);
function BuildTree(KDNode node, int plane, Rect nodeBds, List<Rect> insertRects)
if (insertRects.size() < THRESHOLD /* Stop splitting when there are less than some
number of rects. Experiment with this, but 3
is usually a decent number */)
{
AddRectsToNode(node, insertRects);
node.IsLeaf = true;
return;
}
float splitPos = nodeBds[plane].Min + (nodeBds[plane].Max - nodeBds[plane].Min) / 2;
// Once you have a split plane calculated, you want to split the insertRects list
// into a list of rectangles that have area left of the split plane, and a list of
// rects that have area to the right of the split plane.
// If a rect overlaps the split plane, add it to both lists
List<Rect> leftRects, rightRects;
FillLists(insertRects, splitPos, plane, leftRects, rightRects);
Rect leftBds, rightBds; // Split the nodeBds rect into 2 rects along the split plane
KDNode leftChild, rightChild; // Initialize these
// Build out the left sub-tree
BuildTree(leftChild, (plane + 1) % NUM_DIMS, // 2 for a 2d tree
leftBds, leftRects);
// Build out the right sub-tree
BuildTree(rightChild, (plane + 1) % NUM_DIMS,
rightBds, rightRects);
node.LeftChild = leftChild;
node.RightChild = rightChild;
There a bunch of obvious optimizations here, but build time is usually not as important as search time. That being said, a well build tree is what makes searching fast. Look up SAH-KD-Tree if you want to learn how to build a fast kd-tree.

You can create two vectors of rectangle indexes (because two diagonal points uniquely define your rectangle), and sort them by one of coordinates. Then you search for overlaps using those two index arrays, which is going to be logarithmic instead of linear complexity.

You can do a random "walking" algorithm ... basically create a list of neighbors for all your fixed position rectangles. Then randomly pick one of the fixed-position rectangles, and check to see where the target rectangle is in comparison to the current fixed-position rectangle. If it's not inside the rectangle you randomly picked as the starting point, then it will be in one of the eight directions which correspond to a given neighbor of your current fixed position rectangle (i.e., for any given rectangle there will be a rectangle in the N, NE, E, SE, S, SW, W, NW directions). Pick the neighboring rectangle in the closest given direction to your target rectangle, and re-test. This is essentially a randomized incremental construction algorithm, and it's performance tends to be very good for geometric problems (typically logarithmic for an individual iteration, and O(n log n) for repeated iterations).

Create a matrix containing "quadrant" elements, where each quadrant represents an N*M space within your system, with N and M being the width and height of the widest and tallest rectangles, respectively. Each rectangle will be placed in a quadrant element based on its upper left corner (thus, every rectangle will be in exactly one quadrant). Given a rectangle A, check for collisions between rectangles in the A's own quadrant and the 8 adjacent quadrants.
This is an algorithm I recall seeing recommended as a simple optimization to brute force hit-tests in collision detection for game design. It works best when you're mostly dealing with small objects, though if you have a couple large objects you can avoid wrecking its efficiency by performing collision detection on them separately and not placing them in a quadrant, thus reducing quadrant size.

As they are not overlapping I would suggest an approach similar (but not equal) to Jason Moore (B).
Sort your array by x of upper left corner.
And sort a copy by y of upper left corner. (of course you would just sort pointers to them to save memory).
Now you once create two sets Sliding_Window_X and Sliding_Window_Y.
You search with binary search once your x-coordinate (upper left) for your A window in the x-sorted array and your y-coordinate. You put your results into the corrospondng Sliding_Window_Set. Now you add all following rectangles in the ordered array that have a lower x(y) (this time lower right) coordinate than your lower right of A.
The result is that you have in your Sliding_Window-sets the windows that overlap with your A in one coordinate. The overlapping of A is the intersection of Sliding_Window_X and _Y.
The Sliding_Window sets can be easily represented by just 2 numbers (begin and end index of the corrosponding sorted array).
As you say you move A, it is now really easy to recalculate the overlap. Depending on the direction you can now add/remove Elements to the Sliding_Window set. I.e. you take just the next element from the sorted array at the front/end of the set and maybe remove on at the end.

Topcoder provides a way to determine if a point lies within a rectangle. It says that say we have a point x1,y1 and a rectangle. We should choose a random point very far away from current locality of reference in the rectangular co-ordinate system say x2,y2.
Now we should make a line segment with the points x1,y1 and x2,y2. If this line segment intersects odd number of sides of the given rectangle (it'll be 1 in our case, this method can be extended to general polygons as well) then the point x1,y1 lies inside the rectangle and if it intersects even number of sides it lies outside the rectangle.
Given two rectangles, we need to repeat this process for every vertex of 1 triangle to possibly lie in the second triangle. This way we'd be able to determine if two rectangles overlap even if they are not aligned to the x or y axis.

Interval Trees: Are BSTs designed with taking 'lo' value as key in an interval. So, for example if we want to insert (23, 46) in the tree, we'd insert it using '23' in the BST.
Also, with interval trees at each node, we keep the maximum endpoint (hi value) of the sub-tree rooted at that node.
This order of insertion allows us to search all 'R' intersections in R(logN) time. [We search for first intersection in logN time and all R in RlogN time] Please refer to interval trees documentation for how insert, search is done and details of complexity.
Now for this problem, we use an algorithm known as sweep-line algorithm. Imagine we have a vertical line (parallel to y-axis) which is sweeping the 2D space and in this process intersects with the rectangles.
1) Arrange rectangles in increasing order of x-cordinates (left-edge wise) either via priority queue or via sorting . Complexity NlogN if N rectangles.
2) As this line sweeps from left to right, following are the intersection cases:
If line intersects the left side of a rectangle never seen, add the y co-ords of the rectangle's side to the interval tree. [say (x1,y1) and (x1,y2) are left edge co-ordinates of the rectangle add interval (y1, y2) to the interval tree] ---> (NlogN)
Do a range search on the interval tree. [say (x1,y1) and (x1,y2) are left edge co-ordinates of the rectangle, take the interval (y1,y2) and do an interval intersection query on the tree to find all intersections] ---> RlogN (in practice)
If line intersects the right side of a rectangle, remove it's y-coords from the interval tree as the rectangle is now processed completely. ----> NlogN
Total complexity : NlogN + RlogN

Let your set of rectangle be (Xi1,Yi1,Xi2,Yi2) where i varies from 0 to N.
Rectangle A and B can NOT be intersecting if Ax1 > Bx2 || Ay1 < By2 || Bx1 > Ax2 || By1 < Ay2.
Create tree which is optimized for range/interval (For exa: segment tree or interval tree)
See http://w3.jouy.inra.fr/unites/miaj/public/vigneron/cs4235/l5cs4235.pdf
Use this tree to find set of triangle while your triangle is changing coordinates.

By calculating the area of each rectangle and and checking the length L, height H and area of rectangles whether exceeds or not the length and height and area of a rectangle A

Method (A)
You could use an interval tree or segment tree. If the trees were created so that they would be balanced this would give you a run time of O(log n). I assume this type of preprocessing is practical because it would only happen once (it seems like you are more concerned with the runtime once the rectangle starts moving than you are with the amount of initial preprocessing for the first time). The amount of space would be O(n) or O(n log n) depending on your choice above.
Method (B)
Given that your large set of rectangles are of fixed size and never change their coordinates and that they are non-overlapping, you could try a somewhat different style of algorithm/heuristic than proposed by others here (assuming you can live with a one-time, upfront preprocessing fee).
Preprocessing Algorithm [O(n log n) or O(n^2) runtime {only run once though}, O(n) space]
Sort the rectangles by their horizontal coordinates using your favorite sorting algorithm (I am assuming O(n log n) run time).
Sort the rectangles by their vertical coordinates using your favorite sorting algorithm (I am assuming O(n log n) run time)
Compute a probability distribution function and a cumulative distribution function of the horizontal coordinates. (Runtime of O(1) to O(n^2) depending on method used and what kind of distribution your data has)
a) If your rectangles' horizontal coordinates follow some naturally occurring process then you can probably estimate their distribution function by using a known distribution (ex: normal, exponential, uniform, etc.).
b) If your rectangles' horizontal coordinates do not follow a known distribution, then you can calculate a custom/estimated distribution by creating a histogram.
Compute a probability distribution function and a cumulative distribution function of the vertical coordinates.
a) If your rectangles' vertical coordinates follow some naturally occurring process then you can probably estimate their distribution function by using a known distribution (ex: normal, exponential, uniform, etc.).
b) If your rectangles' vertical coordinates do not follow a known distribution, then you can calculate a custom/estimated distribution by creating a histogram.
Real-time Intersection Finding Algorithm [Anywhere from O(1) to O(log n) to O(n) {note: if O(n), then the constant in front of n would be very small} run time depending on how well the distribution functions fit the dataset]
Taking the horizontal coordinate of your moving rectangle and plug it into the cumulative density function for the horizontal coordinates of the many rectangles. This will output a probability (value between 0 and 1). Multiply this value times n (where n is the number of many rectangles you have). This value will be the array index to check in the sorted rectangle list. If the rectangle of this array index happens to be intersecting then you are done and can proceed to the next step. Otherwise, you have to scan the surrounding neighbors to determine if the neighbors intersect with the moving rectangle. You can attack this portion of the problem multiple ways:
a) do a linear scan until finding the intersecting rectangle or finding a rectangle on the other side of the moving rectangle
b) calculate a confidence interval using the probability density functions you calculated to give you a best guess at potential boundaries (i.e. an interval where an intersection must lie). Then do a binary search on this small interval. If the binary search fails then revert back to a linear search in part (a).
Do the same thing as step 1, but do it for the vertical portions rather than the horizontal parts.
If step 1 yielded an intersection and step 2 yielded an intersection and the intersecting rectangle in step 1 was the same rectangle as in step 2, then the rectangle must intersect with the moving rectangle. Otherwise there is no intersection.

Use an R+ tree, which is most likely precisely the specific tree structure you are looking for. R+ trees explicitly do not allow overlapping in the internal (non-leaf) structure in exchange for speed. As long as no object exists in multiple leaves at once, there is no overlap. In your implementation, rather than support overlap, whenever an object needs to be added to multiple leaves, just return true instead.
Here is a detailed description of the data structure, including how to manage rectangles:
The R+-tree: A dynamic index for multi-dimensional objects

Related

Is there a way to convert an undirect graph to an (x,y) coordinate system?

For a project I am working on I have some txt files that have from id's, to id's, and weight. The id's are used to identify each vertex and the weight represents the distance between the vertices. The graph is undirected and completely connected and I am using c++ and openFrameworks. How can I translate this data into (x,y) coordinate points for a graph this 1920x1080, while maintaining the weight specified in the text files?
You can only do this if the dimension of the graph is 2 or less.
You therefore need to determine the dimension of the graph--this is a measure of its connectivity.
If the dimension is 2 or less, then you will always be able to plot the graph on a Euclidian plane while preserving relative edge lengths, as long as you allow the edges to intersect. If you prohibit intersecting edges, then you can only plot the graph on a Euclidian plane if the ratio of cycle size to density of cycles in the graph is sufficiently low throughout the graph (quite hard to compute). I can tell you how to plot the trickiest bit--cycles--and give you a general approach, but you actually have some freedom in how you plot this, so please, drop a comment or edit the question if you have a more specific request.
If you don't know whether you have cycles, then find out! Here are some efficient algorithms.
Plotting cycles. Give the first node in the cycle arbitrary coordinates.
Give the second node in the cycle coordinates bounded by the distance from the first node.
For example, if you plot the first node at (0,0) and the edge between the first and second nodes has length 1, then plot the second node at (1, 0).
Now it gets tricky because you need to calculate angles.
Count up the number n of nodes in the cycle.
In order for the cycle to form a polygon, the sum of the angles formed by the cycle must be (n - 2) * 180 degrees, where n is the number of sides (i.e., the number of nodes).
Now you won't have a regular polygon unless all the edge lengths are the same, so you can't just use (n - 2) / n * 180 degrees as your angle. If you make the angles too sharp, then the edges will be forced to intersect; and if you make them too large, then you will not be able to close the polygon. Compute the internal angles as explained on StackExchange Math.
Repeat this process to plot every cycle in the graph, in arbitrary positions if needed. You can always translate the cycles later if needed.
Plotting everything else. My naive, undoubtedly inefficient approach is to traverse each node in each cycle and plot the adjacent nodes (the 'branches') layer by layer. Then rotate and translate entire cycles (including connected branches) to ensure every edge can reach both of its nodes. Finally, if possible, rotate branches (relative to their connected cycles) as needed to resolve intersecting edges.
Again, please modify the question or drop a comment if you are looking for something more specific. A full algorithm (or full code, in any common language) would make a very long answer.

Access a circle of rays efficiently (find closest obstacle contours)

Have a binary grid (like black and white pixels with black = empty and white = obstacle).
Starting from a given point on black, I want to emit "rays" in all directions. Those rays should either abort when reaching a given length (for example 100) or when hitting a white pixel (in which case the position of this pixel, aka obstacle contour shall be marked).
Those marked pixels result in a view of all obstacle contours that are "visible" from the given point (not obstructed by other obstacles).
What I have thought of so far, is to simply call a sufficient number of bresenham lines. In the case of a radius of 100, that means 100*2*pi = 628 lines to cover all pixels on the outer most circle.
However that results in many many multiple checks of same pixels closer to the center. Now I could split up the check in multiple rings, each of a different density of bresenham lines, but that appears rather inefficient too.
Does someone happen to have a more efficient algorithm idea for this?
Huge thanks in advance!
Unfortunately the hints towards graphics processing techniques while fascinating, are not well applicable in my case because I have no access to shaders or a camera, etc.
For now I have found a sufficiently efficient solution myself. The basic idea is to launch rays from the contours, not from the origin. Furthermore to use a helper grid named "reachable" where all pixels are marked that are successfully visible from the origin. This way only few pixels are read twice, most are read just once and some are written at most once. The code is rather messy yet, thus only pseudocode here:
Have desired origin O.x/O.y
Have obstacle bool grid Obstacle
Define bool grid Reachable[w][h]
Clear Reachable with false
Reachable[O.x][O.y] = true
For each Point C on all obstacle Contours // if not available, compute contours by finding all pixels adjacent to non-obstacle
For all Pixels A on Bresenham line from C to O
If Obstacle[A.x][A.y]
Continue with outer loop on contours // abort this line due to obstacle hit
If Reachable[A.x][A.y]
For all Pixels B on Bresenham line from C to A
Reachable[B.x][B.y] = true // mark all pixels on this line as Reachable
Mark C as a desired result pixel
Continue with outer loop on contours
Let the "square distance" between two points (x1,y1) and (x2,y2) be max(|x1-x2|,|y1-y2|), so that the points at increasing "square distance" around a center for increasingly large squares.
Now, for each square distance d from your center point, in increasing order, keep track of the angles the center point can see through all the obstacles with distance <= d.
You can use a list of angle intervals starting at [(0,360)] for d=0.
For each new distance, you can inspect the list, examine the new pixels within the given angles, and remove angle from the intervals when obstacles are hit. Each obstacle that causes you to modify an interval is visible from the center point, so you can mark it as such.
This method examines pixels only once, and only examines pixels you can see. The way I wrote it above requires trigonometry, however, which is slow. For a practical implementation, instead of actually using angles, use slopes, which require only simple math, and process each octant separately.

The search for a set of points with a minimum sum of lengths to rectangles. What is the algorithm?

Good day.
I have the task of finding the set of points in 2D space for which the sum of the distances to the rectangles is minimal. For example, for two rectangles, the result will be the next area (picture). Any point in this area has the minimum sum of lengths to A and B rectangles.
Which algorithm is suitable for finding a region, all points of which have the minimum sum of lengths? The number of rectangles can be different, they are randomly located. They can even overlap each other. The sides of the rectangles are parallel to the coordinate axes and cannot be rotated. The region must be either a rectangle or a line or a point.
Hint:
The distance map of a rectangle (function that maps any point (x,y) to the closest distance to the rectangle) is made of four slanted planes (slope 45°), four quarter of cones and the rectangle itself, which is at ground level, forming a continuous surface.
To obtain the global distance map, it "suffices" to sum the distance maps of the individual rectangles. A pretty complex surface will result. Depending on the geometries, the minimum might be achieved on a single vertex, a whole edge or a whole face.
The construction of the global map seems more difficult than that of a line arrangement, due to the conic patches. A very difficult problem in the general case, though the axis-aligned constraint might ease it.
Add on Yves's answer.
As Yves described, each rectangle 'divide' plane into 9 parts and adds different distance method in to the sum. Middle part (rectangle) add distance 0, side parts add coordinate distance to that side, corner parts add point distance to that corner. With that approach plan has to be divided into 9^n parts, and distance sum is calculated by adding appropriate rectangle distance functions. That is feasible if number of rectangles is not too large.
Probably it is not needed to calculate all parts since it is easy to calculate some bound on part min value and check is it needed to calculate part at all.
I am not sure, but it seems to me that global distance map is convex function. If that is the case than it can be solved iteratively by similar idea as in linear programming.

Fit rectangle around points

I'm trying to fit a rectangle around a set of 8 2D-Points, while trying to minimize the covered area.
Example:
The rectangle may be scaled and rotated. However it needs to stay a rectangle.
My first approach was to brute force each possible rotation, fit the rectangle as close as possible, and calculate the covered area. The best fit would be then the rotation with the lowest area.
However this does not really sound like the best solution.
Is there any better way for doing this?
I don't know what you mean by "try every possible rotation", as there are infinitely many of them, but this basic idea actually yields a very efficient solution:
The first step is to compute the convex hull. How much this actually saves depends on the distribution of your data, but for points picked uniformly from a unit disk, the number of points on the hull is expected to be O(n^1/3). There are a number of ways to do that:
If the points are already sorted by one of their coordinates, the Graham scan algorithm does that in O(n). For every point in the given order, connect it to the previous two in the hull and then remove every concave point (the only candidate are those neighboring the new point) on the new hull.
If the points are not sorted, the gift-wrapping algorithm is a simple algorithm that runs at O(n*h). For each point on the hull starting from the leftmost point of the input, check every point to see if it's the next point on the hull. h is the number of points on the hull.
Chen's algorithm promises O(n log h) performance, but I haven't quite explored how it works.
another simle idea would be to sort the points by their azimuth and then remove the concave ones. However, this only seems like O(n+sort) at first, but I'm afraid it actually isn't.
At this point, checking every angle collected thus far should suffice (as conjenctured by both me and Oliver Charlesworth, and for which Evgeny Kluev offered a gist of a proof). Finally, let me refer to the relevant reference in Lior Kogan's answer.
For each direction, the bounding box is defined by the same four (not necessarily distinct) points for every angle in that interval. For the candidate directions, you will have at least one arbitrary choice to make. Finding these points might seem like an O(h^2) task until you realise that the extremes for the axis-aligned bounding box are the same extremes that you start the merge from, and that consecutive intervals have their extreme points either identical or consecutive. Let us call the extreme points A,B,C,D in the clockwise order, and let the corresponding lines delimiting the bounding box be a,b,c,d.
So, let's do the math. The bounding box area is given by |a,c| * |b,d|. But |a,c| is just the vector (AC) projected onto the rectangle's direction. Let u be a vector parallel to a and c and let v be the perpendicular vector. Let them vary smoothly across the range. In the vector parlance, the area becomes ((AC).v) / |v| * ((BD).u) / |u| = {((AC).v) ((BD).u)} / {|u| |v|}. Let us also choose that u = (1,y). Then v = (y, -1). If u is vertical, this poses a slight problem involving limits and infinities, so let's just choose u to be horizontal in that case instead. For numerical stability, let's just rotate 90° every u that is outside (1,-1)..(1,1). Translating the area to the cartesian form, if desired, is left as an exercise for the reader.
It has been shown that the minimum area rectangle of a set of points is collinear with one of the edges of the collection's convex hull polygon ["Determining the Minimum-Area Encasing Rectangle for an Arbitrary Closed Curve" [Freeman, Shapira 1975]
An O(nlogn) solution for this problem was published in "On the computation of minimum encasing rectangles and set diameters" [Allison, Noga, 1981]
A simple and elegant O(n) solution was published in "A Linear time algorithm for the minimum area rectangle enclosing a convex polygon" [Arnon, Gieselmann 1983] when the input is the convex hull (The complexity of constructing a convex hull is equal to the complexity of sorting the input points). The solution is based on the Rotating calipers method described in Shamos, 1978. An online demonstration is available here.
They first thing that came to mind when I saw this problem was to use principal component analysis. I conjecture that the smallest rectangle is the one that satisfies two conditions: that the edges are parallel with the principal axes and that at least four points lie on the edges (bounded points). There should be an extension to n dimensions.

"moving furniture": collision resolution in 2d space (non-rotating shrinkable 2d rectangles)

In 2d space we have a collection of rectangles.
Here's a picture:
Vertical line on the right is non-moveable "wall".
Arrow on the left shows direction of movement.
I need to move leftmost rectangle to the right.
Rectangles cannot rotate.
Rectangles are not allowed to overlap horizontally.
Rectangle can shrink (horizontally) down to a certain minimum width (which is set individually to each rectangle)
Rectangles can only move horizontally (left/right) and shrink horizontally.
Leftmost rectangle (pointed at by arrow) cannot shrink.
Widths and coordinates are stored as integers.
I need to move leftmost rectangle to the right by X units, pushing everything in its way to the right.
There are two problems:
I need to determine how far I can move leftmost rectangle to the right (it might not be possible to move for X units).
Move rect by X units (or if it is not possible to move by X units, move by maximum possible amount, smaller than X) and get new coordinates and sizes for every rectangle in the system.
Additional complications:
You cannot use Y coordinate and height of rectangle for anything, instead
every rectangle has a list (implemented as pointers) of rectangles it will hit if you keep moving it to the right, you can only retrieve x coordinate, width, and minimum width. This data model cannot be changed. (technically, reppresenting this as a set of rectangles in 2d is simplification)
Important: Children from different levels and branches can have the same rectangle in the "potential collision" list. Here's initial picture with pointers displayed as red lines:
How can I do it?
I know a dumb way (that'll work) to solve this problem: iteratively. I.e.
Memorize current state of the system. If state of the system is already memorized, forget previously memorized state.
Push leftmost rect by 1 unit.
Recursively resolve collisions (if any).
If collision could not be resolved, return memorized state of the system.
If collisions could be resolved, and we already moved by X units, return current state of the system.
Otherwise, go to 1.
This WILL solve the problem, but such iterative solution can be slow if X is large. Is there any better way to solve it?
One possible solution that comes to mind:
You said that each rectangle holds pointers to all the objects it will hit when moving right. I would suggest, take the list of pointers from the big rectangle (the one pointed by the arrow), take all it's nodes (the rectangles it would collide), find the min width, then do the same of all the child nodes, add the widths for each branch recursively. Treat the problem like a tree depth problem. Every node has a min width value so the answer to your question would be the distance between the wall and the x value of the right edge of the big rectangle minus the GREATEST sum of the least width of the rectangles. Create a vector where the depth (sum of min widths) of each branch of the tree is stored and find the max value. Distance minus max is your answer.
imagine the same picture with 4 boxes. one to the left, one to the right and then the wall. lets name them box 1, box 2 (mid top), box 3 (mid bottom) and the last one box 4 (right). each box has a width of 4. all can shrink except the left one. box 2 can shrink by 2, box 3 can shrink by 1, box 4 can shrink by 2. Calculating the 2 branches gives
* Branch 1 : 2 + 2 = 4
* Branch 2 : 3 + 2 = 5
* Only concerned with branch 2 because branch 1 is LESS than branch 2 hence will fit in the space parallel to branch 2and is available to shrink that much.