diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/RectangleUtil.hh | 44 | ||||
-rw-r--r-- | src/tests/testRectangleUtil.cc | 55 |
2 files changed, 99 insertions, 0 deletions
diff --git a/src/RectangleUtil.hh b/src/RectangleUtil.hh index 88c3a33..9725e63 100644 --- a/src/RectangleUtil.hh +++ b/src/RectangleUtil.hh | |||
@@ -24,6 +24,50 @@ bool insideBorder(const RectangleLike& rect, | |||
24 | y < rect.y() + (int)rect.height() + border_width; | 24 | y < rect.y() + (int)rect.height() + border_width; |
25 | } | 25 | } |
26 | 26 | ||
27 | |||
28 | |||
29 | /* | ||
30 | * Determines if rectangle 'a' overlaps rectangle 'b' | ||
31 | * @returns true if 'a' overlaps 'b' | ||
32 | * | ||
33 | * outside overlap situations | ||
34 | * | ||
35 | * a----a a----a a--------a b--------b | ||
36 | * | | b----b | b-+--b | b----b | | a----a | | ||
37 | * a----a | | a--+-a | | | | | | | | | | ||
38 | * b----b b----b | b----b | | a----a | | ||
39 | * a--------a b--------b | ||
40 | * | ||
41 | */ | ||
42 | |||
43 | inline bool overlapRectangles( | ||
44 | int ax, int ay, int awidth, int aheight, | ||
45 | int bx, int by, int bwidth, int bheight) { | ||
46 | |||
47 | bool do_not_overlap = | ||
48 | ax > (bx + bwidth) | ||
49 | || bx > (ax + awidth) | ||
50 | || ay > (by + bheight) | ||
51 | || by > (ay + aheight); | ||
52 | |||
53 | return !do_not_overlap; | ||
54 | } | ||
55 | |||
56 | |||
57 | /* | ||
58 | * Determines if rectangle 'a' overlaps rectangle 'b' | ||
59 | * @param a - rectangle a | ||
60 | * @param b - rectangle b | ||
61 | * @returns true if 'a' overlaps 'b' | ||
62 | */ | ||
63 | template <typename RectangleLikeA, typename RectangleLikeB> | ||
64 | bool overlapRectangles(const RectangleLikeA& a, const RectangleLikeB& b) { | ||
65 | |||
66 | return overlapRectangles( | ||
67 | a.x(), a.y(), a.width(), a.height(), | ||
68 | b.x(), b.y(), b.width(), b.height()); | ||
69 | } | ||
70 | |||
27 | } // namespace RectangleUtil | 71 | } // namespace RectangleUtil |
28 | 72 | ||
29 | 73 | ||
diff --git a/src/tests/testRectangleUtil.cc b/src/tests/testRectangleUtil.cc index f10b6af..2da2a4e 100644 --- a/src/tests/testRectangleUtil.cc +++ b/src/tests/testRectangleUtil.cc | |||
@@ -55,12 +55,67 @@ int test_insideBorder() { | |||
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
58 | int test_overlapRectangles() { | ||
58 | 59 | ||
60 | printf("testing RectangleUtil::overlapRectangles()\n"); | ||
61 | |||
62 | struct _t { | ||
63 | struct Rect a; | ||
64 | struct Rect b; | ||
65 | int truth; | ||
66 | }; | ||
67 | |||
68 | struct _test { | ||
69 | bool operator()(const Rect& a, const Rect& b, int truth, int i) { | ||
70 | |||
71 | int result = RectangleUtil::overlapRectangles(a, b); | ||
72 | |||
73 | printf(" %d: [%2d %2d]-[%2d %2d] %s [%2d %2d]-[%2d %2d]: %s\n", | ||
74 | i, | ||
75 | a.x(), a.y(), | ||
76 | a.x() + (int)a.width(), | ||
77 | a.y() + (int)a.height(), | ||
78 | result ? "overlaps" : "does not overlap", | ||
79 | b.x(), b.y(), | ||
80 | b.x() + (int)b.width(), | ||
81 | b.y() + (int)b.height(), | ||
82 | result == truth ? "ok" : "failed"); | ||
83 | return result == truth; | ||
84 | } | ||
85 | }; | ||
86 | |||
87 | const _t tests[] = { | ||
88 | |||
89 | { { 0, 0, 8, 8 }, { 0, 0, 8, 8 }, true }, // b equals a | ||
90 | { { 0, 0, 8, 8 }, { 3, 3, 3, 3 }, true }, // b completely inside a | ||
91 | { { 0, 0, 8, 8 }, { 4, 4, 8, 8 }, true }, // b overlaps a in one corner | ||
92 | { { 0, 0, 8, 8 }, { 4,-1, 2, 9 }, true }, // b overlaps a in the middle | ||
93 | |||
94 | { { 0, 0, 8, 8 }, { -8, 0, 5, 8 }, false }, // b completely left from a | ||
95 | { { 0, 0, 8, 8 }, { 9, 0, 5, 8 }, false }, // b completely right from a | ||
96 | { { 0, 0, 8, 8 }, { 0,-9, 5, 8 }, false }, // b completely down below a | ||
97 | { { 0, 0, 8, 8 }, { 0, 9, 5, 8 }, false }, // b completely up above a | ||
98 | }; | ||
99 | |||
100 | |||
101 | |||
102 | _test test; | ||
103 | int i; | ||
104 | for (i = 0; i < sizeof(tests)/sizeof(_t); ++i) { | ||
105 | test(tests[i].a, tests[i].b, tests[i].truth, i); | ||
106 | test(tests[i].b, tests[i].a, tests[i].truth, i); | ||
107 | } | ||
108 | |||
109 | printf("done.\n"); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
59 | 113 | ||
60 | 114 | ||
61 | int main(int argc, char **argv) { | 115 | int main(int argc, char **argv) { |
62 | 116 | ||
63 | test_insideBorder(); | 117 | test_insideBorder(); |
118 | test_overlapRectangles(); | ||
64 | 119 | ||
65 | return 0; | 120 | return 0; |
66 | } | 121 | } |