Now that your question has been answered, I would like to suggest a way of doing this that I think is more Ruby-like, as it does not make use of indices. It also generalizes to dimensions higher than two (though that may be of no immediate interest).
Note that regardless of which method you use, you can generalize it to determining the intersection of any number of rectangles by first determining the intersection of the first two, then the intersection of that result with the third rectangle, and so on.
Code
def rec_intersection(rec1,rec2)
rec1.zip(rec2, [:max, :min])
.map { |*a,method| a.transpose.map { |b| b.send method } }
end
Examples
Suppose your overlapping rectangles looked like this.
The two rectangles are:
rec1 = [[0,0],[3,4]]
rec2 = [[2,2],[5,5]]
Therefore:
rec_intersection(rec1,rec2)
#=> [[2, 2], [3, 4]]
One nice thing about this method is that it can be applied to overlapping boxes (orthotopes or hyperrectangles) in any number of dimensions. Suppose you have these two boxes in three dimensions:
The two rectangles are:
rec1 = [[0,0,0],[3,4,3]]
rec2 = [[2,3,1],[5,8,5]]
Therefore:
rec_intersection(rec1,rec2)
#=> [[2, 3, 1], [3, 4, 3]]
Explanation
Consider the first example above:
rec1 = [[0,0],[3,4]]
rec2 = [[2,2],[5,5]]
We use Array#zip in order to compare the lower-left and upper-right coordinates of the two rectangles:
c = rec1.zip(rec2, [:max, :min])
#=> [[[0, 0], [2, 2], :max], [[3, 4], [5, 5], :min]]
Notice that we also pass methods to each of these arrays: Enumerable#max for the first, Enumerable#min for the second.
Enumerable#map passes each element of c
(of which there are two) into its block and assigns values to the block variables a
and method
. The first is:
a => [[0, 0], [2, 2]]
method => :max
Next we apply Array#transpose to a
:
d = a.transpose
#=> [[0, 2], [0, 2]]
and then map each of these arrays into the maximum of the elements by sending max
to the array:
d.map { |b| b.send method } #=> [2,2]
This gives us the maxima of the x and y coordinates, resulting in the first element of b
being replaced with [2,2]
. Next, map
passes:
[[3, 4], [5, 5], #<Proc:0x00000101138498>]
into the block, assigning it to the block variables:
a => [[3, 4], [5, 5]]
method => :min
Since :min
computes the minimum of an array, we obtain:
d = a.transpose
#=> [[3, 5], [4, 5]]
d.map { |b| b.send method } #=> [3,4]
The second element of b
is therefore replaced with [3,4]
and the method returns:
[[2, 2], [3, 4]]