Arrange rectangles to anchor points without overlap - performance

I have a set of rectangles of different size. Each rectangle has an anchor point on the 2 dimensional plane where the center of the rectangle should be placed. The rectangles should not overlap and the center of a rectangle should be as close as possible to its anchor point. So if the center of the rectangle_i is vector c_i and its anchor point is vector a_i then the target function would be min(sum_i((c_i - a_i)^2)). I am looking for an algorithm that approaches the optimal solution as much as possible in O(n).
The rectangles can not be rotated.
The inputs of the problem are:
the size of n rectangle
for each rectangle the coordinates of the associated anchor point.
The output should be the position of the rectangles i.e. coordinates of the center of each rectangle.
In the example below x signs the center of the rectangle and o the anchor points:
+-----------+
| |
+-----------+| x |
| || o |
| x |+-----------+
| o | +-------------+
+-----------+ | o |
+---------+| x |
| o || |
| x |+-------------+
| |
+---------+

Related

Calculating the angles of the rotation giving the vertices

I have 4 points (black A, black B, black C and black D) which are the vertices of the rotated red square.
Is it possible to determine what were the three angles (x angle, y angle and z angle) used to rotate the red square into the black square?
In this case, the angles were:
X = 1rad
Y = 0.2rad
Z = 0.3rad
EDIT: I just have the four black points, not the red ones.
The only thing I know about the red square is that it is a square
There is method to find affine matrix needed to transform point set into another one.
Having natrix, you can find angles.
Description for 2D case is here, 3D case is similar.
M * A = B
where
| xa xb xc xd|
A =| ya yb yc yd|
| za zb zc zd|
| 1 1 1 1 |
| xa' xb' xc' xd'|
B =| ya' yb' yc' yd'|
| za' zb' zc' zd'|
| 1 1 1 1 |
To find unknown M, we can multiply both sides of the expression by inverse of A matrix
M * A * Inv(A) = B * Inv(A)
M = B * Inv(A)
But solution is unique for non-complanar point quadruplet - in your case points lie in the same plane, so if solution exists, it is really a family of solutions and you have to choose arbitrary one. (Perhaps angles will be defined unambiguously)

Finding all the rectangles within a given rectangle that do not intersect with an arbitrary shape

