Minimum distance between two rotated rectangles with different angles - geometry

How can I calculate the minimum distance between two rectangles?It is easy for rectangles which have no angles (i.e. 0 degrees one), but for rotated rectangles with any different angles I do not know how to do it.
Can you recommend any way?
WhiteFlare

Check either they intersect first (try to take point from one rectangle and check either it is inside other rectangle).There are several ways to do it. One method (not the best one, but easy to explain) is the following. Let A1, A2, A3, A4 - rectangle points, T - some other point. Then count squares for triangles: S1 = (A1,A2,T), S2 = S(A2,A3,T), S3 = S(A3, A4, T), S4 = S(A4, A1, A2). Let S_rectangle be reactangle square. Then T lies inside rectangle <=> S1 + S2 + S3 + S4 = S_rectangle.
If reactangles don't intersect each other, then do these steps.
Calculate coordinates of all 8 points of 2 rectangles.
Take minimum among all 4 * 4 = 16 pairs of points (points from different rectangles). Let's denote it min_1.
Then, take some point from the first rectangle (4 ways to do it), take 4 segments of another rectangle (4 ways), check either perpendicular from that point to that segment gets inside segment. Take the mininmum of such perpendiculars. Let's denote it min_2.
The same as in 3, but take point from the second rectangle, lines from the first: you get min_3.
result = min(min_1, min_2, min_3)

Calculate coordinates of all 8
points of 2 rectangles.
Take the two lowest distances among
all 4 * 4 = 16 pairs of points
(points from different rectangles).
And get the 3 points P1, P2 and P3
{Two of them belong to one rectangle
and the third to the other}
The 2 Points belong to one rectangle
should considered as segment, Now
find the Short distance between a
segment and the third point.

Related

Calculate area inside country boundaries for top 10

Using country boundaries, I wish to calculate area of the polygons inside countries. For example; calculate area of large water bodies inside a country polygon to estimate the top 10 countries with the largest area of water bodies.
Some lakes are trans-national, and can be excluded in the analysis.
I am not sure I fully understood your question.
Do you ask how to calculate a polygon area?
If so, and I'm assuming your area is placed on an x and y axis plane, it should be pretty simple:
First of all, make sure you have all the area vertex by their order. Then calculate:
abs((x1y2 - x2y1) + (x2y3 - x3y2) + .... + (xny1 - x1yn)) and divide it all by 2.
[The "abs" mean you should get a positive result even if it calculates out as negative.]
Make sure xn is the x coordinate of vertex n, yn is the y coordinate of the nth vertex, etc.
Good Luck!

Bitmap pattern recogination

