in reply to Detecting control placement constraints in dialog resources - rectangle overlap checking
However, we can remove that assumption by replacing x1 by min(x1,x2) and x2 by max(x1,x2) (rect_overlap_2). This gets the fourth test case correct.
We can simplify further by using map to apply the min resp. max operation to the appropriate coordinates of the two rectangles (rect_overlap_3).At this point, the variables $r1 and $r2 become unnecessary and we can replace ($r1,$r2) throughout by @_. At this point, rect_overlap should be able to calculate correctly whether any number of rectangles have at least one point that is common to all of them.
use List::Util qw(min max); sub x1{0} sub y1{1} sub x2{2} sub y2{3} sub rect_overlap_1 { my($r1,$r2) = @_; return max($$r1[x1],$$r2[x1]) <= min($$r1[x2],$$r2[x2]) && max($$r1[y1],$$r2[y1]) <= min($$r1[y2],$$r2[y2]); } # some tests: use Test::Simple 'no_plan'; ok rect_overlap_1 [10, 10, 30, 30], [20, 20, 40, 60]; # do ok !rect_overlap_1 [10, 10, 30, 30], [20, 40, 40, 60]; # don't ok rect_overlap_1 [10, 10, 30, 30], [15, 15, 20, 20]; # inside ok rect_overlap_1 [10, 10, 30, 30], [40, 20, 20, 60]; # do sub rect_overlap_2 { my($r1,$r2) = @_; return max(min(@$r1[x1,x2]),min(@$r2[x1,x2])) <= min(max(@$r1[x1,x2]),max(@$r2[x1,x2])) && max(min(@$r1[y1,y2]),min(@$r2[y1,y2])) <= min(max(@$r1[y1,y2]),max(@$r2[y1,y2])); } ok rect_overlap_2 [10, 10, 30, 30], [20, 20, 40, 60]; # do ok !rect_overlap_2 [10, 10, 30, 30], [20, 40, 40, 60]; # don't ok rect_overlap_2 [10, 10, 30, 30], [15, 15, 20, 20]; # inside ok rect_overlap_2 [10, 10, 30, 30], [40, 20, 20, 60]; # do sub rect_overlap_3 { my($r1,$r2) = @_; return max(map{min(@$_[x1,x2])}($r1,$r2)) <= min(map{max(@$_[x1,x2])}($r1,$r2)) && max(map{min(@$_[y1,y2])}($r1,$r2)) <= min(map{max(@$_[y1,y2])}($r1,$r2)); } ok rect_overlap_3 [10, 10, 30, 30], [20, 20, 40, 60]; # do ok !rect_overlap_3 [10, 10, 30, 30], [20, 40, 40, 60]; # don't ok rect_overlap_3 [10, 10, 30, 30], [15, 15, 20, 20]; # inside ok rect_overlap_3 [10, 10, 30, 30], [40, 20, 20, 60]; # do sub rect_overlap { return max(map{min(@$_[x1,x2])}@_) <= min(map{max(@$_[x1,x2])}@_) && max(map{min(@$_[y1,y2])}@_) <= min(map{max(@$_[y1,y2])}@_); } ok rect_overlap [10, 10, 30, 30], [20, 20, 40, 60]; # do ok !rect_overlap [10, 10, 30, 30], [20, 40, 40, 60]; # don't ok rect_overlap [10, 10, 30, 30], [15, 15, 20, 20]; # inside ok rect_overlap [10, 10, 30, 30], [40, 20, 20, 60]; # do ok rect_overlap [10, 10, 30, 30], [15, 15, 20, 20], [20, 20, 40, 60]; + # (20,20)
|
|---|