I need to find an algorithm to find the least number of overlapping rectangles within a given rectangle R that do not intersect with the union of a set of other rectangles contained within R. These inner rectangles can overlap. Here's a terrible ASCII drawing of an example R:
A-----------------B-------------------------+
| |
| |
| |
| |
| +--------+ |
| |........| |
| |........| |
C +---D........| |
| |.........+--+ |
| |.........| |
| ++........+------+ |
| |...............| |
G +---H...........| |
| |...........| |
| |...........| |
| |...........| |
| +-----------+ |
| |
| |
| |
E-------------I----F------------------------+
The rectangles here would include (A, D), (A, I), (G, F). This seems like a problem for which the solution is well-understood, but for which I simply lack the vocabulary. Any answers, pointers, RTFMs cheerfully and gratefully accepted. Thanks!
EDIT: As per #Paul's observation below, what I'm trying to do is find a set of rectangles that cover the space in R without covering any of polygon comprised of the union of the inner set. If that makes sense.
I believe this is one possible way to solve.
I will refer to the overlapping rectangles as "white", and the ones in the solution as "black"
First of all, let's assume we have a data structure suitable for search on intersection. One possible data structure is an Interval Tree, using points on one of the coordinates as intervals (for example, if a rectangle is defined by two points (x0,y0) and (x1, y1), use (x0, y1) as interval. The link also explain how to extend to higher dimensions (in your case you need 2).
I won't go in the detail of an implementation of such data structure, but let's assume we have one called Rectangles, with the following API defined:
void add(Rectangle r)
void remove(Rectangle r)
Rectangle[] getIntersecting(Rectangle r)
Rectangle[] getAdjacent(Rectangle r)
Ok, now create two instances of Rectangles called black and white. Initialize white with all the white rectangles. Initializie black with the R rectangle (the whole domain).
For each rectangle rw in white get the array arr of intersecting rectangles from black.
For each rectangle rb in black, determine the result of rw-rb. This is a set set of 0, 1, 2, 3 or 4 rectangles, depending on how the two rectangles intersect.
remove rw from white, and add the content of set to it. This may require merging rectangles from set with rectangle already in white, if such rectangles together form a larger rectangle (they're adjacent sharing one side)
remove rb from black
repeat from 1 until there are no more rectangles in black
Using some basic math, we could say the solution to your problem would be the decomposition of the rectilinear polygon R \ union(rs), where union(rs) represents the polygon inside R. Calculating R \ union(rs) can be done using the Greiner-Hormann-algorithm. Note that this step will result in a polygon with holes and - only if the inner polygon contains holes - multiple other polygons. The decomposition is described here (this is only an approximation, but i wasn't able to find a precise algorithm so far).

Find a line connecting two faces of a cubic volume

Imagine a volumetric cube of N³ resolution that is filled with occluding voxels. The cube could be completely filled, or contain curvy "tunnels", or walls - or just a few stray voxels; We now pick any two of the six faces of the bounding cube and attempt to find a line that connects those two faces without hitting any voxel inside it. If such a line exists, the faces can see each other, otherwise, they're completely occluded.
My question is: does an O(n) (or better) algorithm exist to quickly discern if such a line can be drawn? The exact parameters of the line do not matter.
I'm somewhat unclear on the exact parameters of being a straight line in this (continuous? discrete?) space, but I wonder if you're looking for a dynamic programming solution?
Perhaps lets restrict to 2-D left to right case to build the algorithm and then generalize:
Loop over first column of the array,
for each opaque square, mark that it is impossible to build a ray which reaches this square
for each non opaque square, mark that it is possible to reach this square -AND- track ranges of slopes can reach this square. You may restrict the set of slopes in this initialization by the set of slopes that could potentially reach the opposite end of your voxel volume.
Then loop over the next column
Each square is potentially able to be reached by any square in the previous column, but only if the range of slopes that can reach the square in the previous column intersects the range of slopes necessary to reach the current square from the square in the previous column.
You thus set the valid range of slopes in the current square to the union of the intersections of the valid ranges from previous squares with valid ranges to current square.
You continue looping over columns until you hit the far end, and any reachable entries on the far end will report the ranges of slopes of vectors that allow hitting that square.
The speed of the algorithm is heavily dependent on how quickly you can union and intersect ranges of slopes (or in the 3D case, arbitrary ranges of UV coordinates). In 2D continuous space this operation can be done quickly by sorting, in a 3D discrete space, you can use a set of possible vector slopes in X,Y dependent on dimensions of your voxel space. In a 3D continuous space, some type of quadtree would probably approach what can be achieved by sorting in 2D.
The algorithm loops once over each cell in your input (Do you consider this O(n) or O(n^3)?), and takes time that will be bounded by the union of intersections call times the number of elements in your space (Worst case O(n^2) in discrete case I believe, but will shrink dramatically in the initialization step if the opposite end of the volume is far away, and may shrink quickly in the case of many opaque cells and proper data structures)
As far as I can tell, processing order of slices of the volume doesn't actually matter, so if you know that certain spots are very opaque (by sum of opaque cells or whatever), you might use a heuristic to reorder intersection operations.
A Voxel cube would look like a Rubik Cube, voxel structure is a 3D matrix of blocks, so to draw a line from one side to the other, we need to draw within each related block the line that connects to the next, together the lines form one continuous line through the cube.
The following algorithm works fine if implemented well, since you're going to work on local coordinates within the cube, any transformations of the cube itself will be applied automatically by the 3D engine when it translate it into world coordinates.
Time Complexity
MATRIX.MAX_Z * (
Time(MATRIX.GET_VOXEL(x,y,z))
+ Time(VOXEL.DRAW-LINE(0,0,0, 0,0,VOXEL_DEPTH))
)
Algorithm
FUNCTION DRAW (INTEGER X, INTEGER Y)
INTEGER VOXEL_X = X / MATRIX.VOXEL_WIDTH
INTEGER VOXEL_Y = Y / MATRIX.VOXEL_HEIGHT
FOR i = 0 .. (MATRIX.MAX_Z-1)
VOXEL V = MATRIX.GET_VOXEL(VOXEL_X, VOXEL_Y, i)
INTEGER X_0 = X % MATRIX.VOXEL_WIDTH
INTEGER Y_0 = Y % MATRIX.VOXEL_HEIGHT
INTEGER Z_0 = 0
INTEGER X_1 = X_0
INTEGER Y_1 = Y_0
INTEGER Z_1 = (MATRIX.VOXEL_DEPTH-1)
V.DRAW-LINE(X_0,Y_0,Z_0, X_1,Y_1,Z_1)
END-FOR
END-FUNCTION
So one easy way to do this test is to render the view (orthographic) from the source to the target cube at arbitrary resolution. If there is any background pixel left, there exists a line between the two rectangles. So the complexity comes down to two things:
The resolution at which you render
How fast can you render an orthographic, binary view
Now for that binary rendering the only thing you need to know is covered/not covered. That comes down to two octrees, one for minimum and one for maximum. The minimum tree tracks "is there any open child node (or)" the maximum tracks "is there any closed child node (and)". Building those trees is n log(n), but the query is only log(n).
For the target resolution, m, it should be only log(m). Even if you go up to m=2^23 for float size.
Breaking the problem down to two dimensions, it is clear that some voxel configurations are obviously impenetrable from, say, left to right:
+-+-+-+ +-+-+-+-+-+
| |#| | |#| | | | |
+-+-+-+ +-+-+-+-+-+
| |#| | |#| | |#| |
+-+-+-+ +-+-+-+-+-+
| |#| | |#| | |#| |
+-+-+-+ +-+-+-+-+-+
|#| | |#| |
+-+-+-+-+-+
| | | |#| |
+-+-+-+-+-+
... but this might not be impenetrable, depending on how you handle your corners:
+-+-+-+-+-+
|#| | | |/|
+-+-+-+-+-+
|#| | |/| |
+-+-+-+-+-+
|#| |/|#| |
+-+-+-+-+-+
|#|/| |#| |
+-+-+-+-+-+
|/| | |#| |
+-+-+-+-+-+
... and this is definitely possible:
+-+-+-+-+-+
|#| | | | |
+-+-+-+-+-+
|#| | | | |
+-+-+-+-+-+
|#| | | | |
+-+-+-+-+-+
| | | |#| |
+-+-+-+-+-+
| | | |#| |
+-+-+-+-+-+
Now, if you can think of any trick that can tell the upper 2D-cubes from the lower one, that might eliminate at least some impossible pixel/voxel configurations -- but I'm afraid you need to test every pixel on your target side for light coming through from your source side from any angle, which sounds awfully like an n-squared problem (2D), or n^4 in 3D.
In 2D, I'd start at the top of the left side and check if the line connecting my voxel centre to the top right hits an occluding pixel: if not, we're done; if it does, you advance your angle so that the ray passes the lower left corner of the occlusion and continue checking until you either find a passage or get to the end of the right side.
Continue with every pixel on your source side, until you are done -- one way or the other.
But that's brute-force, and I'd be interested to see a more elegant solution, perhaps by G. Bach ...?

Direction that is perpendicular to a collection of 3D points?

I have a collection of 3D points which form an imperfect circle and are stored in the order in which they appear in the circle. I'm positioning an object in the centre of the ring by calculating the mean position of all of the points, which works fine. Now, what I want is for the object in the centre to be facing up/down relative to the rest of the points (i.e perpendicular to the ring).
I've included an image to help clarify what I mean. Does anyone know of an algorithm that would be suitable for this?
You have to compute the plane that your points form and get its normal.
If the points are perfectly coplanar, just get three of them, a, b, and c, and compute two vectors. The normal vector n is the cross product of them:
v1 = b - a;
v2 = c - a;
n = v1 x v2;
If the points are not perfectly coplanar, you can get the plane that best fits the points and then, its normal. You can get the plane by solving a linear equation system of the form Ax=0. Since the general equation of a plane is Ax + By + Cz + D = 0, you get one equation per 3D point, obtaining this system:
| x1 y1 z1 1 | | A | | 0 |
| x2 y2 z2 1 | x | B | = | 0 |
| x3 y3 z3 1 | | C | | 0 |
| ... | | D | | ... |
| xn yn zn 1 | | 0 |
The normal vector is (A, B, C).
Elaborating on a previous answer, you get a system of n equations in 4 unknowns when you solve for the best hyperplane normal vector with n points. You need to set one of the unknown coefficients (say D) to a constant like 1 and move the corresponding data column to the right hand side so that you don't get the trivial solution A=B=C=D=0. You can safely set one coefficient to 1 if it is non-zero because the solution A,B,C,D is still a solution if you scale it. So you get a system of n equations in 3 unknowns where the right hand side is a vector of all -1 instead of the zero vector, and your data matrix is simply your matrix of points and your unknown coefficients are A,B,C. In general such a system is overdetermined if you have more than 3 points so you need to solve it using linear regression. See http://en.wikipedia.org/wiki/Linear_regression to get the matrix formula for solving for the 3 coefficients using least squares best fit.

how to simulate a rectangle union starting with a rectangle intersection

Given rectangle_A intersecting rectangle_B, which has a union defined such that it is the rectangle containing both rectangles, I want to determine the coordinates of the (not overlapping) rectangles required to add to rectangle_A to create the union of rectangle_A and rectangle_B:
Note: this is just one configuration of the solution set of rectangles. the white rectangles above could be configured differently, as long as they don't overlap.
Is there a simple algorithm for every case of rectangle intersection? I've done a first pass and I miss some corners. Evidently not my forté.
Why? When panning in a UI, I only want to (i) update the new parts of the canvas (ii) keep track of what has been painted as a rectangle (the union of rectangle_A and rectangle_B).
If you are not concerned with minimizing the number of rectangles returned, you can simplify the thought process to one that always returns no more than 8 rectangles:
U
+----------+----+-------+
| | | |
| 1 | 2 | 3 |
+----------+----+-------+
| | | |
| 4 | A | 5 |
| | | |
+----------+----+-------+
| 6 | 7 | 8 |
+----------+----+-------+
U.x1 = min(A.x1,B.x1)
U.x2 = max(A.x2,B.x2)
U.y1 = min(A.y1,B.y1)
U.y2 = max(A.y2,B.y2)
R1.x1 = R4.x1 = R6.x1 = U.x1
R2.x1 = R7.x1 = R1.x2 = R4.x2 = R6.x2 = A.x1
R2.x2 = R7.x2 = R3.x1 = R5.x1 = R8.x1 = A.x2
R3.x2 = R5.x2 = R8.x2 = U.x2
R1.y1 = R2.y1 = R3.y1 = U.y1
R1.y2 = R2.y2 = R3.y2 = R4.y1 = R5.y1 = A.y1
R4.y2 = R5.y2 = R6.y1 = R7.y1 = R8.y1 = A.y2
R6.y2 = R7.y2 = R8.y2 = U.y2
If you wanted, you could then quickly check each rectangle to see if r.x1 == r.x2 || r.y1 == r.y2 (i.e. if it has zero area), and throw it out if so. In most cases, over half of the rectangles can be thrown out this way.
For example, in your three examples, this solution would return 3, 1, and 5 rectangles, and would return 0 in the best case (when B is contained in A) and 8 in the worst case (when A is contained in B).
Say we represent rectangles by a pair of x,y coordinate pairs: x1,y1 for the top-left and x2,y2 for the bottom left corner. Let's also assume y coordinate increase downwards and x coordinates increase left to right.
Now, suppose the rectangle formed by the union of A and B (according to your definition of union) is the rectangle is U.
So,
U.x1=min(A.x1,B.x1), U.y1=min(A.y1,B.y2) --- top-left corner, take the lowest values
U.x2=max(A.x2,B.x2), U.y2=max(A.y2,B.y2) --- bottom-right corner, take the highest values
Now that we have the larger rectangle U, we can use that to compute the smaller right and bottom rectangles that have to be added to A (the left/top rectangle) to make it U. Lets call them Rt and Bot.
(This time I'm assuming A is the top-left rectangle, if it isn't swap A and B. Also assuming the layout to be similar to that of your picture. If that isn't the case you can adapt this easily).
Rt.x1=A.x2, Rt.y1=A.y1
Rt.x2=A.x2, Rt.y2=B.y2
Bot.x1=A.x1, Bot.y1=A.y2
Bot.x2=A.x2, Bot.y2=B.y2
I'm sorry i cant give a working solution, but...
At first I would try to draw such nice images for every different case that you can imagine. There will be a lot cases, where you need more than 2 rectangles, or just one, right?
I think getting the rect containing the others is trivial-but at this time I can't think of how to proceed. :)
Edit: At this time i'm thinking of a flood fill algorith, just fill up your larger rect. But there are 2 problems with this I can imagine: How to use the flood fill output to generate rects from it? Will it be the right way, or is there a linear algebra solution or something?

Resources