Describe and analyze an algorithm that finds the maximum-area rectangular
pattern that appears more than once in a given bitmap. Specifically, given
a two-dimensional array M[1 .. n, 1 .. n] of bits as input, your algorithm
should output the area of the largest repeated rectangular pattern in M.
For example, given the bitmap shown on the left in the figure below, your
algorithm should return the integer 195, which is the area of the 15 x 13
doggo. (Although it doesn’t happen in this example, the two copies of the
repeated pattern might overlap.)
Image: enter image description here
Using term rectangle instead of sub-matrix.
Brute Force Approach O(n^8)
Take two distinct positions A and B in matrix. Then consider all rectangles in the matrix with A as top left corner. Similarly consider all rectangles with B as top left corner. Suppose we have a rectangle with top-left corner A of length l and breadth b, then take corresponding rectangle with top left corner B, length l, breath b (Assuming both such rectangles exist). If every bit of both rectangles match, then we have a pattern of area of lb repeating and if lb is greater than previously seen maximum area, update the maximum area.
Repeat this procedure for all pairs of A and B.
Time Complexity : Without making analysis complex, let us assume that for every point P in matrix,for all rectangles with P as top left corner, possible maximum length of rectangle is n (But this is not true, for example consider point in the last row and last column of matrix). Let us make similar assumption for maximum possible breath of rectangle.
Then from product rule in counting, there are n^2 possible rectangles with point P as their top left corner.
This estimate is not so bad because according to this, there are total n^4 rectangles possible, as there are n^2 points in the rectangle and we have n^2 rectangles per point.
Actual answer is ( (n+1) Choose 2 ) * ( (n+1) Choose 2 ), which is in the order of n^4
So in total, for each pair, we'd compare n^2 rectangles. And similar to above, let us estimate that there are n^2 points in each rectangle for easy calculations. So for a pair of points A and B, we'll have O(n^4) comparisons because for each rectangle, we need to check all of their corresponding points.
And there are ( n^2 Choose 2 ) pairs of points in total, which is of order n^4. So we'd have overall time complexity of O(n^8).
Avoiding Repeated Calculations O(n^6)
We see that we are repeatedly checking same area again and again. For example consider two rectangles with top-left corners at A and B respectively, with length l and breadth b. Again when we check another corresponding rectangles with top-left corners at A and B with length (l+1) and breadth b, we are again checking rectangle of length l and breadth b.
So we use memoization to avoid repeated calculations.
Assume length of a rectangle is measured horizontally and breadth vertically measured.
Consider rectangles of length l+1 and breadth b with top-left corners at A and B. Now we need to compare if all values of corresponding points in rectangles match. A_r, B_r be points to right of A and B respectively. Then if rectangles have same values for all corresponding points, rectangles of length l, breadth b with top left corners A and B must repeat. Similarly rectangles of length l and breadth b with top-left corners at A_r and B_r must match.
Consider below figure :
Time Complexity By above procedure, it'd take O(1) time to compare two rectangles. So compared to above case, time complexity is reduced by a factor of n^2 (which was time required to compare rectangles in earlier case). So O(n^6) time in this case.
Let us represent (P, m, n) as rectangle with top-left corner P, length m and breadth m.
Removing unnecessary calculations O(n^5)
In the above approach, even if we know that if rectangles (A, l, b) and (B, l, b) do not match we again compare the rectangles (A, l+1, b) and (B, l+1, B).
So suppose now we have rectangles with top-left corners A and B each of length l, then what is maximum possible breadth of the rectangles?
If all the corresponding elements in top row of each rectangle do not match, then answer is 0. But if all corresponding rows match, then the answer is 1 + (max.breadth of rectangles of length l but with top-left corners below A and B).
And similar to above approach this calculation would take O(1) time, as we need breadth that of (A, B, l-1) and that of below rectangles with length l.
Refer to this answer Largest Square Block for more clarity.
Time Complexity For each pair of points in the matrix, we have to store max. breadth for length 1, 2, ...n. And there are order of n^4 such pairs. And we can check obtain each value in O(1) time. So overall time complexity is O(n^5). And finding max. area for each length of rectangle for each pair is obvious here.
Further Optimization O(n^4)
Imagine you have two copies of bitmaps. One is glued to the ground and other can move on top the glued one. Let us call fixed one as base and other one as moving bitmap.
Now top-left corner of moving bitmap can be on one of (n^2 - 1) points of base, except the case where moving bitmap sits on top of base. Now in each case, there are some points left-out i.e for some points on base bitmap, there will not be a point of moving one on top of it and vice-versa. Assume top-left corner of moving bitmap needs to have an element of base bitmap below it.
Now take one instance of these (n^2 - 1) configurations. And for all points on moving bitmap which have a point of base bitmap below them, let us construct a new matrix such that it contains "Y" if top and bottom element of both the bitmaps are same, else it'd contain "N". And remember, the size of matrix is same as no of elements on moving bitmap which have an element of base bitmap below them.
Then, maximum area of repeated pattern for that portions of base and moving bitmaps would be maximum solid block area containing all Y's, which can be done in O(n^2) time.
Our required answer is maximum of answers in all these (n^2 - 1) configurations.
Refer to Largest rectangle containing all Y's for further clarity
Time Complexity For each configuration, constructing new matrix of "Y" and "N"'s would take O(n^2) time and maximum area calculation also O(n^2) time.
And there are (n^2- 1) such configurations, so overall O(n^4) time.
Further Optimization O(n^3 polylog(n))
Consider in above bitmap :
For length : 1, a rectangle with length : 1 and breadth 3 is
repeating twice. (1st and 2nd columns are same in bitmap). So
maxBreadth(1) is 3.
For length : 2, a rectangle with length : 2 and breadth 2 is
repeating twice. So maxBreadth(2) is 2.
The rectangle is :
0
0
0
0
For length : 3, a rectangle with length : 3 and breadth 1 is
repeating twice. So maxBreadth(3) is 1.
For lengths : 4, no rectangle with length : 4 is repeating in the
bitMap, so maxBreadth(4) is 0.
Consider you have a method named maxBreadth which takes a bitmap matrix and length L as input and returns to you the maximum breadth B for which there is a repeating rectangle of with length L and breadth B in the bitmap.
Using this, can you find the area of largest repeating rectangle in a bitmap?? Iterate over each length. We now know that there is a rectangle repeating in the bitmap with area length * maxBreadth(bitMap, length). Update the corresponding maximum area encountered till now.
So now let's focus on maxBreadth method.
Observations :
If a rectangle of length 3 and breadth 5 is not repeating in given bitmap then a rectangle of length 3 and breadth 6 definitely will not be repeating in the bitmap. Generally if a rectangle of length l and breadth b does not repeat in bitMap, any rectangle of length l and breadth > b does not repeat in bitMap. Same goes for length also.
So based on above observation, you can do binary search to find maxBreadth of given length.
If rectangle of length L breadth B is
repeating, then check for breadth 2B
not repeating, then check for breadth B/2
Ok, now how to check if any rectangle of dimensions (l, b) is repeating in a bitMap? There are n^2 such rectangles, so will you compare each with all the others?
What will you do if you asked if an array of numbers is having a repeated element efficiently? Answer is to sort them and check
So take all the n^2 rectangles and sort them and check if there is any repeating one. And how to compare two 2D rectangles, just divide the rectangle into 4 quadrants and compare them individually. In this way we only need to store sorted indices for breadths 1, 2, 4, 8, ... n. and also for lengths 1, 2, 4, 8, ....n.
Each sorting takes O(n^2 log(n)) time for given (length, breadth)
And for each length we perform this operation log(n) times, so total O((n.logn)^2) time complexity for maxBreadth operation.
Finally we call the method maxBreadth n times, so overall time complexity is O(n^3 log(n)^2) and space complexity is O((n.logn)^2)
Note : This O(n^3 log(n)^2) method not only works for bitMaps but also for matrices containing any number of distinct arbitrary numbers to search for maximum repeating sub-matrix

