码迷,mamicode.com
首页 > 其他好文 > 详细

Axis­ Aligned ?Rectangles

时间:2015-06-26 23:37:54      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

Describe ?an? algorithm ?that ?takes ?an ?unsorted ?array ?of ?axis‐aligned ?rectangles ?and? returns ?any ?pair ?of ?rectangles ?that? overlaps,? if ?there? is ?such? a ?pair.? ?Axis‐aligned? means? that? all ?the? rectangle? sides? are ?either ?parallel? or? perpendicular ?to? the? x‐? and? y‐axis. ??You? can? assume ?that? each? rectangle? object? has? two ?variables?in? it: ?the ?x‐y? coordinates ?of ?the? upper‐left ?corner ?and ?the ?bottom‐right ?corner.

 

Good? Answer: ?Create? a ?sorted ?array ?of? the? x? coordinates ?of ?the? left? and? right? edges ?of? the ?rectangles. ??Then, ?use ?a? "scanline" ?to? move? from? left ?to ?right ?through? the? rectangles. ??Keep ?a? binary? search? tree ?containing ?the? y ?coordinates ?of ?the? top? and? bottom? edges ?of ?the? rectangles? that? overlap ?the ?scanline. ??For ?each? element? of ?the? array,? check? whether ?it ?is ?a? left ?or ?right? edge.? ?If ?it ?is ?a ?right? edge, ?remove? the? corresponding? top? and ?bottom? edges ?from ?the ?BST.?? If ?it ?is ?a?left ?edge,? search? the? BST? for ?rectangles? that? overlap ?the? current? rectangle; ?if ?there? is ?one,?return ?the? overlap.?? Then,? add ?the?y? coordinates ?of? the? top? and? bottom?edges? of ?the ?rectangle? to ?the ?BST.?? The? search? takes ?O(n?log?n) ?time,? since ?it ?takes ?O(n?log?n) ?time? to? sort? the? rectangles? and? each? of ?the? 2n ?iteration s?takes ?O(log?n)? time.

 

C++ Sample Code (Find all pairs of rectangles that overlap): 

 1 #include <iostream>
 2 #include <vector>
 3 #include <map>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 struct rect {
 8     int _x1, _x2, _y1, _y2;
 9     rect(int x1, int x2, int y1, int y2) :
10         _x1(x1), _x2(x2), _y1(y1), _y2(y2) {}
11 };
12 
13 struct xedge {
14     int _x;
15     int _is_left;
16     int _i_rect;
17     xedge(int x, int is_left, int i_rect) :
18         _x(x), _is_left(is_left), _i_rect(i_rect) {}
19 };
20 
21 struct yedge {
22     int _y;
23     int _is_top;
24     int _i_rect;
25     yedge(int y, int is_top, int i_rect) :
26         _y(y), _is_top(is_top), _i_rect(i_rect) {} 
27 };
28 
29 int main() {
30     vector<rect> rcts; // vector that stores rectangles
31     vector<xedge> xes; // left and right edges of the rectangles
32     int x1, x2, y1, y2;
33     int i = 0;
34     while (cin >> x1 >> x2 >> y1 >> y2) {
35         rcts.push_back(rect(x1, x2, y1, y2));
36         xes.push_back(xedge(x1, 1, i));
37         xes.push_back(xedge(x2, 0, i));
38         i++;
39     }
40 
41     // sort left and right rectangles according to their x-coordinates
42     sort(xes.begin(), xes.end(), 
43         [](const xedge& e1, const xedge& e2) {
44             if (e1._x != e2._x) return e1._x < e2._x;
45             else if (e1._is_left != e2._is_left) 
46                 return e1._is_left > e2._is_left;
47             else return e1._i_rect < e2._i_rect;
48         });
49 
50     // a binary search tree for top and bottom edges that overlap the "scanline"
51     multimap<int, yedge> edge_map;
52     for (auto& xe : xes) { // xe : "scanline"
53         if (!xe._is_left) { 
54             auto range = edge_map.equal_range(rcts[xe._i_rect]._y1); 
55             for (auto iter = range.first; iter != range.second; ++iter) {
56                 if (iter->second._i_rect == xe._i_rect) {
57                     edge_map.erase(iter);
58                     break;
59                 }
60             }
61             range = edge_map.equal_range(rcts[xe._i_rect]._y2); 
62             for (auto iter = range.first; iter != range.second; ++iter) {
63                 if (iter->second._i_rect == xe._i_rect) {
64                     edge_map.erase(iter);
65                     break;
66                 }
67             }
68         } else {
69             int y1 = rcts[xe._i_rect]._y1;
70             int y2 = rcts[xe._i_rect]._y2;
71             auto iter1 = edge_map.lower_bound(y1);
72             auto iter2 = edge_map.upper_bound(y2);
73             for (auto iter = iter1; iter != iter2; ++iter) {
74                 cout << xe._i_rect << " " << iter->second._i_rect << endl;
75             }
76             edge_map.insert(make_pair(y1, yedge(y1, 0, xe._i_rect)));
77             edge_map.insert(make_pair(y2, yedge(y2, 1, xe._i_rect)));
78         }
79     }
80 
81     return 0;
82 }

 

 

 

 

Axis­ Aligned ?Rectangles

标签:

原文地址:http://www.cnblogs.com/bestofme/p/4603359.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!