Calculating the fraction of the area of multiple squares overlapped by a circle

This is a geometrical question based on a programming problem I have. Basically, I have a MySQL database full of latitude and longitude points, spaced out to be 1km from each other, corresponding to a population of people who live within the square kilometer around each point. I then want to know the relative fraction of each of those grids taken up by a circle of arbitrary size that overlaps them, so I can figure out how many people roughly live within a given circle.
Here is a practical example of one form of the problem (distances not to scale):
I am interested in knowing the population of people who live within a radius of point X. My database figures out that its entries for points A and B are close enough to point X to be relevant. Point A in this example is something like 40.7458, -74.0375, and point B is something like 40.7458, -74.0292. Each of those green lines from A and B to its grid edge represents 0.5 km, so that the gray circle around A and B each represent 1 km^2 respectively.
Point X is at around 40.744, -74.032, and has a radius (in purple) of 0.05 km.
Now I can easily calculate the red lines shown using geographic trig functions. So I know that the line AX is about .504 km, and the distance line BX is about .309 km, for whatever that gets me.
So my question is thus: what's a solid way for calculating the fraction of grid A and the fraction of grid B taken up by the purple circle inscribed around X?
Ultimately I will be taking the population totals and multiplying them by this fraction. So in this case, the 1 km^2 grid around corresponds to 9561 people, and the grid around B is 10763 people. So if I knew (just hypothetically) that the radius around X covered 1% of the area of A and 3% of the area of B, I could make a reasonable back-of-the-envelope estimate of the total population covered by that circle by multiplying the A and B populations by their respective fractions and just summing them.
I've only done it with two squares above, but depending on the size of the radius (which can be arbitrary), there may be a whole host of possible squares, like so, making it a more general problem:
In some cases, where it is easy to figure out that the square grid in question is 100% encompassed by the radius, it is in principle pretty easy (e.g. if the distance between AX was smaller than the radius around X, I know I don't have to do any further math).
Now, it's easy enough to figure out which points are within the range of the circle. But I'm a little stuck on figuring out what fractions of their corresponding areas are.
Thank you for your help.
I ended up coming up with what worked out to be a pretty good approximate solution, I think. Here is how it looks in PHP:
//$p is an array of latitude, longitude, value, and distance from the centerpoint
//$cx,$cy are the lat/lon of the center point, $cr is the radius of the circle
//$pdist is the distance from each node to its edge (in this case, .5 km, since it is a 1km x 1km grid)
function sum_circle($p, $cx, $cy, $cr, $pdist) {
$total = 0; //initialize the total
$hyp = sqrt(($pdist*$pdist)+($pdist*$pdist)); //hypotenuse of distance
for($i=0; $i<count($p); $i++) { //cycle over all points
$px = $p[$i][0]; //x value of point
$py = $p[$i][1]; //y value of point
$pv = $p[$i][2]; //associated value of point (e.g. population)
$dist = $p[$i][3]; //calculated distance of point coordinate to centerpoint
//first, the easy case — items that are well outside the maximum distance
if($dist>$cr+$hyp) { //if the distance is greater than circle radius plus the hypoteneuse
$per = 0; //then use 0% of its associated value
} else if($dist+$hyp<=$cr) { //other easy case - completely inside circle (distance + hypotenuse <= radius)
$per = 1; //then use 100% of its associated value
} else { //the edge cases
$mx = ($cx-$px); $my = ($cy-$py); //calculate the angle of the difference
$theta = abs(rad2deg(atan2($my,$mx)));
$theta = abs((($theta + 89) % 90 + 90) % 90 - 89); //reduce it to a positive degree between 0 and 90
$tf = abs(1-($theta/45)); //this basically makes it so that if the angle is close to 45, it returns 0,
//if it is close to 0 or 90, it returns 1
$hyp_adjust = ($hyp*(1-$tf)+($pdist*$tf)); //now we create a mixed value that is weighted by whether the
//hypotenuse or the distance between cells should be used
$per = ($cr-$dist+$hyp_adjust)/100; //lastly, we use the above numbers to estimate what percentage of
//the square associated with the centerpoint is covered
if($per>1) $per = 1; //normalize for over 100% or under 0%
if($per<0) $per = 0;
}
$total+=$per*$pv; //add the value multiplied by the percentage to the total
}
return $total;
}
This seems to work and is pretty fast (even though it does use some trig on the edge cases). The basic logic is that when calculating edge cases, the two extreme possibilities is that the circle radius is either exactly perpendicular to the grid, or exactly at 45 degree angles from it. So it figures out roughly where between those extremes it falls and then uses that to figure out roughly what percentage of the grid square is covered. It gives plausible results in my testing.
For the size of the squares and circles I am using, this seems to be adequate?
I wrote a little application in Processing.js to try and help me work this out. Without explaining all of it, you can see how the algorithm is "thinking" by looking at this screenshot:
Basically, if the circle is yellow it means it has already figured out it is 100% in, and if it is red it is already quickly screened as 100% out. The other cases are the edge cases. The number (ranging from 0 to 1) under the dot is the (rounded) percentage of coverage calculated using the above method, while the number under that is the calculated theta value used in the above code.
For my purposes I think this approximation is workable.
With enough classification (sketched below) all computations can be reduced to a primitive calculation, the one that provides the angular area of the orange region depicted in the image
When y0 > 0, as illustrated above, and regardless of whether x0 is positive or negative, the orange area can be calculated accurately as the integral from x0 to x1 of sqrt(r^2 - y^2) minus the rectangular area (x1 - x0) * (y1 - y0). The integral has a well known closed expression and therefore there is no need to use any numerical algorithm for calculating it.
Other intersections between a circle and a square can be reduced to a combination of rectangles and right-angular shapes as the one painted in orange above. For instance, an intersection delimited by the horizontal and vertical orange rays in the following picture can be expressed by summing the area of the red rectangle plus two angular shapes: the blue and the green.
The blue area results from a direct application of the primitive case identified above (where the inferior rectangle collapses to nothing.) The green one can also be measured in the same way, once the negative y coordinate is replaced by its absolute value (the other y being 0).
Applying these ideas one could enumerate all cases. Basically, one should consider the case where just one, two, three or four corners of the square lie inside the circle, while the remaining (if any) fall outside. The enumeration is a problem in itself, but it can be solved, at least in theory, by considering a relatively small number of "typical" configurations.
For each of the cases enumerated as described a decomposition on some few rectangles and angular areas has to be calculated and the parts added up (or subtracted) as shown in the three-color example above. The area of every part would reduce to rectangular or primitive angular areas.
A considerably amount of work has to be done to turn this line of attack into a working algorithm. A deeper analysis could shed some light on how to minimize the number of "typical" configurations to consider. If not, I think that the amount of combinations to consider, however large, should be manageable.
In case your problem admits an approximate answer there is another technique you could use which is much simpler to program. The whole idea of this problem reduces to calculate the area of the intersection of a square and a circle. I didn't explain this in my other answer, but finding the squares that are likely to intercept the circle shouldn't be a problem, otherwise, let us know.
The idea of calculating the approximate area of the intersection is very simple. Generate enough points in the square at random and check how many of them belong in the circle. The ratio between the number of points in the circle and the total number of random points in the square will give you the proportion of the intersection with respect to the square's area.
Now, given that you have to repeat the same routine for all squares surrounding the circle (i.e., squares which center has a distance to the circle's center not very different from the circle's radius) you could re-use the random points by translating them from one square to the other.
I don't want to go into details if this method is not appropriate for your problem, so let me just indicate that generating random points uniformly distributed in the square is fairly easy. You only need to generate random numbers for the x coordinate and, independently, random numbers for y. Then just consider all pairs (x, y). Then, for every (x, y) verify whether (x - a)^2 + (y - b)^2 <= r^2 or not, where (a, b) stands for the circle's center and r for the radius.

interpolation in 3d computer graphics

I was wondering if someone could help with explaining in simple terms what interpolation is and how its used in 3d computer graphics
Simply put: given two points A and B, find a point between them.
For example, if I want to move something along a line from a position x=1 to x=4 in one step:
1-----------------------4
The first step is at location 1, the second step is at location 4, so the object moves instantly from one location to the other. However, if I want the object to take a certain amount of time or number of frames to make the transition, I'll need to refine that by finding intermediate points that are evenly spaced.
If I want the object to take two steps (or frames) to move from 1 to 4,
1-----------X-----------4
I need to calculate what the new point (X) is so I can draw the object there at the appropriate time. In this case, the point X will be
(max-min)
location = min + (current_step) * --------
steps
location is what we're trying to find. min=1, max=4, and in this example steps=2 since we want to divide the span into two steps:
step: location:
0 1
1 2.5
2 4
1------------(2.5)-----------4
If we want to take 4 steps:
step: location:
0 1
1 1.75
2 2.5
3 3.25
4 4
1---(1.75)---(2.5)---(3.25)---4
And so forth. For four steps, the object moves 25% of the total distance per frame. For 10 steps, 10%, etc ad nauseum.
For multiple dimensions (when an object has a 2- or 3-dimensional trajectory), just apply this to each X,Y,Z axis independently.
This is linear interpolation. There are other kinds. As always, Google can help you out.
Other applications include texture mapping, anti-aliasing, image smoothing and scaling, etc., and of course many other uses outside of games and graphics.
Note: a lot of frameworks already provide this. In XNA, for instance, it's Matrix.Lerp.
Interpolation is the smooth adjustment from one thing to another. It is used in animation.
For example, if an object is at location 1, and we want to move it to location 2 over the course of six seconds, we need to slowly interpolate its location between the two endpoints. Interpolation also refers to any search for a location on that path.
Interpolation is the 'guessing' of points based on other points.
for example when you have the points (0,0) and (2,2) you might 'guess' that the point (1,1) also belongs to the set.
The simples application is to deduce a line from two points.
The same thing works in 3 or actually n-dimension.
In 3D graphics it will be used
for animations, to calculate the position of things based on start and end coordinations
calculating lines
gradients
scaling of graphics
and probably many more
General Definition
Interpolation (in mathematics) can be regarded as a transition from one value to another. Interpolation usually uses a value in the 0 to 1 range like a percentage. 0 is the starting value and 1 is the end value. The main purpose of interpolation is to find values in between given values.
Types of Interpolation
There are many types of interpolation used in various programs, the most common being linear interpolation. This type of interpolation is the most simple and straight-forward; It is used to find values in a line segment between two points or numbers. There are also: cubic interpolation, quadratic interpolation, bilinear, trilinear, etc. For more information go here: https://en.wikipedia.org/wiki/Interpolation.
Application in 3D Graphics
Interpolation, especially linear, bilinear and trilinear, is important for computing fragments in geometry (the textures and visuals of the geometry), blending volumetric textures, mip-mapping (a depth of field effect on texture), and lighting (like unreal engine's volumetric lightmaps). The results of the interpolation may vary, but it could potentially yield very realistic results. It is a rather large computation, especially when the interpolation is in 3-dimensions or above (hyperspace).
Example of Interpolation
In 1 Dimension:
n1 = 1
n2 = 2
i = 0.5
n3 = (n1 - n1 * i) + n2 * i
///////////////////////////////////////
n3
├────────┼────────┼────────┼────────┤
1 1.25 1.5 1.75 2
///////////////////////////////////////
In 2 Dimensions:
v1 = {1, 1}
v2 = {1.5, 2}
i = 0.5
d = √((v1.x - v2.x)^2 + (v1.y - v2.y)^2)
v3 = {v1.x + -d * i * ((v1.x - v2.x) / d),v1.y + -d * i * ((v1.y - v2.y) / d)}
///////////////////////////////
2 ┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼ v2
1.5 ┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─●
┼─┼─┼─┼─┼─┼─┼v3─┼─┼─┼─┼─┼
┼─┼─┼─┼─┼─┼─●─┼─┼─┼─┼─┼─┼
┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
┼v1─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
●─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼
1 1.5 2
///////////////////////////////

How can I find the 3D coordinates of a projected rectangle?

I have the following problem which is mainly algorithmic.
Let ABCD be a rectangle with known dimensions d1, d2 lying somewhere in space.
The rectangle ABCD is projected on a plane P (forming in the general case a trapezium KLMN). I know the projection matrix H.
I can also find the 2D coordinates of the trapezium edge points K,L,M,N.
The Question is the following :
Given the Projection Matrix H, The coordinates of the edges on the trapezium and the knowledge that our object is a rectangle with specified geometry (dimensions d1, d2), could we calculate the 3D coordinates of the points A, B, C, D ?
I am grabbing images of simple rectangles with a single camera and i want to reconstruct the rectangles on space. I could grab more than one image and use triangulation but this is not desired.
The projection Matrix alone isn't enough since a ray is projected to the same point. The fact that the object has known dimensions, makes me believe that the problem is solvable and there are finite solutions.
If I figure out how this reconstruction can be made I know how to program it. So I am asking for an algorithmic/math answer.
Any ideas are welcome
Thanks
You need to calculate the inverse of your projection matrix. (your matrix cannot be singular)
I'm going to give a fairly brief answer here, but I think you'll get my general drift. I'm assuming you have a 3x4 projection matrix (P), so you should be able to get the camera centre by finding the right null vector of P: call it C.
Once you have C, you'll be able to compute rays with the same direction as vectors CK,CL,CM and CN (i.e. the cross product of C and K,L,M or N, e.g. CxK)
Now all you have to do is compute 3 points (u1,u2,u3) which satisfies the following 6 constraints (arbitrarily assuming KL and KN are adjacent and ||KL|| >= ||KN|| if d1 >= d2):
u1 lies on CK, i.e. u1.CK = 0
u2 lies on CL
u3 lies on CN
||u1-u2|| = d1
||u1-u3|| = d2
(u1xu2).(u1xu3) = 0 (orthogonality)
where, A.B = dot product of vectors A and B
||A|| = euclidean norm of A
AxB = cross product of A and B
I think this problem will generate a set of possible solutions, at least in 2D it does. For the 2D case:
|
-----------+-----------
/|\
/ | \
/ | \
/---+---\VP
/ | \
/ | \
/ | \
/ | \
/ | -- \
/ | | \
/ | | \
In the above diagram, the vertical segment and the horizontal segment would project to the same line on the view plane (VP). If you drew this out to scale you'd see that there are two rays from the eye passing through each end point of the unprojected line. This line can be in many positions and rotations - imagine dropping a stick into a cone, it can get stuck in any number of positions.
So, in 2D space there are an infinite number of solutions within a well defined set.
Does this apply to 3D?
The algorithm would be along the lines of:
Invert the projection matrix
Calculate the four rays that pass through the vertices of the rectangle, effectively creating a skewed pyramid
Try and fit your rectangle into the pyramid. This is the tricky bit and I'm trying to mentally visualise rectangles in pyramids to see if they can fit in more than one way.
EDIT: If you knew the distance to the object it would become trivial.
EDIT V2:
OK, let Rn be the four rays in world space, i.e. transformed via the inverse matrix, expressed in terms of m.Rn, where |Rn| is one. The four points of the rectange are therefore:
P1 = aR1
P2 = bR2
P3 = cR3
P4 = dR4
where P1..P4 are the points around the circumference of the rectangle. From this, using a bit of vector maths, we can derive four equations:
|aR1 - bR2| = d1
|cR3 - dR4| = d1
|aR1 - cR3| = d2
|bR2 - dR4| = d2
where d1 and d2 are the lengths of the sides of the rectangle and a, b, c and d are the unknowns.
Now, there may be no solution to the above in which case you'd need to swap d1 with d2. You can expand each line to:
(a.R1x - b.R2x)2 + (a.R1y - b.R2y)2 + (a.R1z - b.R2z)2 = d12
where R1? and R2? are the x/y/z components of rays 1 and 2. Note that you're solving for a and b in the above, not x,y,z.
m_oLogin is right. If I understand your goal, the image the camera snaps is the plane P, right? If so, you're measuring K,L,M,N off the 2D image. You need the inverse of the projection matrix to reconstruct A,B,C, and D.
Now I've never done this before, but it ocurrs to me that you might run into the same problem GPS does with only 3 satellite fixes - there are two possible solutions, one 'behind' P and one 'in front' of it, right?
The projection matrix encapsulates both the perspective and scale, so the inverse will give you the solution you are after. I think you are assuming that it only encapsulates the perspective, and you need something else to choose the correct scale.

Resources